Replace all calls to pipe() with this new function, which checks
errors for us, and also sets both fds to close-on-exec.
There are some minor functional changes:
* Error messages from pipe() failing are now less detailed about the
context. This is not important.
* The signal self-pipe is now cloexec too. This is at worst harmless.
* When execing userv-ipif we rely on cloexec to close the spare
copies of the pipe ends.
* The stderr self-pipe spare writing end is redudantly made cloexec
even though it is about to be closed shortly afterwards.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
sigemptyset(®istered);
sigemptyset(&pending);
sigemptyset(®istered);
sigemptyset(&pending);
- if (pipe(p)!=0) {
- fatal_perror("start_signal_handling: pipe");
- }
spw=p[1];
spr=p[0];
if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
spw=p[1];
spr=p[0];
if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
}
if (secnet_is_daemon) {
/* stderr etc are redirected to the system/log facility */
}
if (secnet_is_daemon) {
/* stderr etc are redirected to the system/log facility */
- if (pipe(errfds)!=0) {
- fatal_perror("can't create pipe for stderr");
- }
if (dup2(errfds[1],0) < 0
|| dup2(errfds[1],1) < 0
|| dup2(errfds[1],2) < 0)
if (dup2(errfds[1],0) < 0
|| dup2(errfds[1],1) < 0
|| dup2(errfds[1],2) < 0)
extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
void setcloexec(int fd); /* cannot fail */
extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
void setcloexec(int fd); /* cannot fail */
+void pipe_cloexec(int fd[2]); /* pipe(), setcloexec() twice; cannot fail */
extern int sys_cmd(const char *file, const char *argc, ...);
extern int sys_cmd(const char *file, const char *argc, ...);
dup2(st->in,0);
dup2(st->out,1);
dup2(st->in,0);
dup2(st->out,1);
- /* XXX close all other fds */
setsid();
/* XXX We really should strdup() all of argv[] but because we'll just
exit anyway if execvp() fails it doesn't seem worth bothering. */
setsid();
/* XXX We really should strdup() all of argv[] but because we'll just
exit anyway if execvp() fails it doesn't seem worth bothering. */
st->slip.pending_esc=False;
/* Invoke userv */
st->slip.pending_esc=False;
/* Invoke userv */
- if (pipe(c_stdin)!=0) {
- fatal_perror("userv_invoke_userv: pipe(c_stdin)");
- }
- if (pipe(c_stdout)!=0) {
- fatal_perror("userv_invoke_userv: pipe(c_stdout)");
- }
+ pipe_cloexec(c_stdin);
+ pipe_cloexec(c_stdout);
st->txfd=c_stdin[1];
st->rxfd=c_stdout[0];
st->txfd=c_stdin[1];
st->rxfd=c_stdout[0];
if (r<0) fatal_perror("fcntl(,F_SETFD,|FD_CLOEXEC) failed");
}
if (r<0) fatal_perror("fcntl(,F_SETFD,|FD_CLOEXEC) failed");
}
+void pipe_cloexec(int fd[2]) {
+ int r=pipe(fd);
+ if (r) fatal_perror("pipe");
+ setcloexec(fd[0]);
+ setcloexec(fd[1]);
+}
+
static const char *phases[NR_PHASES]={
"PHASE_INIT",
"PHASE_GETOPTS",
static const char *phases[NR_PHASES]={
"PHASE_INIT",
"PHASE_GETOPTS",