This is the mail archive of the
cygwin
mailing list for the Cygwin project.
popen bugs
- From: Eric Blake <ebb9 at byu dot net>
- To: cygwin at cygwin dot com
- Date: Mon, 17 Aug 2009 15:45:23 -0700 (PDT)
- Subject: popen bugs
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