[BACK]Return to popen.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/gen/popen.c between version 1.28 and 1.32

version 1.28, 2003/09/15 22:30:38 version 1.32, 2012/06/25 22:32:43
Line 54  __RCSID("$NetBSD$");
Line 54  __RCSID("$NetBSD$");
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   #include <fcntl.h>
   
   #include "env.h"
 #include "reentrant.h"  #include "reentrant.h"
   
 #ifdef __weak_alias  #ifdef __weak_alias
Line 61  __weak_alias(popen,_popen)
Line 64  __weak_alias(popen,_popen)
 __weak_alias(pclose,_pclose)  __weak_alias(pclose,_pclose)
 #endif  #endif
   
 #ifdef _REENTRANT  
 extern rwlock_t __environ_lock;  
 #endif  
   
 static struct pid {  static struct pid {
         struct pid *next;          struct pid *next;
         FILE *fp;          FILE *fp;
Line 79  static rwlock_t pidlist_lock = RWLOCK_IN
Line 78  static rwlock_t pidlist_lock = RWLOCK_IN
 #endif  #endif
   
 FILE *  FILE *
 popen(command, type)  popen(const char *command, const char *type)
         const char *command, *type;  
 {  {
         struct pid *cur, *old;          struct pid *cur, *old;
         FILE *iop;          FILE *iop;
         int pdes[2], pid, twoway, serrno;          const char * volatile xtype = type;
           int pdes[2], pid, serrno;
           volatile int twoway;
           int flags;
   
         _DIAGASSERT(command != NULL);          _DIAGASSERT(command != NULL);
         _DIAGASSERT(type != NULL);          _DIAGASSERT(xtype != NULL);
   
 #ifdef __GNUC__          flags = strchr(xtype, 'e') ? O_CLOEXEC : 0;
         /* This outrageous construct just to shut up a GCC warning. */          if (strchr(xtype, '+')) {
         (void) &cur; (void) &twoway; (void) &type;                  int stype = flags ? (SOCK_STREAM | SOCK_CLOEXEC) : SOCK_STREAM;
 #endif  
   
         if (strchr(type, '+')) {  
                 twoway = 1;                  twoway = 1;
                 type = "r+";                  xtype = "r+";
                 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pdes) < 0)                  if (socketpair(AF_LOCAL, stype, 0, pdes) < 0)
                         return (NULL);                          return NULL;
         } else  {          } else  {
                 twoway = 0;                  twoway = 0;
                 if ((*type != 'r' && *type != 'w') || type[1] ||                  xtype = strrchr(xtype, 'r') ? "r" : "w";
                     (pipe(pdes) < 0)) {                  if (pipe2(pdes, flags) == -1)
                         errno = EINVAL;                          return NULL;
                         return (NULL);  
                 }  
         }          }
   
         if ((cur = malloc(sizeof(struct pid))) == NULL) {          if ((cur = malloc(sizeof(struct pid))) == NULL) {
Line 115  popen(command, type)
Line 111  popen(command, type)
                 return (NULL);                  return (NULL);
         }          }
   
         rwlock_rdlock(&pidlist_lock);          (void)rwlock_rdlock(&pidlist_lock);
         rwlock_rdlock(&__environ_lock);          (void)__readlockenv();
         switch (pid = vfork()) {          switch (pid = vfork()) {
         case -1:                        /* Error. */          case -1:                        /* Error. */
                 serrno = errno;                  serrno = errno;
                 rwlock_unlock(&__environ_lock);                  (void)__unlockenv();
                 rwlock_unlock(&pidlist_lock);                  (void)rwlock_unlock(&pidlist_lock);
                 free(cur);                  free(cur);
                 (void)close(pdes[0]);                  (void)close(pdes[0]);
                 (void)close(pdes[1]);                  (void)close(pdes[1]);
Line 139  popen(command, type)
Line 135  popen(command, type)
                         close(fileno(old->fp)); /* don't allow a flush */                          close(fileno(old->fp)); /* don't allow a flush */
 #endif  #endif
   
                 if (*type == 'r') {                  if (*xtype == 'r') {
                         (void)close(pdes[0]);                          (void)close(pdes[0]);
                         if (pdes[1] != STDOUT_FILENO) {                          if (pdes[1] != STDOUT_FILENO) {
                                 (void)dup2(pdes[1], STDOUT_FILENO);                                  (void)dup2(pdes[1], STDOUT_FILENO);
Line 159  popen(command, type)
Line 155  popen(command, type)
                 _exit(127);                  _exit(127);
                 /* NOTREACHED */                  /* NOTREACHED */
         }          }
         rwlock_unlock(&__environ_lock);          (void)__unlockenv();
   
         /* Parent; assume fdopen can't fail. */          /* Parent; assume fdopen can't fail. */
         if (*type == 'r') {          if (*xtype == 'r') {
                 iop = fdopen(pdes[0], type);                  iop = fdopen(pdes[0], xtype);
 #ifdef _REENTRANT  #ifdef _REENTRANT
                 cur->fd = pdes[0];                  cur->fd = pdes[0];
 #endif  #endif
                 (void)close(pdes[1]);                  (void)close(pdes[1]);
         } else {          } else {
                 iop = fdopen(pdes[1], type);                  iop = fdopen(pdes[1], xtype);
 #ifdef _REENTRANT  #ifdef _REENTRANT
                 cur->fd = pdes[1];                  cur->fd = pdes[1];
 #endif  #endif
Line 181  popen(command, type)
Line 177  popen(command, type)
         cur->pid =  pid;          cur->pid =  pid;
         cur->next = pidlist;          cur->next = pidlist;
         pidlist = cur;          pidlist = cur;
         rwlock_unlock(&pidlist_lock);          (void)rwlock_unlock(&pidlist_lock);
   
         return (iop);          return (iop);
 }  }
Line 192  popen(command, type)
Line 188  popen(command, type)
  *      if already `pclosed', or waitpid returns an error.   *      if already `pclosed', or waitpid returns an error.
  */   */
 int  int
 pclose(iop)  pclose(FILE *iop)
         FILE *iop;  
 {  {
         struct pid *cur, *last;          struct pid *cur, *last;
         int pstat;          int pstat;
Line 208  pclose(iop)
Line 203  pclose(iop)
                 if (cur->fp == iop)                  if (cur->fp == iop)
                         break;                          break;
         if (cur == NULL) {          if (cur == NULL) {
                 rwlock_unlock(&pidlist_lock);                  (void)rwlock_unlock(&pidlist_lock);
                 return (-1);                  return (-1);
         }          }
   
Line 220  pclose(iop)
Line 215  pclose(iop)
         else          else
                 last->next = cur->next;                  last->next = cur->next;
   
         rwlock_unlock(&pidlist_lock);          (void)rwlock_unlock(&pidlist_lock);
   
         do {          do {
                 pid = waitpid(cur->pid, &pstat, 0);                  pid = waitpid(cur->pid, &pstat, 0);

Legend:
Removed from v.1.28  
changed lines
  Added in v.1.32

CVSweb <webmaster@jp.NetBSD.org>