popen misbehaves when various std fds are closed. Test program:
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/file.h> #include <unistd.h> #include <assert.h> static FILE *tty; static void dump (const char *s, int fd) { fprintf (tty, "%s: fd %d: %s\n", s, fd, dup2 (fd, fd) == fd ? (fcntl (fd, F_GETFD) & FD_CLOEXEC) ? "cloexec" : "open" : "closed"); } int main (int argc, char** argv) { const char *id = "child"; if (dup2 (6, 6) == 6) tty = fdopen (6, "a"); else { int fd = open ("/dev/tty", O_WRONLY|O_CREAT|O_APPEND, 0600); tty = fdopen (fcntl (fd, F_DUPFD, 6), "w"); close (fd); } assert (tty); if (argc > 1) { id = "parent"; FILE *slave = popen (argv[0], argv[1]); if (slave) { fputs ("parent ", tty); dump ("slave", fileno (slave)); } else fputs ("invalid mode to popen\n", tty); } dump (id, 0); dump (id, 1); dump (id, 2); return 0; } I ran the following (testing all combinations of read and write children, and all combinations of which std fds are closed): { for mode in r w; do echo testing $mode >&6; i=0; for closed in '' '<&-' '>&-' '<&- >&-' '2>&-' \ '<&- 2>&-' '>&- 2>&-' '<&- >&- 2>&-' ; do echo $((i++)) >&6; (eval ./foo $mode $closed); sleep 1; done; done } 6>log.txt then compared the logs between cygwin and Solaris, to spot the following bugs: When both stdin and stdout are closed and the parent is reading from the slave, the slave fails to get the write end of the pipe set to its stdout (regardless of whether stderr is also closed; cases r3 and r7 above): ./foo r <&- >&- $ ./foo r <&- >&- parent's slave: fd 0: cloexec parent: fd 0: cloexec parent: fd 1: closed parent: fd 2: open child: fd 0: closed child: fd 1: closed child: fd 2: open expected "child: fd 1: open" When stdin is closed and the parent is writing to the slave, the slave fails to get the read end of the pipe set to its stdin (regardless of whether stdout or stderr are closed, cases w1, w3, w5, and w7 above). $ ./foo w <&- parent's slave: fd 3: cloexec parent: fd 0: closed parent: fd 1: open parent: fd 2: open child: fd 0: closed child: fd 1: open child: fd 2: open expected "child: fd 0: open" -- Eric Blake -- View this message in context: http://www.nabble.com/popen-bugs-tp25015624p25015624.html Sent from the Cygwin list mailing list archive at Nabble.com. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple