|
|
1.1 ! root 1: #ident "@(#)popen.c 1.3 'attmail mail(1) command'" ! 2: #ident "@(#)mailx:popen.c 1.4.1.1" ! 3: /* Copyright (c) 1984 AT&T */ ! 4: /* All Rights Reserved */ ! 5: ! 6: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 7: /* The copyright notice above does not evidence any */ ! 8: /* actual or intended publication of such source code. */ ! 9: ! 10: #ident "@(#)mailx:popen.c 1.4" ! 11: /* ! 12: * mailx -- a modified version of a University of California at Berkeley ! 13: * mail program ! 14: * ! 15: * npopen() and npclose() ! 16: * ! 17: * stolen from C library, modified to use SHELL variable ! 18: */ ! 19: /* ! 20: * adb ! 21: * entirely replaced with code stolen from V9 stdio library ! 22: * ! 23: */ ! 24: ! 25: #include <stdio.h> ! 26: #include <signal.h> ! 27: #include <sys/param.h> ! 28: ! 29: #ifndef NSYSFILE ! 30: #define NSYSFILE 4 ! 31: #endif ! 32: ! 33: #define MAXFORKS 20 ! 34: #define tst(a,b) (*mode == 'r'? (b) : (a)) ! 35: #define RDR 0 ! 36: #define WTR 1 ! 37: ! 38: struct a_fork { ! 39: short done; ! 40: short fd; ! 41: int pid; ! 42: int status; ! 43: }; ! 44: static struct a_fork the_fork[MAXFORKS]; ! 45: ! 46: static FILE * ! 47: _popen(cmd,mode,paranoid,args,env) ! 48: char *cmd; ! 49: char *mode; ! 50: int paranoid; ! 51: char **args, **env; ! 52: { ! 53: int p[2]; ! 54: register myside, hisside, pid; ! 55: register i, ind; ! 56: char *Shell, *value(); ! 57: ! 58: if ((Shell = value("SHELL")) == NULL || *Shell=='\0') ! 59: Shell = "/bin/sh"; ! 60: ! 61: for (ind = 0; ind < MAXFORKS; ind++) ! 62: if (the_fork[ind].pid == 0) ! 63: break; ! 64: if (ind == MAXFORKS) ! 65: return NULL; ! 66: if(pipe(p) < 0) ! 67: return NULL; ! 68: myside = tst(p[WTR], p[RDR]); ! 69: hisside = tst(p[RDR], p[WTR]); ! 70: switch (pid = fork()) { ! 71: case -1: ! 72: return NULL; ! 73: case 0: ! 74: /* myside and hisside reverse roles in child */ ! 75: close(myside); ! 76: dup2(hisside, tst(0, 1)); ! 77: if (paranoid!=2) { ! 78: /* a hack for "safety" against incautious SUIDs */ ! 79: setuid(getuid()); ! 80: setgid(getgid()); ! 81: } ! 82: for (i=NSYSFILE; i<_NFILE; i++) ! 83: close(i); ! 84: if (paranoid==2) ! 85: execve(cmd, args, env); ! 86: else if (paranoid==1) ! 87: execl(Shell, "sh", "-c", "-p", cmd, 0); ! 88: else ! 89: execl(Shell, "sh", "-c", cmd, 0); ! 90: _exit(1); ! 91: default: ! 92: the_fork[ind].pid = pid; ! 93: the_fork[ind].fd = myside; ! 94: the_fork[ind].done = 0; ! 95: close(hisside); ! 96: return(fdopen(myside, mode)); ! 97: } ! 98: } ! 99: ! 100: FILE * ! 101: npopen(cmd,mode) ! 102: char *cmd; ! 103: char *mode; ! 104: { ! 105: return _popen(cmd, mode, 0, (char **)NULL, (char **)NULL); ! 106: } ! 107: ! 108: npclose(ptr) ! 109: FILE *ptr; ! 110: { ! 111: register f, r, ind; ! 112: register void (*hstat)(), (*istat)(), (*qstat)(); ! 113: int status; ! 114: ! 115: f = fileno(ptr); ! 116: fclose(ptr); ! 117: for (ind = 0; ind < MAXFORKS; ind++) ! 118: if (the_fork[ind].fd == f && the_fork[ind].pid != 0) ! 119: break; ! 120: if (ind == MAXFORKS) ! 121: return 0; ! 122: if (!the_fork[ind].done) { ! 123: istat = (void (*)())signal(SIGINT, SIG_IGN); ! 124: qstat = (void (*)())signal(SIGQUIT, SIG_IGN); ! 125: hstat = (void (*)())signal(SIGHUP, SIG_IGN); ! 126: do { ! 127: r = wait(&status); ! 128: for (f = 0; f < MAXFORKS; f++) ! 129: if (the_fork[f].pid == r) { ! 130: the_fork[f].done = 1; ! 131: the_fork[f].status = status; ! 132: break; ! 133: } ! 134: } while(r != the_fork[ind].pid && r != -1); ! 135: the_fork[ind].status = r == -1 ? -1 : status; ! 136: signal(SIGINT, istat); ! 137: signal(SIGQUIT, qstat); ! 138: signal(SIGHUP, hstat); ! 139: } ! 140: the_fork[ind].pid = 0; ! 141: return (the_fork[ind].status); ! 142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.