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