xref: /csrg-svn/lib/libc/gen/popen.c (revision 15073)
1*15073Skarels /* @(#)popen.c	4.4 (Berkeley) 09/25/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);
2414718Ssam 		if (hisside != tst(0, 1)) {
2514718Ssam 			dup2(hisside, tst(0, 1));
2614718Ssam 			close(hisside);
2714718Ssam 		}
282024Swnj 		execl("/bin/sh", "sh", "-c", cmd, 0);
292024Swnj 		_exit(1);
302024Swnj 	}
31*15073Skarels 	if(pid == -1) {
32*15073Skarels 		close(myside);
33*15073Skarels 		close(hisside);
342024Swnj 		return NULL;
35*15073Skarels 	}
362024Swnj 	popen_pid[myside] = pid;
372024Swnj 	close(hisside);
382024Swnj 	return(fdopen(myside, mode));
392024Swnj }
402024Swnj 
412024Swnj pclose(ptr)
422024Swnj FILE *ptr;
432024Swnj {
442024Swnj 	register f, r, (*hstat)(), (*istat)(), (*qstat)();
452024Swnj 	int status;
462024Swnj 
472024Swnj 	f = fileno(ptr);
482024Swnj 	fclose(ptr);
492024Swnj 	istat = signal(SIGINT, SIG_IGN);
502024Swnj 	qstat = signal(SIGQUIT, SIG_IGN);
512024Swnj 	hstat = signal(SIGHUP, SIG_IGN);
522024Swnj 	while((r = wait(&status)) != popen_pid[f] && r != -1)
532024Swnj 		;
542024Swnj 	if(r == -1)
552024Swnj 		status = -1;
562024Swnj 	signal(SIGINT, istat);
572024Swnj 	signal(SIGQUIT, qstat);
582024Swnj 	signal(SIGHUP, hstat);
592024Swnj 	return(status);
602024Swnj }
61