Commit | Line | Data |
---|---|---|
bbbe213d SL |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)popen.c 1.7 (Berkeley) %G%"; | |
3 | #endif | |
4 | ||
e343f97a KS |
5 | #include <stdio.h> |
6 | #include <signal.h> | |
ea394d88 | 7 | #include <errno.h> |
e343f97a KS |
8 | #define tst(a,b) (*mode == 'r'? (b) : (a)) |
9 | #define RDR 0 | |
10 | #define WTR 1 | |
11 | static int popen_pid[20]; | |
ea394d88 | 12 | |
4bc721c3 SL |
13 | #ifdef VMUNIX |
14 | #define mask(s) (1<<((s)-1)) | |
15 | #else | |
16 | #define vfork fork | |
17 | #endif VMUNIX | |
d3c349a9 CS |
18 | #ifndef SIGRETRO |
19 | #define sigchild() | |
20 | #endif | |
e343f97a KS |
21 | |
22 | FILE * | |
23 | popen(cmd,mode) | |
24 | char *cmd; | |
25 | char *mode; | |
26 | { | |
27 | int p[2]; | |
28 | register myside, hisside, pid; | |
29 | ||
30 | if(pipe(p) < 0) | |
31 | return NULL; | |
32 | myside = tst(p[WTR], p[RDR]); | |
33 | hisside = tst(p[RDR], p[WTR]); | |
34 | if((pid = vfork()) == 0) { | |
35 | /* myside and hisside reverse roles in child */ | |
cb9e16fc | 36 | sigchild(); |
e343f97a KS |
37 | close(myside); |
38 | dup2(hisside, tst(0, 1)); | |
39 | close(hisside); | |
40 | execl("/bin/csh", "sh", "-c", cmd, 0); | |
41 | _exit(1); | |
42 | } | |
43 | if(pid == -1) | |
44 | return NULL; | |
45 | popen_pid[myside] = pid; | |
46 | close(hisside); | |
47 | return(fdopen(myside, mode)); | |
48 | } | |
49 | ||
50 | pclose(ptr) | |
51 | FILE *ptr; | |
52 | { | |
39c234be | 53 | register f, r; |
4bc721c3 | 54 | int status, omask; |
ea394d88 | 55 | extern int errno; |
e343f97a KS |
56 | |
57 | f = fileno(ptr); | |
58 | fclose(ptr); | |
ea394d88 | 59 | # ifdef VMUNIX |
4bc721c3 | 60 | omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP)); |
ea394d88 KS |
61 | # endif VMUNIX |
62 | while((r = wait(&status)) != popen_pid[f] && r != -1 && errno != EINTR) | |
e343f97a KS |
63 | ; |
64 | if(r == -1) | |
65 | status = -1; | |
ea394d88 | 66 | # ifdef VMUNIX |
4bc721c3 | 67 | sigsetmask(omask); |
ea394d88 | 68 | # endif VMUNIX |
e343f97a KS |
69 | return(status); |
70 | } |