X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fpopen.c;h=590f9843bf402b7d91c7b415b7ddd46af70c7802;hb=a425462f784164b73297d8992075fd9aebd65a94;hp=92a8050fdb803a851d0e62b0bfac12c9ff427e4f;hpb=1b3a58de6630d88009c1ef06ed154249fb2e9d6b;p=gnulib.git diff --git a/lib/popen.c b/lib/popen.c index 92a8050fd..590f9843b 100644 --- a/lib/popen.c +++ b/lib/popen.c @@ -1,5 +1,5 @@ /* Open a stream to a sub-process. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,17 +21,36 @@ /* Specification. */ #include -#include -#include -#include -#include +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Native Windows API. */ -#undef popen +# include + +FILE * +popen (const char *filename, const char *mode) +{ + /* Use binary mode by default. */ + if (strcmp (mode, "r") == 0) + mode = "rb"; + else if (strcmp (mode, "w") == 0) + mode = "wb"; + + return _popen (filename, mode); +} + +#else + +# include +# include +# include +# include + +# undef popen FILE * rpl_popen (const char *filename, const char *mode) { - /* The mingw popen works fine, and all other platforms have fcntl. + /* All other platforms have popen and fcntl. The bug of the child clobbering its own file descriptors if stdin or stdout was closed in the parent can be worked around by opening those two fds as close-on-exec to begin with. */ @@ -40,7 +59,7 @@ rpl_popen (const char *filename, const char *mode) the fd leaks into subsequent popen calls. We could work around this by maintaining a list of all fd's opened by popen, and temporarily marking them cloexec around the real popen call, but - we would also have to override pclose, and the bookkeepping seems + we would also have to override pclose, and the bookkeeping seems extreme given that cygwin 1.7 no longer has the bug. */ FILE *result; int cloexec0 = fcntl (STDIN_FILENO, F_GETFD); @@ -59,16 +78,16 @@ rpl_popen (const char *filename, const char *mode) if (cloexec0 < 0) { if (open ("/dev/null", O_RDONLY) != STDIN_FILENO - || fcntl (STDIN_FILENO, F_SETFD, - fcntl (STDIN_FILENO, F_GETFD) | FD_CLOEXEC) == -1) - abort (); + || fcntl (STDIN_FILENO, F_SETFD, + fcntl (STDIN_FILENO, F_GETFD) | FD_CLOEXEC) == -1) + abort (); } if (cloexec1 < 0) { if (open ("/dev/null", O_RDONLY) != STDOUT_FILENO - || fcntl (STDOUT_FILENO, F_SETFD, - fcntl (STDOUT_FILENO, F_GETFD) | FD_CLOEXEC) == -1) - abort (); + || fcntl (STDOUT_FILENO, F_SETFD, + fcntl (STDOUT_FILENO, F_GETFD) | FD_CLOEXEC) == -1) + abort (); } result = popen (filename, mode); /* Now, close any dummy fd's created in the parent. */ @@ -80,3 +99,5 @@ rpl_popen (const char *filename, const char *mode) errno = saved_errno; return result; } + +#endif