--- popen.c.orig Mon May 24 23:50:41 2004 +++ popen.c Tue May 25 00:09:39 2004 @@ -43,6 +43,7 @@ #include "namespace.h" #include <sys/param.h> #include <sys/wait.h> +#include <sys/socket.h> #include <signal.h> #include <errno.h> @@ -55,11 +56,14 @@ #include "un-namespace.h" #include "libc_private.h" -extern char **environ; +#include <crt_externs.h> +#define environ (*_NSGetEnviron()) +/* 3516149 - store file descriptor and use that to close to prevent blocking */ static struct pid { struct pid *next; FILE *fp; + int fd; pid_t pid; } *pidlist; static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -77,20 +81,18 @@ char *argv[4]; struct pid *p; - /* - * Lite2 introduced two-way popen() pipes using _socketpair(). - * FreeBSD's pipe() is bidirectional, so we use that. - */ if (strchr(type, '+')) { twoway = 1; type = "r+"; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) + return (NULL); } else { twoway = 0; if ((*type != 'r' && *type != 'w') || type[1]) return (NULL); + if (pipe(pdes) < 0) + return (NULL); } - if (pipe(pdes) < 0) - return (NULL); if ((cur = malloc(sizeof(struct pid))) == NULL) { (void)_close(pdes[0]); @@ -138,7 +140,7 @@ (void)_close(pdes[1]); } for (p = pidlist; p; p = p->next) { - (void)_close(fileno(p->fp)); + (void)_close(p->fd); } _execve(_PATH_BSHELL, argv, environ); _exit(127); @@ -149,9 +151,11 @@ /* Parent; assume fdopen can't fail. */ if (*type == 'r') { iop = fdopen(pdes[0], type); + cur->fd = pdes[0]; (void)_close(pdes[1]); } else { iop = fdopen(pdes[1], type); + cur->fd = pdes[1]; (void)_close(pdes[0]); }