]> git.saurik.com Git - apple/libc.git/blobdiff - gen/FreeBSD/popen.c.patch
Libc-391.5.21.tar.gz
[apple/libc.git] / gen / FreeBSD / popen.c.patch
index a5e07fc6e2770a1815ee94079606366057da92d1..9a2785ca31e351da5015e76aeea44794a9b91dd6 100644 (file)
@@ -1,6 +1,14 @@
---- popen.c.orig       Fri Jan  3 16:15:15 2003
-+++ popen.c    Sat May  3 14:05:13 2003
-@@ -55,7 +55,8 @@
+--- popen.c.orig       2003-05-20 15:21:02.000000000 -0700
++++ popen.c    2005-09-17 16:08:55.000000000 -0700
+@@ -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"
  
@@ -8,5 +16,66 @@
 +#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]);
+@@ -104,7 +106,7 @@
+       argv[3] = NULL;
+       THREAD_LOCK();
+-      switch (pid = vfork()) {
++      switch (pid = fork()) {
+       case -1:                        /* Error. */
+               THREAD_UNLOCK();
+               (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]);
+       }