# 2.11BSD#431 - /usr/src/usr.sbin/cron/popen.c

##### Functions

    cron_pclose       X
    cron_popen        X

##### Macros

    WANT_GLOBBING     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: /* this came out of the ftpd sources; it's been modified to avoid the
      23:  * globbing stuff since we don't need it.  also execvp instead of execv.
      24:  */
      25:
      26: #if !defined(lint) && defined(DOSCCS)
      27: static char sccsid[] = "@(#)popen.c	5.7.2 (2.11BSD) 1999/08/05";
      28: #endif
      29:
      30: #include "cron.h"
      31: #include <errno.h>
      32: #include <sys/signal.h>
      33:
      34: #define WANT_GLOBBING 0
      35:
      36: /*
      37:  * Special version of popen which avoids call to shell.  This insures noone
      38:  * may create a pipe to a hidden program as a side effect of a list or dir
      39:  * command.
      40:  */
      41: static PID_T *pids;
      42: static int fds;
      43:
      44: FILE *
      45: cron_popen(program, type)
      46:     char *program, *type;
      47: {
      48:     register char *cp;
      49:     FILE *iop;
      50:     int argc, pdes[2];
      51:     PID_T pid;
      52:     char *argv[100];
      53: #if WANT_GLOBBING
      54:     char **pop, *vv[2];
      55:     int gargc;
      56:     char *gargv[1000];
      57:     extern char **glob(), **copyblk();
      58: #endif
      59:
      60:     if (*type != 'r' && *type != 'w' || type[1])
      61:         return(NULL);
      62:
      63:     if (!pids) {
      64:         if ((fds = getdtablesize()) <= 0)
      65:             return(NULL);
      66:         if (!(pids = (PID_T *)malloc((u_int)(fds * sizeof(PID_T)))))
      67:             return(NULL);
      68:         bzero((char *)pids, fds * sizeof(PID_T));
      69:     }
      70:     if (pipe(pdes) < 0)
      71:         return(NULL);
      72:
      73:     /* break up string into pieces */
      74:     for (argc = 0, cp = program;; cp = NULL)
      75:         if (!(argv[argc++] = strtok(cp, " \t\n")))
      76:             break;
      77:
      78: #if WANT_GLOBBING
      79:     /* glob each piece */
      80:     gargv[0] = argv[0];
      81:     for (gargc = argc = 1; argv[argc]; argc++) {
      82:         if (!(pop = glob(argv[argc]))) {    /* globbing failed */
      83:             vv[0] = argv[argc];
      84:             vv[1] = NULL;
      85:             pop = copyblk(vv);
      86:         }
      87:         argv[argc] = (char *)pop;       /* save to free later */
      88:         while (*pop && gargc < 1000)
      89:             gargv[gargc++] = *pop++;
      90:     }
      91:     gargv[gargc] = NULL;
      92: #endif
      93:
      94:     iop = NULL;
      95:     switch(pid = vfork()) {
      96:     case -1:            /* error */
      97:         (void)close(pdes[0]);
      98:         (void)close(pdes[1]);
      99:         goto pfree;
     100:         /* NOTREACHED */
     101:     case 0:             /* child */
     102:         if (*type == 'r') {
     103:             if (pdes[1] != 1) {
     104:                 dup2(pdes[1], 1);
     105:                 dup2(pdes[1], 2);   /* stderr, too! */
     106:                 (void)close(pdes[1]);
     107:             }
     108:             (void)close(pdes[0]);
     109:         } else {
     110:             if (pdes[0] != 0) {
     111:                 dup2(pdes[0], 0);
     112:                 (void)close(pdes[0]);
     113:             }
     114:             (void)close(pdes[1]);
     115:         }
     116: #if WANT_GLOBBING
     117:         execvp(gargv[0], gargv);
     118: #else
     119:         execvp(argv[0], argv);
     120: #endif
     121:         _exit(1);
     122:     }
     123:     /* parent; assume fdopen can't fail...  */
     124:     if (*type == 'r') {
     125:         iop = fdopen(pdes[0], type);
     126:         (void)close(pdes[1]);
     127:     } else {
     128:         iop = fdopen(pdes[1], type);
     129:         (void)close(pdes[0]);
     130:     }
     131:     pids[fileno(iop)] = pid;
     132:
     133: pfree:
     134: #if WANT_GLOBBING
     135:     for (argc = 1; argv[argc] != NULL; argc++) {
     136: /*		blkfree((char **)argv[argc]);	*/
     137:         free((char *)argv[argc]);
     138:     }
     139: #endif
     140:     return(iop);
     141: }
     142:
     143: int
     144: cron_pclose(iop)
     145:     FILE *iop;
     146: {
     147:     register int fdes;
     148:     sigset_t omask, nmask;
     149:     WAIT_T stat_loc;
     150:     register PID_T pid;
     151:
     152:     /*
     153: 	 * pclose returns -1 if stream is not associated with a
     154: 	 * `popened' command, or, if already `pclosed'.
     155: 	 */
     156:     if (pids == 0 || pids[fdes = fileno(iop)] == 0)
     157:         return(-1);
     158:     (void)fclose(iop);
     159:     sigemptyset(&nmask);
     160:     sigaddset(&nmask, SIGINT);
     161:     sigaddset(&nmask, SIGQUIT);
     162:     sigaddset(&nmask, SIGHUP);
     163:     sigprocmask(SIG_BLOCK, &nmask, &omask);
     164:     do  {
     165:         pid = waitpid(pids[fdes], &stat_loc, NULL);
     166:         } while (pid == -1 && errno == EINTR);
     167:     (void)sigprocmask(SIG_SETMASK, &omask, NULL);
     168:     pids[fdes] = 0;
     169:     return (pid == -1 ? -1 : WEXITSTATUS(stat_loc));
     170: }

#### Defined functions

cron_pclose defined in line 143; never used
cron_popen defined in line 44; used 1 times

- in /usr/src/usr.sbin/cron/do_command.c line 341

#### Defined variables

fds defined in line 42; used 3 times

- in line 64-68(3)

sccsid defined in line 27; never used

#### Defined macros

WANT_GLOBBING defined in line 34; used 4 times

- in line 53, 78, 116, 134

Last modified: 1999-08-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1615 |