BSD 3 development
[unix-history] / usr / src / libc / stdio / popen.c
CommitLineData
fc1edd3e
BJ
1#include <stdio.h>
2#include <signal.h>
3#define tst(a,b) (*mode == 'r'? (b) : (a))
4#define RDR 0
5#define WTR 1
6static int popen_pid[20];
7
8FILE *
9popen(cmd,mode)
10char *cmd;
11char *mode;
12{
13 int p[2];
14 register myside, hisside, pid;
15
16 if(pipe(p) < 0)
17 return NULL;
18 myside = tst(p[WTR], p[RDR]);
19 hisside = tst(p[RDR], p[WTR]);
20 if((pid = vfork()) == 0) {
21 /* myside and hisside reverse roles in child */
22 close(myside);
23 dup2(hisside, tst(0, 1));
24 close(hisside);
25 execl("/bin/sh", "sh", "-c", cmd, 0);
26 _exit(1);
27 }
28 if(pid == -1)
29 return NULL;
30 popen_pid[myside] = pid;
31 close(hisside);
32 return(fdopen(myside, mode));
33}
34
35pclose(ptr)
36FILE *ptr;
37{
38 register f, r, (*hstat)(), (*istat)(), (*qstat)();
39 int status;
40
41 f = fileno(ptr);
42 fclose(ptr);
43 istat = signal(SIGINT, SIG_IGN);
44 qstat = signal(SIGQUIT, SIG_IGN);
45 hstat = signal(SIGHUP, SIG_IGN);
46 while((r = wait(&status)) != popen_pid[f] && r != -1)
47 ;
48 if(r == -1)
49 status = -1;
50 signal(SIGINT, istat);
51 signal(SIGQUIT, qstat);
52 signal(SIGHUP, hstat);
53 return(status);
54}