chiark / gitweb /
fds: Introduce pipe_cloexec()
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 27 Sep 2014 10:41:53 +0000 (11:41 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 2 Oct 2014 01:23:59 +0000 (02:23 +0100)
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>
process.c
secnet.c
secnet.h
slip.c
util.c

index a9ff3d92648557d7692d9da97fe864c41227a5fe..64683159ccc40be20132f5bc8d40beb89ed325c1 100644 (file)
--- a/process.c
+++ b/process.c
@@ -310,9 +310,7 @@ void start_signal_handling(void)
     sigemptyset(&registered);
     sigemptyset(&pending);
 
-    if (pipe(p)!=0) {
-       fatal_perror("start_signal_handling: pipe");
-    }
+    pipe_cloexec(p);
     spw=p[1];
     spr=p[0];
     if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
index c604d44b65781c2cbc7b60604621991cd9e55d32..7fabb1b50f473292f64a681d38b7fa43d0c4a59d 100644 (file)
--- a/secnet.c
+++ b/secnet.c
@@ -403,9 +403,7 @@ static void become_daemon(void)
     }
     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");
-       }
+       pipe_cloexec(errfds);
        if (dup2(errfds[1],0) < 0
            || dup2(errfds[1],1) < 0
            || dup2(errfds[1],2) < 0)
index ce01d24e31749e1bb8a00db3444f1c5cb449bcab..f0ab80b8cde32ab4214577205b7ae37b7a88fa18 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -139,6 +139,7 @@ extern void *safe_malloc(size_t size, const char *message);
 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, ...);
 
diff --git a/slip.c b/slip.c
index 17a9099215f9ae8d3cdc236fe9c83a3d8c8cbfaa..7d060c371881cfeb8c9e28ac78fe0c0476bc2a9c 100644 (file)
--- a/slip.c
+++ b/slip.c
@@ -262,7 +262,6 @@ static void userv_entry(void *sst)
     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. */
@@ -326,12 +325,8 @@ static void userv_invoke_userv(struct userv *st)
     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];
 
diff --git a/util.c b/util.c
index fc6f6264cf433ba84211858df529b986b377b714..aa85559b37be4113800c623e8dbae4dfcd0ab716 100644 (file)
--- a/util.c
+++ b/util.c
@@ -169,6 +169,13 @@ void setcloexec(int fd) {
     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",