about summary refs log tree commit diff
path: root/lib/libsystem.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-02-23 15:56:42 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-02-23 15:56:42 +0000
commit262dd3e215abe1851583c743109dd8077535d145 (patch)
treefe4df2f9fea182e39ef2be2178f08fc8ca89352b /lib/libsystem.c
parent31bc465ed7c22db3ff44e5ca942711f458f46178 (diff)
downloadnetpbm-mirror-262dd3e215abe1851583c743109dd8077535d145.tar.gz
netpbm-mirror-262dd3e215abe1851583c743109dd8077535d145.tar.xz
netpbm-mirror-262dd3e215abe1851583c743109dd8077535d145.zip
Close extraneous file descriptors in child
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1129 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/libsystem.c')
-rw-r--r--lib/libsystem.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/lib/libsystem.c b/lib/libsystem.c
index 2ce9b743..8a0f520a 100644
--- a/lib/libsystem.c
+++ b/lib/libsystem.c
@@ -33,16 +33,44 @@
 
 
 static void
+closeUninheritableFds(int const stdinFd,
+                      int const stdoutFd) {
+/*----------------------------------------------------------------------------
+  Close all the file descriptors that we declare uninheritable -- files Parent
+  has open that Child has no business accessing.
+
+  Closing an extra file descriptor is essential to allow the file to close
+  when Parent closes it.
+
+  We define uninheritable as less than 64 and not Standard Input, Output,
+  or Error, or 'stdinFd' or 'stdoutFd'.
+-----------------------------------------------------------------------------*/
+    int fd;
+
+    for (fd = 0; fd < 64; ++fd) {
+        if (fd == stdinFd) {
+        } else if (fd == stdoutFd) {
+        } else if (fd == STDIN_FILENO) {
+        } else if (fd == STDOUT_FILENO) {
+        } else if (fd == STDERR_FILENO) {
+        } else {
+            close(fd);
+        }
+    }
+}
+
+
+
+static void
 execProgram(const char *  const progName,
             const char ** const argArray,
             int           const stdinFd,
             int           const stdoutFd) {
 /*----------------------------------------------------------------------------
-   Run the program 'progName' with arguments argArray[], in a child process
-   with 'stdinFd' as its Standard Input and 'stdoutFd' as its
-   Standard Output.
+   Exec the program 'progName' with arguments argArray[], with 'stdinFd' as
+   its Standard Input and 'stdoutFd' as its Standard Output.
 
-   But leave Standard Input and Standard Output as we found them.
+   But if the exec fails, leave all file descriptors as we found them.
 
    Note that stdinFd or stdoutFd may actually be Standard Input and
    Standard Output already.
@@ -58,11 +86,13 @@ execProgram(const char *  const progName,
         stdinSaveFd  = dup(STDIN);
         close(STDIN);
         dup2(stdinFd, STDIN);
+        close(stdinFd);
     }
     if (stdoutFd != STDOUT) {
         stdoutSaveFd = dup(STDOUT);
         close(STDOUT);
         dup2(stdoutFd, STDOUT);
+        close(stdoutFd);
     }
 
     rc = execvp(progName, (char **)argArray);
@@ -166,6 +196,8 @@ spawnProcessor(const char *  const progName,
         } else
             stdoutFd = STDOUT;
 
+        closeUninheritableFds(stdinFd, stdoutFd);
+
         execProgram(progName, argArray, stdinFd, stdoutFd);
 
         close(stdinFd);