|
|
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.