|
|
1.1 ! root 1: /* @(#)popen.c 4.1 (Berkeley) 12/21/80 */ ! 2: #include <stdio.h> ! 3: #include <signal.h> ! 4: #include <sys/param.h> ! 5: ! 6: #define MAXFORKS 20 ! 7: #define tst(a,b) (*mode == 'r'? (b) : (a)) ! 8: #define RDR 0 ! 9: #define WTR 1 ! 10: ! 11: struct a_fork { ! 12: short done; ! 13: short fd; ! 14: int pid; ! 15: int status; ! 16: }; ! 17: static struct a_fork the_fork[MAXFORKS]; ! 18: ! 19: static FILE * ! 20: _popen(cmd,mode,paranoid) ! 21: char *cmd; ! 22: char *mode; ! 23: int paranoid; ! 24: { ! 25: int p[2]; ! 26: register myside, hisside, pid; ! 27: register i, ind; ! 28: ! 29: for (ind = 0; ind < MAXFORKS; ind++) ! 30: if (the_fork[ind].pid == 0) ! 31: break; ! 32: if (ind == MAXFORKS) ! 33: return NULL; ! 34: if(pipe(p) < 0) ! 35: return NULL; ! 36: myside = tst(p[WTR], p[RDR]); ! 37: hisside = tst(p[RDR], p[WTR]); ! 38: switch (pid = vfork()) { ! 39: case -1: ! 40: return NULL; ! 41: case 0: ! 42: /* myside and hisside reverse roles in child */ ! 43: close(myside); ! 44: dup2(hisside, tst(0, 1)); ! 45: setuid(getuid()); ! 46: setgid(getgid()); ! 47: for (i=NSYSFILE; i<_NFILE; i++) ! 48: close(i); ! 49: if (paranoid) ! 50: execl("/bin/sh", "sh", "-c", "-p", cmd, 0); ! 51: else ! 52: execl("/bin/sh", "sh", "-c", cmd, 0); ! 53: _exit(1); ! 54: default: ! 55: the_fork[ind].pid = pid; ! 56: the_fork[ind].fd = myside; ! 57: the_fork[ind].done = 0; ! 58: close(hisside); ! 59: return(fdopen(myside, mode)); ! 60: } ! 61: } ! 62: ! 63: FILE * ! 64: popen(cmd,mode) ! 65: char *cmd; ! 66: char *mode; ! 67: { ! 68: return _popen(cmd, mode, 0); ! 69: } ! 70: ! 71: FILE * ! 72: ppopen(cmd,mode) ! 73: char *cmd; ! 74: char *mode; ! 75: { ! 76: return _popen(cmd, mode, 1); ! 77: } ! 78: ! 79: pclose(ptr) ! 80: FILE *ptr; ! 81: { ! 82: register f, r, ind, (*hstat)(), (*istat)(), (*qstat)(); ! 83: int status; ! 84: ! 85: f = fileno(ptr); ! 86: fclose(ptr); ! 87: for (ind = 0; ind < MAXFORKS; ind++) ! 88: if (the_fork[ind].fd == f && the_fork[ind].pid != 0) ! 89: break; ! 90: if (ind == MAXFORKS) ! 91: return 0; ! 92: if (!the_fork[ind].done) { ! 93: istat = signal(SIGINT, SIG_IGN); ! 94: qstat = signal(SIGQUIT, SIG_IGN); ! 95: hstat = signal(SIGHUP, SIG_IGN); ! 96: do { ! 97: r = wait(&status); ! 98: for (f = 0; f < MAXFORKS; f++) ! 99: if (the_fork[f].pid == r) { ! 100: the_fork[f].done = 1; ! 101: the_fork[f].status = status; ! 102: break; ! 103: } ! 104: } while(r != the_fork[ind].pid && r != -1); ! 105: the_fork[ind].status = r == -1 ? -1 : status; ! 106: signal(SIGINT, istat); ! 107: signal(SIGQUIT, qstat); ! 108: signal(SIGHUP, hstat); ! 109: } ! 110: the_fork[ind].pid = 0; ! 111: return (the_fork[ind].status); ! 112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.