xref: /original-bsd/usr.bin/mail/popen.c (revision 0b685140)
1 #include <stdio.h>
2 #include <signal.h>
3 #define	tst(a,b)	(*mode == 'r'? (b) : (a))
4 #define	RDR	0
5 #define	WTR	1
6 static	int	popen_pid[20];
7 static	char	*sccsid = "@(#)popen.c	1.2 09/19/81";
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 = vfork()) == 0) {
22 		/* myside and hisside reverse roles in child */
23 		close(myside);
24 		dup2(hisside, tst(0, 1));
25 		close(hisside);
26 		execl("/bin/csh", "sh", "-c", cmd, 0);
27 		_exit(1);
28 	}
29 	if(pid == -1)
30 		return NULL;
31 	popen_pid[myside] = pid;
32 	close(hisside);
33 	return(fdopen(myside, mode));
34 }
35 
36 pclose(ptr)
37 FILE *ptr;
38 {
39 	register f, r;
40 	int status;
41 
42 	f = fileno(ptr);
43 	fclose(ptr);
44 	sighold(SIGINT);
45 	sighold(SIGQUIT);
46 	sighold(SIGHUP);
47 	while((r = wait(&status)) != popen_pid[f] && r != -1)
48 		;
49 	if(r == -1)
50 		status = -1;
51 	sigrelse(SIGINT);
52 	sigrelse(SIGQUIT);
53 	sigrelse(SIGHUP);
54 	return(status);
55 }
56