Commit | Line | Data |
---|---|---|
fec6f225 | 1 | /* @(#)popen.c 4.7 (Berkeley) %G% */ |
99756664 | 2 | |
01a56307 BJ |
3 | #include <stdio.h> |
4 | #include <signal.h> | |
43d12555 | 5 | #include <sys/param.h> |
99756664 | 6 | |
01a56307 BJ |
7 | #define tst(a,b) (*mode == 'r'? (b) : (a)) |
8 | #define RDR 0 | |
9 | #define WTR 1 | |
99756664 | 10 | |
fec6f225 S |
11 | extern char *malloc(); |
12 | ||
13 | static int *popen_pid; | |
14 | static int nfiles; | |
01a56307 BJ |
15 | |
16 | FILE * | |
17 | popen(cmd,mode) | |
99756664 SL |
18 | char *cmd; |
19 | char *mode; | |
01a56307 BJ |
20 | { |
21 | int p[2]; | |
99756664 | 22 | int myside, hisside, pid; |
01a56307 | 23 | |
fec6f225 S |
24 | if (nfiles <= 0) |
25 | nfiles = getdtablesize(); | |
26 | if (popen_pid == NULL) { | |
27 | popen_pid = (int *)malloc(nfiles * sizeof *popen_pid); | |
28 | if (popen_pid == NULL) | |
29 | return (NULL); | |
30 | for (pid = 0; pid < nfiles; pid++) | |
31 | popen_pid[pid] = -1; | |
32 | } | |
99756664 SL |
33 | if (pipe(p) < 0) |
34 | return (NULL); | |
01a56307 BJ |
35 | myside = tst(p[WTR], p[RDR]); |
36 | hisside = tst(p[RDR], p[WTR]); | |
fec6f225 | 37 | if ((pid = vfork()) == 0) { |
01a56307 BJ |
38 | /* myside and hisside reverse roles in child */ |
39 | close(myside); | |
482b978e SL |
40 | if (hisside != tst(0, 1)) { |
41 | dup2(hisside, tst(0, 1)); | |
42 | close(hisside); | |
43 | } | |
fec6f225 S |
44 | execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); |
45 | _exit(127); | |
01a56307 | 46 | } |
99756664 | 47 | if (pid == -1) { |
2337e291 MK |
48 | close(myside); |
49 | close(hisside); | |
99756664 | 50 | return (NULL); |
2337e291 | 51 | } |
01a56307 BJ |
52 | popen_pid[myside] = pid; |
53 | close(hisside); | |
99756664 | 54 | return (fdopen(myside, mode)); |
01a56307 BJ |
55 | } |
56 | ||
57 | pclose(ptr) | |
99756664 | 58 | FILE *ptr; |
01a56307 | 59 | { |
99756664 | 60 | int child, pid, status, omask; |
01a56307 | 61 | |
99756664 | 62 | child = popen_pid[fileno(ptr)]; |
fec6f225 | 63 | popen_pid[fileno(ptr)] = -1; |
01a56307 | 64 | fclose(ptr); |
fec6f225 S |
65 | if (child == -1) |
66 | return (-1); | |
67 | omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); | |
99756664 | 68 | while ((pid = wait(&status)) != child && pid != -1) |
01a56307 | 69 | ; |
99756664 SL |
70 | (void) sigsetmask(omask); |
71 | return (pid == -1 ? -1 : status); | |
01a56307 | 72 | } |