Loading...
gen/FreeBSD/popen.c.patch /dev/null Libc-498.1.5
--- /dev/null
+++ Libc/Libc-498.1.5/gen/FreeBSD/popen.c.patch
@@ -0,0 +1,98 @@
+--- popen.c.orig	2003-05-20 15:21:02.000000000 -0700
++++ popen.c	2005-09-14 15:53:35.000000000 -0700
+@@ -43,7 +43,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop
+ #include "namespace.h"
+ #include <sys/param.h>
+ #include <sys/wait.h>
+-
++#include <sys/socket.h>
++#include <wchar.h>		/* fwide() */
+ #include <signal.h>
+ #include <errno.h>
+ #include <unistd.h>
+@@ -55,11 +56,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop
+ #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,24 @@ popen(command, type)
+ 	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, '+')) {
++	if (type == NULL) {
++		errno = EINVAL;
++		return (NULL);
++	}
++	if (strcmp(type, "r+") == 0) {
+ 		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])
++		if ((*type != 'r' && *type != 'w') || type[1]) {
++			errno = EINVAL;
+ 			return (NULL);
+ 	}
+ 	if (pipe(pdes) < 0)
+ 		return (NULL);
++	}
+ 
+ 	if ((cur = malloc(sizeof(struct pid))) == NULL) {
+ 		(void)_close(pdes[0]);
+@@ -104,7 +112,7 @@ popen(command, type)
+ 	argv[3] = NULL;
+ 
+ 	THREAD_LOCK();
+-	switch (pid = vfork()) {
++	switch (pid = fork()) {
+ 	case -1:			/* Error. */
+ 		THREAD_UNLOCK();
+ 		(void)_close(pdes[0]);
+@@ -138,7 +146,7 @@ popen(command, type)
+ 			(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 +157,11 @@ popen(command, type)
+ 	/* 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]);
+ 	}
+ 
+@@ -162,7 +172,7 @@ popen(command, type)
+ 	cur->next = pidlist;
+ 	pidlist = cur;
+ 	THREAD_UNLOCK();
+-
++	fwide(iop, -1);		/* byte stream */
+ 	return (iop);
+ }
+