chiark / gitweb /
util: in make_stdio() use dup2() rather than dup3()
authorLennart Poettering <lennart@poettering.net>
Wed, 17 Dec 2014 20:54:00 +0000 (21:54 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 18 Dec 2014 00:36:28 +0000 (01:36 +0100)
dup3() allows setting O_CLOEXEC which we are not interested in. However,
it also fails if called with the same fd as input and output, which is
something we don't want. Hence use dup2().

Also, we need to explicitly turn off O_CLOEXEC for the fds, in case the
input fd was O_CLOEXEC and < 3.

src/shared/util.c

index ee95a4b6f71c67bb7ff3f5c3e8ce736bfaa98113..364f61885b00a1b3f9a076a993b982f74468ba7e 100644 (file)
@@ -2468,9 +2468,9 @@ int make_stdio(int fd) {
 
         assert(fd >= 0);
 
 
         assert(fd >= 0);
 
-        r = dup3(fd, STDIN_FILENO, 0);
-        s = dup3(fd, STDOUT_FILENO, 0);
-        t = dup3(fd, STDERR_FILENO, 0);
+        r = dup2(fd, STDIN_FILENO);
+        s = dup2(fd, STDOUT_FILENO);
+        t = dup2(fd, STDERR_FILENO);
 
         if (fd >= 3)
                 safe_close(fd);
 
         if (fd >= 3)
                 safe_close(fd);
@@ -2478,7 +2478,11 @@ int make_stdio(int fd) {
         if (r < 0 || s < 0 || t < 0)
                 return -errno;
 
         if (r < 0 || s < 0 || t < 0)
                 return -errno;
 
-        /* We rely here that the new fd has O_CLOEXEC not set */
+        /* Explicitly unset O_CLOEXEC, since if fd was < 3, then
+         * dup2() was a NOP and the bit hence possibly set. */
+        fd_cloexec(STDIN_FILENO, false);
+        fd_cloexec(STDOUT_FILENO, false);
+        fd_cloexec(STDERR_FILENO, false);
 
         return 0;
 }
 
         return 0;
 }