Loading...
--- Libc/Libc-583/gen/FreeBSD/popen.c.patch
+++ Libc/Libc-320.1.3/gen/FreeBSD/popen.c.patch
@@ -1,31 +1,6 @@
---- popen.c.orig 2009-03-03 02:04:57.000000000 -0800
-+++ popen.c 2009-03-03 15:28:31.000000000 -0800
-@@ -34,6 +34,10 @@
- * SUCH DAMAGE.
- */
-
-+#ifdef VARIANT_DARWINEXTSN
-+#define _DARWIN_UNLIMITED_STREAMS
-+#endif /* VARIANT_DARWINEXTSN */
-+
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95";
- #endif /* LIBC_SCCS and not lint */
-@@ -43,7 +47,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>
-@@ -52,17 +57,29 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop
- #include <string.h>
- #include <paths.h>
- #include <pthread.h>
-+#include <spawn.h>
+--- popen.c.orig Fri Jan 3 16:15:15 2003
++++ popen.c Sat May 3 14:05:13 2003
+@@ -55,7 +55,8 @@
#include "un-namespace.h"
#include "libc_private.h"
@@ -33,216 +8,5 @@
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
--static struct pid {
-+/* 3516149 - store file descriptor and use that to close to prevent blocking */
-+struct pid {
+ static struct pid {
struct pid *next;
- FILE *fp;
-+ int fd;
- pid_t pid;
--} *pidlist;
--static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER;
-+};
-+#define pidlist __popen_pidlist
-+#define pidlist_mutex __popen_pidlist_mutex
-+#ifndef BUILDING_VARIANT
-+__private_extern__ struct pid *pidlist = NULL;
-+__private_extern__ pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER;
-+#else /* BUILDING_VARIANT */
-+extern struct pid *pidlist;
-+extern pthread_mutex_t pidlist_mutex;
-+#endif /* !BUILDING_VARIANT */
-
- #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&pidlist_mutex)
- #define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex)
-@@ -73,85 +90,109 @@ popen(command, type)
- {
- struct pid *cur;
- FILE *iop;
-- int pdes[2], pid, twoway;
-+ int pdes[2], pid, twoway, other;
- char *argv[4];
- struct pid *p;
-+ posix_spawn_file_actions_t file_actions;
-+ int err;
-
-- /*
-- * 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 (pipe(pdes) < 0)
-- return (NULL);
-
-- if ((cur = malloc(sizeof(struct pid))) == NULL) {
-+ /* fdopen can now fail */
-+ if (*type == 'r') {
-+ iop = fdopen(pdes[0], type);
-+ other = pdes[1];
-+ } else {
-+ iop = fdopen(pdes[1], type);
-+ other = pdes[0];
-+ }
-+ if (iop == NULL) {
- (void)_close(pdes[0]);
- (void)_close(pdes[1]);
- return (NULL);
- }
-
-+ if ((cur = malloc(sizeof(struct pid))) == NULL) {
-+ (void)fclose(iop);
-+ (void)_close(other);
-+ return (NULL);
-+ }
-+
-+ if ((err = posix_spawn_file_actions_init(&file_actions)) != 0) {
-+ (void)fclose(iop);
-+ (void)_close(other);
-+ free(cur);
-+ errno = err;
-+ return (NULL);
-+ }
-+ if (*type == 'r') {
-+ /*
-+ * The dup2() to STDIN_FILENO is repeated to avoid
-+ * writing to pdes[1], which might corrupt the
-+ * parent's copy. This isn't good enough in
-+ * general, since the _exit() is no return, so
-+ * the compiler is free to corrupt all the local
-+ * variables.
-+ */
-+ (void)posix_spawn_file_actions_addclose(&file_actions, pdes[0]);
-+ if (pdes[1] != STDOUT_FILENO) {
-+ (void)posix_spawn_file_actions_adddup2(&file_actions, pdes[1], STDOUT_FILENO);
-+ (void)posix_spawn_file_actions_addclose(&file_actions, pdes[1]);
-+ if (twoway)
-+ (void)posix_spawn_file_actions_adddup2(&file_actions, STDOUT_FILENO, STDIN_FILENO);
-+ } else if (twoway && (pdes[1] != STDIN_FILENO))
-+ (void)posix_spawn_file_actions_adddup2(&file_actions, pdes[1], STDIN_FILENO);
-+ } else {
-+ if (pdes[0] != STDIN_FILENO) {
-+ (void)posix_spawn_file_actions_adddup2(&file_actions, pdes[0], STDIN_FILENO);
-+ (void)posix_spawn_file_actions_addclose(&file_actions, pdes[0]);
-+ }
-+ (void)posix_spawn_file_actions_addclose(&file_actions, pdes[1]);
-+ }
-+ for (p = pidlist; p; p = p->next) {
-+ (void)posix_spawn_file_actions_addclose(&file_actions, p->fd);
-+ }
-+
- argv[0] = "sh";
- argv[1] = "-c";
- argv[2] = (char *)command;
- argv[3] = NULL;
-
-- THREAD_LOCK();
-- switch (pid = vfork()) {
-- case -1: /* Error. */
-- THREAD_UNLOCK();
-- (void)_close(pdes[0]);
-- (void)_close(pdes[1]);
-+ err = posix_spawn(&pid, _PATH_BSHELL, &file_actions, NULL, argv, environ);
-+ posix_spawn_file_actions_destroy(&file_actions);
-+
-+ if (err == ENOMEM || err == EAGAIN) { /* as if fork failed */
-+ (void)fclose(iop);
-+ (void)_close(other);
- free(cur);
-+ errno = err;
- return (NULL);
-- /* NOTREACHED */
-- case 0: /* Child. */
-- if (*type == 'r') {
-- /*
-- * The _dup2() to STDIN_FILENO is repeated to avoid
-- * writing to pdes[1], which might corrupt the
-- * parent's copy. This isn't good enough in
-- * general, since the _exit() is no return, so
-- * the compiler is free to corrupt all the local
-- * variables.
-- */
-- (void)_close(pdes[0]);
-- if (pdes[1] != STDOUT_FILENO) {
-- (void)_dup2(pdes[1], STDOUT_FILENO);
-- (void)_close(pdes[1]);
-- if (twoway)
-- (void)_dup2(STDOUT_FILENO, STDIN_FILENO);
-- } else if (twoway && (pdes[1] != STDIN_FILENO))
-- (void)_dup2(pdes[1], STDIN_FILENO);
-- } else {
-- if (pdes[0] != STDIN_FILENO) {
-- (void)_dup2(pdes[0], STDIN_FILENO);
-- (void)_close(pdes[0]);
-- }
-- (void)_close(pdes[1]);
-- }
-- for (p = pidlist; p; p = p->next) {
-- (void)_close(fileno(p->fp));
-- }
-- _execve(_PATH_BSHELL, argv, environ);
-- _exit(127);
-- /* NOTREACHED */
-+ } else if (err != 0) { /* couldn't exec the shell */
-+ pid = -1;
- }
-- THREAD_UNLOCK();
-
-- /* 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,10 +203,11 @@ popen(command, type)
- cur->next = pidlist;
- pidlist = cur;
- THREAD_UNLOCK();
--
-+ fwide(iop, -1); /* byte stream */
- return (iop);
- }
-
-+#ifndef BUILDING_VARIANT
- /*
- * pclose --
- * Pclose returns -1 if stream is not associated with a `popened' command,
-@@ -198,6 +240,10 @@ pclose(iop)
-
- (void)fclose(iop);
-
-+ if (cur->pid < 0) {
-+ free(cur);
-+ return W_EXITCODE(127, 0);
-+ }
- do {
- pid = _wait4(cur->pid, &pstat, 0, (struct rusage *)0);
- } while (pid == -1 && errno == EINTR);
-@@ -206,3 +252,4 @@ pclose(iop)
-
- return (pid == -1 ? -1 : pstat);
- }
-+#endif /* !BUILDING_VARIANT */