V10/cmd/library/dospopen.c
/* library:dospopen.c 1.2 */
#include "sccsid.h"
VERSION(@(#)library:dospopen.c 1.2)
/* popen/pclose: simple MS-DOS piping scheme to imitate UNIX pipes */
/* information needed between popen and pclose */
#include <stdio.h>
static char *prgname[32]; /* program name if write pipe */
static int pipetype[32]; /* 1=read 2=write */
/* open a pipe */
FILE *popen(prg,type)
char *prg,*type;
{ FILE *p;
int ostdout, ostdin;
switch(*type) {
/* for write style pipe, pclose handles program execution */
case 'w' :
if ((p= fopen("\\pipe.tmp","w")) != NULL) {
pipetype[fileno(p)]= 1;
prgname[fileno(p)]= prg;
}
return(p);
/* read pipe must create tmp file, set up stdout to point to the temp
* file, and run the program. note that if the pipe file cannot be
* opened, it'll return a condition indicating pipe failure, which is
* fine.
*/
case 'r' :
if ((p= fopen("\\pipe.tmp","w")) != NULL) {
pipetype[fileno(p)]= 2;
ostdout= dup(fileno(stdout)); /* we need this later */
dup2(fileno(stdout),fileno(p)); /* substitute for stdout */
system(prg); /* run the program */
dup2(fileno(stdout),ostdout); /* repair stdout */
fclose(p); /* close redirected stdout */
return(fopen("\\pipe.tmp","r")); /* return pointer to tmp file */
}
return(NULL); /* everyone has their problems */
/* screwy call or unsupported type */
default :
printf("popen: unknown pipe style\n");
exit(1);
}
}
/* close a pipe */
void pclose(p)
FILE *p;
{ int n;
int ostdout, ostdin;
FILE *p2;
switch(pipetype[fileno(p)]) {
/* close the temp file, open again as read, redirect stdin from that
* file, run the program, then clean up.
*/
case 1 :
n= fileno(p);
fclose(p);
if ((p2= fopen("\\pipe.tmp","r")) != NULL) {
ostdin= dup(fileno(stdin)); /* save stdin for later */
dup2(fileno(stdin),fileno(p2)); /* redirect to tmp file */
system(prgname[n]); /* run the program */
dup2(fileno(stdin),ostdin); /* repair stdin */
fclose(p2);
unlink("\\pipe.tmp"); /* erase tmp file */
return;
}
printf("pclose: could not reopen temporary file\n");
exit(1);
/* close the temp file and remove it */
case 2 :
n= fileno(p); /* get file number for unlink */
fclose(p); /* close the file */
unlink("\\pipe.tmp"); /* erase the file */
return;
/* if we're neither read nor write, we have problems */
default :
printf("pclose: internal error\n");
exit(1);
}
}