xref: /csrg-svn/lib/libc/gen/popen.c (revision 35451)
122101Smckusick /*
2*35451Sbostic  * Copyright (c) 1988 The Regents of the University of California.
3*35451Sbostic  * All rights reserved.
4*35451Sbostic  *
5*35451Sbostic  * This code is derived from software written by Ken Arnold and published
6*35451Sbostic  * in UNIX Review, Vol. 6, No. 8.
7*35451Sbostic  *
8*35451Sbostic  * Redistribution and use in source and binary forms are permitted
9*35451Sbostic  * provided that the above copyright notice and this paragraph are
10*35451Sbostic  * duplicated in all such forms and that any documentation,
11*35451Sbostic  * advertising materials, and other materials related to such
12*35451Sbostic  * distribution and use acknowledge that the software was developed
13*35451Sbostic  * by the University of California, Berkeley.  The name of the
14*35451Sbostic  * University may not be used to endorse or promote products derived
15*35451Sbostic  * from this software without specific prior written permission.
16*35451Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17*35451Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18*35451Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1922101Smckusick  */
2016676Ssam 
2126575Sdonn #if defined(LIBC_SCCS) && !defined(lint)
22*35451Sbostic static char sccsid[] = "@(#)popen.c	5.6 (Berkeley) 08/31/88";
23*35451Sbostic #endif /* LIBC_SCCS and not lint */
2422101Smckusick 
252024Swnj #include <stdio.h>
2616676Ssam 
27*35451Sbostic #define	MAXFILES	32
282024Swnj 
29*35451Sbostic typedef struct {
30*35451Sbostic 	int pid;
31*35451Sbostic 	int status;
32*35451Sbostic } PID_STRUCT;
3316676Ssam 
34*35451Sbostic PID_STRUCT pids[MAXFILES];
3518246Sserge 
362024Swnj FILE *
37*35451Sbostic popen(program, type)
38*35451Sbostic char *program, *type;
392024Swnj {
40*35451Sbostic 	char **argv;
41*35451Sbostic 	int pdes[2], pid;
42*35451Sbostic 	FILE *iop;
432024Swnj 
44*35451Sbostic 	if (*type != 'r' && *type != 'w')
45*35451Sbostic 		return NULL;
46*35451Sbostic 	if (pipe(pdes) < 0)
47*35451Sbostic 		return NULL;
48*35451Sbostic 	switch(pid = fork()) {
49*35451Sbostic 	case -1:
50*35451Sbostic 		iop = NULL;
51*35451Sbostic 		break;
52*35451Sbostic 	case 0:			/* child */
53*35451Sbostic 		if (*type == 'r') {
54*35451Sbostic 			close(1);
55*35451Sbostic 			dup(pdes[1]);
5614718Ssam 		}
57*35451Sbostic 		else {
58*35451Sbostic 			close(0);
59*35451Sbostic 			dup(pdes[0]);
60*35451Sbostic 		}
61*35451Sbostic 		close(pdes[1]);
62*35451Sbostic 		close(pdes[0]);
63*35451Sbostic 		execl("/bin/sh", "sh", "-c", program, NULL);
64*35451Sbostic 		exit(-1);
65*35451Sbostic 		/* NOTREACHED */
66*35451Sbostic 	default:
67*35451Sbostic 		if (*type == 'r') {
68*35451Sbostic 			iop = fdopen(pdes[0], "r");
69*35451Sbostic 			close(pdes[1]);
70*35451Sbostic 		} else {
71*35451Sbostic 			iop = fdopen(pdes[0], "w");
72*35451Sbostic 			close(pdes[0]);
73*35451Sbostic 		}
74*35451Sbostic 		break;
752024Swnj 	}
76*35451Sbostic 	if (iop != NULL)
77*35451Sbostic 		pids[fileno(iop)].pid = pid;
78*35451Sbostic 	else {
79*35451Sbostic 		close(pdes[0]);
80*35451Sbostic 		close(pdes[1]);
8115073Skarels 	}
82*35451Sbostic 	return iop;
832024Swnj }
842024Swnj 
85*35451Sbostic pclose(iop)
86*35451Sbostic FILE *iop;
872024Swnj {
88*35451Sbostic 	int status;
89*35451Sbostic 	int pid, fdes, i;
902024Swnj 
91*35451Sbostic 	fdes = fileno(iop);
92*35451Sbostic 	fclose(iop);
93*35451Sbostic 	if (pids[fdes].pid == 0)
94*35451Sbostic 		return pids[fdes].status;
95*35451Sbostic 	for (;;) {
96*35451Sbostic 		pid = wait(&status);
97*35451Sbostic 		if (pid < 0)
98*35451Sbostic 			return -1;
99*35451Sbostic 		if (pid == pids[fdes].pid) {
100*35451Sbostic 			pids[fdes].pid = 0;
101*35451Sbostic 			return status;
102*35451Sbostic 		}
103*35451Sbostic 		for (i = 0; i < MAXFILES; i++)
104*35451Sbostic 			if (pids[i].pid == pid) {
105*35451Sbostic 				pids[i].pid = 0;
106*35451Sbostic 				pids[i].status = status;
107*35451Sbostic 				break;
108*35451Sbostic 			}
109*35451Sbostic 	}
1102024Swnj }
111