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