xref: /original-bsd/usr.bin/mail/popen.c (revision e5dafb11)
1 #include <stdio.h>
2 #include <signal.h>
3 #include <errno.h>
4 #define	tst(a,b)	(*mode == 'r'? (b) : (a))
5 #define	RDR	0
6 #define	WTR	1
7 static	int	popen_pid[20];
8 static	char	*sccsid = "@(#)popen.c	1.3 03/15/82";
9 
10 # ifndef VMUNIX
11 # define vfork	fork
12 # endif VMUNIX
13 
14 FILE *
15 popen(cmd,mode)
16 char	*cmd;
17 char	*mode;
18 {
19 	int p[2];
20 	register myside, hisside, pid;
21 
22 	if(pipe(p) < 0)
23 		return NULL;
24 	myside = tst(p[WTR], p[RDR]);
25 	hisside = tst(p[RDR], p[WTR]);
26 	if((pid = vfork()) == 0) {
27 		/* myside and hisside reverse roles in child */
28 		close(myside);
29 		dup2(hisside, tst(0, 1));
30 		close(hisside);
31 		execl("/bin/csh", "sh", "-c", cmd, 0);
32 		_exit(1);
33 	}
34 	if(pid == -1)
35 		return NULL;
36 	popen_pid[myside] = pid;
37 	close(hisside);
38 	return(fdopen(myside, mode));
39 }
40 
41 pclose(ptr)
42 FILE *ptr;
43 {
44 	register f, r;
45 	int status;
46 	extern int errno;
47 
48 	f = fileno(ptr);
49 	fclose(ptr);
50 # ifdef VMUNIX
51 	sighold(SIGINT);
52 	sighold(SIGQUIT);
53 	sighold(SIGHUP);
54 # endif VMUNIX
55 	while((r = wait(&status)) != popen_pid[f] && r != -1 && errno != EINTR)
56 		;
57 	if(r == -1)
58 		status = -1;
59 # ifdef VMUNIX
60 	sigrelse(SIGINT);
61 	sigrelse(SIGQUIT);
62 	sigrelse(SIGHUP);
63 # endif VMUNIX
64 	return(status);
65 }
66