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