|
|
1.1 ! root 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: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: * ! 22: */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)popen.c 5.8 (Berkeley) 6/1/90"; ! 26: #endif /* not lint */ ! 27: ! 28: #include <sys/types.h> ! 29: #include <sys/signal.h> ! 30: #include <sys/wait.h> ! 31: #include <stdio.h> ! 32: ! 33: /* ! 34: * Special version of popen which avoids call to shell. This insures noone ! 35: * may create a pipe to a hidden program as a side effect of a list or dir ! 36: * command. ! 37: */ ! 38: static int *pids; ! 39: static int fds; ! 40: ! 41: FILE * ! 42: ftpd_popen(program, type) ! 43: char *program, *type; ! 44: { ! 45: register char *cp; ! 46: FILE *iop; ! 47: int argc, gargc, pdes[2], pid; ! 48: char **pop, *argv[100], *gargv[1000], *vv[2]; ! 49: extern char **glob(), **copyblk(), *strtok(), *malloc(); ! 50: ! 51: if (*type != 'r' && *type != 'w' || type[1]) ! 52: return(NULL); ! 53: ! 54: if (!pids) { ! 55: if ((fds = getdtablesize()) <= 0) ! 56: return(NULL); ! 57: if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL) ! 58: return(NULL); ! 59: bzero((char *)pids, fds * sizeof(int)); ! 60: } ! 61: if (pipe(pdes) < 0) ! 62: return(NULL); ! 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: argv[argc] = (char *)pop; /* save to free later */ ! 78: while (*pop && gargc < 1000) ! 79: gargv[gargc++] = *pop++; ! 80: } ! 81: gargv[gargc] = NULL; ! 82: ! 83: iop = NULL; ! 84: switch(pid = vfork()) { ! 85: case -1: /* error */ ! 86: (void)close(pdes[0]); ! 87: (void)close(pdes[1]); ! 88: goto pfree; ! 89: /* NOTREACHED */ ! 90: case 0: /* child */ ! 91: if (*type == 'r') { ! 92: if (pdes[1] != 1) { ! 93: dup2(pdes[1], 1); ! 94: dup2(pdes[1], 2); /* stderr, too! */ ! 95: (void)close(pdes[1]); ! 96: } ! 97: (void)close(pdes[0]); ! 98: } else { ! 99: if (pdes[0] != 0) { ! 100: dup2(pdes[0], 0); ! 101: (void)close(pdes[0]); ! 102: } ! 103: (void)close(pdes[1]); ! 104: } ! 105: execv(gargv[0], gargv); ! 106: _exit(1); ! 107: } ! 108: /* parent; assume fdopen can't fail... */ ! 109: if (*type == 'r') { ! 110: iop = fdopen(pdes[0], type); ! 111: (void)close(pdes[1]); ! 112: } else { ! 113: iop = fdopen(pdes[1], type); ! 114: (void)close(pdes[0]); ! 115: } ! 116: pids[fileno(iop)] = pid; ! 117: ! 118: pfree: for (argc = 1; argv[argc] != NULL; argc++) { ! 119: blkfree((char **)argv[argc]); ! 120: free((char *)argv[argc]); ! 121: } ! 122: return(iop); ! 123: } ! 124: ! 125: ftpd_pclose(iop) ! 126: FILE *iop; ! 127: { ! 128: register int fdes; ! 129: int omask; ! 130: union wait stat_loc; ! 131: int pid; ! 132: ! 133: /* ! 134: * pclose returns -1 if stream is not associated with a ! 135: * `popened' command, or, if already `pclosed'. ! 136: */ ! 137: if (pids == 0 || pids[fdes = fileno(iop)] == 0) ! 138: return(-1); ! 139: (void)fclose(iop); ! 140: omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); ! 141: while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1); ! 142: (void)sigsetmask(omask); ! 143: pids[fdes] = 0; ! 144: return(pid == -1 ? -1 : stat_loc.w_status); ! 145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.