xref: /csrg-svn/lib/libc/gen/popen.c (revision 9194)
1*9194Ssam /* @(#)popen.c	4.2 (Berkeley) 11/14/82 */
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]);
21*9194Ssam 	if((pid = fork()) == 0) {
222024Swnj 		/* myside and hisside reverse roles in child */
232024Swnj 		close(myside);
242024Swnj 		dup2(hisside, tst(0, 1));
252024Swnj 		close(hisside);
262024Swnj 		execl("/bin/sh", "sh", "-c", cmd, 0);
272024Swnj 		_exit(1);
282024Swnj 	}
292024Swnj 	if(pid == -1)
302024Swnj 		return NULL;
312024Swnj 	popen_pid[myside] = pid;
322024Swnj 	close(hisside);
332024Swnj 	return(fdopen(myside, mode));
342024Swnj }
352024Swnj 
362024Swnj pclose(ptr)
372024Swnj FILE *ptr;
382024Swnj {
392024Swnj 	register f, r, (*hstat)(), (*istat)(), (*qstat)();
402024Swnj 	int status;
412024Swnj 
422024Swnj 	f = fileno(ptr);
432024Swnj 	fclose(ptr);
442024Swnj 	istat = signal(SIGINT, SIG_IGN);
452024Swnj 	qstat = signal(SIGQUIT, SIG_IGN);
462024Swnj 	hstat = signal(SIGHUP, SIG_IGN);
472024Swnj 	while((r = wait(&status)) != popen_pid[f] && r != -1)
482024Swnj 		;
492024Swnj 	if(r == -1)
502024Swnj 		status = -1;
512024Swnj 	signal(SIGINT, istat);
522024Swnj 	signal(SIGQUIT, qstat);
532024Swnj 	signal(SIGHUP, hstat);
542024Swnj 	return(status);
552024Swnj }
56