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