|
|
1.1 ! root 1: #include <pads.pri> ! 2: #include <CC/signal.h> ! 3: SRCFILE("popen.c") ! 4: static int popen_pid[_NFILE]; ! 5: ! 6: #ifdef BSD ! 7: #define SIG_ARG_TYP SIG_TYP ! 8: #endif ! 9: int pipe(int[2]), wait(int*), vfork(), _exit(int); ! 10: ! 11: FILE *Popen(char *cmd, char *mode) ! 12: { ! 13: int parent = (*mode == 'r') ? 0 : 1; ! 14: int child = (*mode == 'r') ? 1 : 0; ! 15: int p[2]; ! 16: ! 17: if( pipe(p) < 0 ) return NULL; ! 18: int pid = vfork(); ! 19: if( pid == 0) { ! 20: dup2(p[child], child); ! 21: setuid(getuid()); ! 22: setgid(getgid()); ! 23: for( int i = 0; i < _NFILE; ++i ) ! 24: if( i != child ) close(i); ! 25: execl("/bin/sh", "sh", "-c", cmd, 0); ! 26: _exit(1); ! 27: } ! 28: if(pid == -1) ! 29: return NULL; ! 30: close(p[child]); ! 31: popen_pid[p[parent]] = pid; ! 32: return(fdopen(p[parent], mode)); ! 33: } ! 34: ! 35: int Pclose(FILE *ptr) ! 36: { ! 37: static SIG_TYP stat[4]; ! 38: static int sig[4] = { SIGINT, SIGQUIT, SIGHUP, SIGPIPE }; ! 39: int f, r, status, i; ! 40: ! 41: f = fileno(ptr); ! 42: fclose(ptr); ! 43: for( i = 0; i < 4; ++i ) ! 44: stat[i] = signal(sig[i], (SIG_ARG_TYP)SIG_IGN); ! 45: while((r = wait(&status)) != popen_pid[f] && r != -1) {} ! 46: if(r == -1) ! 47: status = -1; ! 48: for( i = 0; i < 4; ++i ) ! 49: signal(sig[i], (SIG_ARG_TYP)stat[i]); ! 50: return(status); ! 51: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.