#include #include #include "popen.h" #include #ifndef AMIGA STATIC_DATA char template[] = "piXXXXXX"; #else static void mkcmd(char *, char *, char, char *); extern char *mktemp(char *); #endif typedef enum { unopened = 0, reading, writing } pipemode; STATIC_DATA struct { char *command; char *name; pipemode pmode; } pipes[FOPEN_MAX]; FILE * popen( const char *command, const char *mode ) { FILE *current; char *name; int cur; pipemode curmode; #ifdef AMIGA char template[] = "T:piXXXXXX"; #endif /* ** decide on mode. */ if(strcmp(mode,"r") == 0) curmode = reading; else if(strcmp(mode,"w") == 0) curmode = writing; else return NULL; /* ** get a name to use. */ #ifdef AMIGA name = mktemp(template); #else if((name = tempnam(".","pip"))==NULL) return NULL; #endif /* ** If we're reading, just call system to get a file filled with ** output. */ if(curmode == reading) { char cmd[256]; #ifdef AMIGA mkcmd(cmd, command, '>', name); #else sprintf(cmd,"%s > %s",command,name); #endif system(cmd); if((current = fopen(name,"r")) == NULL) return NULL; } else { if((current = fopen(name,"w")) == NULL) return NULL; } cur = fileno(current); pipes[cur].name = strdup(name); pipes[cur].pmode = curmode; pipes[cur].command = strdup(command); return current; } int pclose( FILE * current) { int cur = fileno(current),rval; /* ** check for an open file. */ if(pipes[cur].pmode == unopened) return -1; if(pipes[cur].pmode == reading) { /* ** input pipes are just files we're done with. */ rval = fclose(current); unlink(pipes[cur].name); } else { /* ** output pipes are temporary files we have ** to cram down the throats of programs. */ char command[256]; fclose(current); #ifdef AMIGA mkcmd(command, pipes[cur].command, '<', pipes[cur].name); #else sprintf(command,"%s < %s",pipes[cur].command,pipes[cur].name); #endif rval = system(command); unlink(pipes[cur].name); } /* ** clean up current pipe. */ pipes[cur].pmode = unopened; free(pipes[cur].name); free(pipes[cur].command); return rval; } #ifdef AMIGA /* ^%#@%! Amiga CLI requires I/O redirection immediately after command name. Assume command name ends at first space and place redirection there */ STATIC_DATA void mkcmd(char *cmd, char *command, char op, char *name) { while (*command == ' ') { command++; } while (*command != ' ' && *command != '\000') { *cmd++ = *command++; } *cmd++ = ' '; *cmd++ = op; strcpy(cmd, name); cmd += strlen(name); while (*command != '\000') { *cmd++ = *command++; } *cmd = '\000'; return; } #endif