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