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