diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-02-23 15:56:42 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-02-23 15:56:42 +0000 |
commit | 262dd3e215abe1851583c743109dd8077535d145 (patch) | |
tree | fe4df2f9fea182e39ef2be2178f08fc8ca89352b | |
parent | 31bc465ed7c22db3ff44e5ca942711f458f46178 (diff) | |
download | netpbm-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
-rw-r--r-- | doc/HISTORY | 3 | ||||
-rw-r--r-- | lib/libsystem.c | 40 |
2 files changed, 39 insertions, 4 deletions
diff --git a/doc/HISTORY b/doc/HISTORY index 81aa0da3..7be10a64 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -12,6 +12,9 @@ not yet BJH Release 10.50.00 pnmconvol: Add -normalize . + pm_system(): Close extraneous file descriptors that, among + other things, prevent child from seeing EOF. + libnetpbm: Add PNM_GETR(), PNM_GETG(), PNM_GETB(). Same as PPM_GETR(), etc. 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); |