|
|
1.1 root 1: /*
2: * Standard I/O library
3: * Make streams to or from a process.
4: *
5: * Modified for use with the COHERENT mail system.
6: * This version of popen closes all file descriptors
7: * above 2 (stderr) in the child process.
8: */
9:
10: #include <stdio.h>
11: #include <signal.h>
12:
13: #define R 0 /* Pipe read descriptor index */
14: #define W 1 /* Pipe write descriptor index */
15:
16: void close_fds();
17:
18: static int poppid[_NFILE];
19:
20: FILE *
21: popen(command, type)
22: char *command, *type;
23: {
24: register mode;
25: register fd;
26: int pd[2];
27:
28: if (pipe(pd) < 0)
29: return (NULL);
30: if (*type == 'w') {
31: mode = W;
32: fd = pd[W];
33: } else {
34: mode = R;
35: fd = pd[R];
36: }
37: if ((poppid[fd] = fork()) < 0) {
38: close(pd[R]);
39: close(pd[W]);
40: return (NULL);
41: }
42: if (poppid[fd] == 0) { /* Child */
43: if (mode == W) {
44: close(pd[W]);
45: close(fileno(stdin));
46: dup(pd[R]);
47: close(pd[R]);
48: } else {
49: close(pd[R]);
50: close(fileno(stdout));
51: dup(pd[W]);
52: close(pd[W]);
53: }
54:
55: /* Clean up any file descriptors which may be laying around. */
56: close_fds();
57:
58: execl("/bin/sh", "sh", "-c", command, NULL);
59: exit(1);
60: }
61: if (mode == W) {
62: close(pd[R]);
63: return (fdopen(pd[W], "w"));
64: } else {
65: close(pd[W]);
66: return (fdopen(pd[R], "r"));
67: }
68: }
69:
70: pclose(stream)
71: FILE *stream;
72: {
73: register fd;
74: register pid, wpid;
75: int status;
76: int (*hupfun)(), (*intfun)(), (*quitfun)();
77:
78: char BOBerrmsg[80];
79:
80: fd = fileno(stream);
81: pid = poppid[fd];
82: poppid[fd] = 0;
83: if (pid==0 || fclose(stream)==EOF){
84: return (-1);
85: }
86: hupfun = signal(SIGHUP, SIG_IGN);
87: intfun = signal(SIGINT, SIG_IGN);
88: quitfun = signal(SIGQUIT, SIG_IGN);
89:
90: while ((wpid = wait(&status))!=pid && wpid>=0){
91: ;
92: }
93:
94: if (wpid < 0){
95: sprintf(BOBerrmsg,"wpid is %d",wpid);
96: error_log(BOBerrmsg);
97: status = -1;
98: }
99: signal(SIGHUP, hupfun);
100: signal(SIGINT, intfun);
101: signal(SIGQUIT, quitfun);
102: return (status);
103: }
104:
105:
106: /* Close all file descriptors above 2 (stderr). */
107:
108: void
109: close_fds()
110: {
111: int fd;
112: for (fd = fileno(stderr) + 1; fd <= _NFILE; ++fd) {
113: (void) close(fd);
114: } /* for fd = stderr to number_of_file_descriptors */
115: } /* close_fds() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.