1: /*
   2:  * Copyright (c) 1988 The Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * This code is derived from software written by Ken Arnold and
   6:  * published in UNIX Review, Vol. 6, No. 8.
   7:  *
   8:  * Redistribution and use in source and binary forms, with or without
   9:  * modification, are permitted provided that the following conditions
  10:  * are met:
  11:  * 1. Redistributions of source code must retain the above copyright
  12:  *    notice, this list of conditions and the following disclaimer.
  13:  * 2. Redistributions in binary form must reproduce the above copyright
  14:  *    notice, this list of conditions and the following disclaimer in the
  15:  *    documentation and/or other materials provided with the distribution.
  16:  * 3. All advertising materials mentioning features or use of this software
  17:  *    must display the following acknowledgement:
  18:  *	This product includes software developed by the University of
  19:  *	California, Berkeley and its contributors.
  20:  * 4. Neither the name of the University nor the names of its contributors
  21:  *    may be used to endorse or promote products derived from this software
  22:  *    without specific prior written permission.
  23:  *
  24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34:  * SUCH DAMAGE.
  35:  */
  36: 
  37: #if defined(LIBC_SCCS) && !defined(lint)
  38: static char sccsid[] = "@(#)popen.c	5.15.1 (2.11BSD) 1999/10/24";
  39: #endif /* LIBC_SCCS and not lint */
  40: 
  41: #include <errno.h>
  42: #include <sys/signal.h>
  43: #include <sys/types.h>
  44: #include <sys/wait.h>
  45: #include <stdio.h>
  46: 
  47: static int *pids;
  48: 
  49: FILE *
  50: popen(program, type)
  51:     char *program;
  52:     register char *type;
  53: {
  54:     register FILE *iop;
  55:     int pdes[2], fds, pid;
  56: 
  57:     if (*type != 'r' && *type != 'w' || type[1])
  58:         return (NULL);
  59: 
  60:     if (pids == NULL) {
  61:         if ((fds = getdtablesize()) <= 0)
  62:             return (NULL);
  63:         if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
  64:             return (NULL);
  65:         bzero((char *)pids, fds * sizeof(int));
  66:     }
  67:     if (pipe(pdes) < 0)
  68:         return (NULL);
  69:     switch (pid = vfork()) {
  70:     case -1:            /* error */
  71:         (void) close(pdes[0]);
  72:         (void) close(pdes[1]);
  73:         return (NULL);
  74:         /* NOTREACHED */
  75:     case 0:             /* child */
  76:         if (*type == 'r') {
  77:             if (pdes[1] != fileno(stdout)) {
  78:                 (void) dup2(pdes[1], fileno(stdout));
  79:                 (void) close(pdes[1]);
  80:             }
  81:             (void) close(pdes[0]);
  82:         } else {
  83:             if (pdes[0] != fileno(stdin)) {
  84:                 (void) dup2(pdes[0], fileno(stdin));
  85:                 (void) close(pdes[0]);
  86:             }
  87:             (void) close(pdes[1]);
  88:         }
  89:         execl("/bin/sh", "sh", "-c", program, NULL);
  90:         _exit(127);
  91:         /* NOTREACHED */
  92:     }
  93:     /* parent; assume fdopen can't fail...  */
  94:     if (*type == 'r') {
  95:         iop = fdopen(pdes[0], type);
  96:         (void) close(pdes[1]);
  97:     } else {
  98:         iop = fdopen(pdes[1], type);
  99:         (void) close(pdes[0]);
 100:     }
 101:     pids[fileno(iop)] = pid;
 102:     return (iop);
 103: }
 104: 
 105: int
 106: pclose(iop)
 107:     FILE *iop;
 108: {
 109:     register int fdes;
 110:     sigset_t omask, nmask;
 111:     union wait pstat;
 112:     register int pid;
 113: 
 114:     /*
 115: 	 * pclose returns -1 if stream is not associated with a
 116: 	 * `popened' command, if already `pclosed', or waitpid
 117: 	 * returns an error.
 118: 	 */
 119:     if (pids == NULL || pids[fdes = fileno(iop)] == 0)
 120:         return (-1);
 121:     (void) fclose(iop);
 122:     sigemptyset(&nmask);
 123:     sigaddset(&nmask, SIGINT);
 124:     sigaddset(&nmask, SIGQUIT);
 125:     sigaddset(&nmask, SIGHUP);
 126:     (void) sigprocmask(SIG_BLOCK, &nmask, &omask);
 127:     do {
 128:         pid = waitpid(pids[fdes], (int *) &pstat, 0);
 129:     } while (pid == -1 && errno == EINTR);
 130:     (void) sigprocmask(SIG_SETMASK, &omask, NULL);
 131:     pids[fdes] = 0;
 132:     return (pid == -1 ? -1 : pstat.w_status);
 133: }

Defined functions

pclose defined in line 105; used 51 times
popen defined in line 49; used 93 times

Defined variables

pids defined in line 47; used 8 times
sccsid defined in line 38; never used
Last modified: 1999-10-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 12838
Valid CSS Valid XHTML 1.0 Strict