# 2.11BSD#431 - /usr/src/libexec/ftpd/popen.c

##### Functions

    ftpd_pclose       X
    ftpd_popen        X

       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 are permitted
       9:  * provided that the above copyright notice and this paragraph are
      10:  * duplicated in all such forms and that any documentation,
      11:  * advertising materials, and other materials related to such
      12:  * distribution and use acknowledge that the software was developed
      13:  * by the University of California, Berkeley.  The name of the
      14:  * University may not be used to endorse or promote products derived
      15:  * from this software without specific prior written permission.
      16:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
      17:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      19:  *
      20:  */
      21:
      22: #if !defined(lint) && defined(DOSCCS)
      23: static char sccsid[] = "@(#)popen.c	5.7.1 (2.11BSD) 1999/10/25";
      24: #endif
      25:
      26: #include <sys/types.h>
      27: #include <sys/signal.h>
      28: #include <sys/wait.h>
      29: #include <stdio.h>
      30: #include <string.h>
      31:
      32: /*
      33:  * Special version of popen which avoids call to shell.  This insures noone
      34:  * may create a pipe to a hidden program as a side effect of a list or dir
      35:  * command.
      36:  */
      37: static int *pids;
      38: static int fds;
      39:
      40: FILE *
      41: ftpd_popen(program, type)
      42:     char *program, *type;
      43: {
      44:     register char *cp;
      45:     FILE *iop;
      46:     int argc, gargc, pdes[2], pid;
      47:     char **pop, *argv[100], *gargv[1000], *vv[2], **ppop, *endprogram;
      48:     extern char **glob(), **copyblk(), *malloc();
      49:
      50:     if (*type != 'r' && *type != 'w' || type[1])
      51:         return(NULL);
      52:
      53:     if (!pids) {
      54:         if ((fds = getdtablesize()) <= 0)
      55:             return(NULL);
      56:         if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
      57:             return(NULL);
      58:         bzero((char *)pids, fds * sizeof(int));
      59:     }
      60:     if (pipe(pdes) < 0)
      61:         return(NULL);
      62:     endprogram = program + strlen(program);
      63:
      64:     /* break up string into pieces */
      65:     for (argc = 0, cp = program;; cp = NULL)
      66:         if (!(argv[argc++] = strtok(cp, " \t\n")))
      67:             break;
      68:
      69:     /* glob each piece */
      70:     gargv[0] = argv[0];
      71:     for (gargc = argc = 1; argv[argc]; argc++) {
      72:         if (!(pop = glob(argv[argc]))) {    /* globbing failed */
      73:             vv[0] = argv[argc];
      74:             vv[1] = NULL;
      75:             pop = copyblk(vv);
      76:         }
      77:         for (ppop = pop; *ppop != NULL; ppop++) {
      78:             if (*ppop >= program && *ppop <= endprogram) {
      79:                 cp = (char *) malloc(strlen(*ppop) + 1);
      80:                 strcpy(cp, *ppop);
      81:                 *ppop = cp;
      82:             }
      83:         }
      84:         argv[argc] = (char *)pop;       /* save to free later */
      85:         while (*pop && gargc < 1000)
      86:             gargv[gargc++] = *pop++;
      87:     }
      88:     gargv[gargc] = NULL;
      89:
      90:     iop = NULL;
      91:     switch(pid = vfork()) {
      92:     case -1:            /* error */
      93:         (void)close(pdes[0]);
      94:         (void)close(pdes[1]);
      95:         goto pfree;
      96:         /* NOTREACHED */
      97:     case 0:             /* child */
      98:         if (*type == 'r') {
      99:             if (pdes[1] != 1) {
     100:                 dup2(pdes[1], 1);
     101:                 dup2(pdes[1], 2);   /* stderr, too! */
     102:                 (void)close(pdes[1]);
     103:             }
     104:             (void)close(pdes[0]);
     105:         } else {
     106:             if (pdes[0] != 0) {
     107:                 dup2(pdes[0], 0);
     108:                 (void)close(pdes[0]);
     109:             }
     110:             (void)close(pdes[1]);
     111:         }
     112:         execv(gargv[0], gargv);
     113:         _exit(1);
     114:     }
     115:     /* parent; assume fdopen can't fail...  */
     116:     if (*type == 'r') {
     117:         iop = fdopen(pdes[0], type);
     118:         (void)close(pdes[1]);
     119:     } else {
     120:         iop = fdopen(pdes[1], type);
     121:         (void)close(pdes[0]);
     122:     }
     123:     pids[fileno(iop)] = pid;
     124:
     125: pfree:  for (argc = 1; argv[argc] != NULL; argc++) {
     126:         blkfree((char **)argv[argc]);
     127:         free((char *)argv[argc]);
     128:     }
     129:     return(iop);
     130: }
     131:
     132: ftpd_pclose(iop)
     133:     FILE *iop;
     134: {
     135:     register int fdes;
     136:     sigset_t  set;
     137:     union wait stat_loc;
     138:     int pid;
     139:
     140:     /*
     141: 	 * pclose returns -1 if stream is not associated with a
     142: 	 * `popened' command, or, if already `pclosed'.
     143: 	 */
     144:     if (pids == 0 || pids[fdes = fileno(iop)] == 0)
     145:         return(-1);
     146:     (void)fclose(iop);
     147:     sigemptyset(&set);
     148:     sigaddset(&set, SIGINT);
     149:     sigaddset(&set, SIGQUIT);
     150:     sigaddset(&set, SIGHUP);
     151:     (void)sigprocmask(SIG_BLOCK, &set, NULL);
     152:     while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1);
     153:     (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
     154:     pids[fdes] = 0;
     155:     return(pid == -1 ? -1 : stat_loc.w_status);
     156: }

#### Defined functions

ftpd_pclose defined in line 132; used 5 times

- in /usr/src/libexec/ftpd/ftpd.c line 74, 516, 905, 911, 918

ftpd_popen defined in line 40; used 3 times

- in /usr/src/libexec/ftpd/ftpd.c line 73, 516, 899

#### Defined variables

fds defined in line 38; used 3 times

- in line 54-58(3)

pids defined in line 37; used 8 times

- in line 53-58(3), 123, 144(2), 152-154(2)

sccsid defined in line 23; never used

Last modified: 1999-10-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1439 |