xref: /csrg-svn/lib/libc/gen/popen.c (revision 14718)
1*14718Ssam /* @(#)popen.c	4.3 (Berkeley) 08/18/83 */
22024Swnj #include <stdio.h>
32024Swnj #include <signal.h>
42024Swnj #define	tst(a,b)	(*mode == 'r'? (b) : (a))
52024Swnj #define	RDR	0
62024Swnj #define	WTR	1
72024Swnj static	int	popen_pid[20];
82024Swnj 
92024Swnj FILE *
102024Swnj popen(cmd,mode)
112024Swnj char	*cmd;
122024Swnj char	*mode;
132024Swnj {
142024Swnj 	int p[2];
152024Swnj 	register myside, hisside, pid;
162024Swnj 
172024Swnj 	if(pipe(p) < 0)
182024Swnj 		return NULL;
192024Swnj 	myside = tst(p[WTR], p[RDR]);
202024Swnj 	hisside = tst(p[RDR], p[WTR]);
219194Ssam 	if((pid = fork()) == 0) {
222024Swnj 		/* myside and hisside reverse roles in child */
232024Swnj 		close(myside);
24*14718Ssam 		if (hisside != tst(0, 1)) {
25*14718Ssam 			dup2(hisside, tst(0, 1));
26*14718Ssam 			close(hisside);
27*14718Ssam 		}
282024Swnj 		execl("/bin/sh", "sh", "-c", cmd, 0);
292024Swnj 		_exit(1);
302024Swnj 	}
312024Swnj 	if(pid == -1)
322024Swnj 		return NULL;
332024Swnj 	popen_pid[myside] = pid;
342024Swnj 	close(hisside);
352024Swnj 	return(fdopen(myside, mode));
362024Swnj }
372024Swnj 
382024Swnj pclose(ptr)
392024Swnj FILE *ptr;
402024Swnj {
412024Swnj 	register f, r, (*hstat)(), (*istat)(), (*qstat)();
422024Swnj 	int status;
432024Swnj 
442024Swnj 	f = fileno(ptr);
452024Swnj 	fclose(ptr);
462024Swnj 	istat = signal(SIGINT, SIG_IGN);
472024Swnj 	qstat = signal(SIGQUIT, SIG_IGN);
482024Swnj 	hstat = signal(SIGHUP, SIG_IGN);
492024Swnj 	while((r = wait(&status)) != popen_pid[f] && r != -1)
502024Swnj 		;
512024Swnj 	if(r == -1)
522024Swnj 		status = -1;
532024Swnj 	signal(SIGINT, istat);
542024Swnj 	signal(SIGQUIT, qstat);
552024Swnj 	signal(SIGHUP, hstat);
562024Swnj 	return(status);
572024Swnj }
58