This is osprg.c in view mode; [Download] [Up]
/* osmsdos/osprg.c */ #include "elvis.h" #include <sys/types.h> #include <dos.h> #include <fcntl.h> #include <io.h> /* Microsoft has an annoying habit of adding underscores to the front of * conventional names. */ #ifndef O_WRONLY # define O_WRONLY _O_WRONLY # define O_RDONLY _O_RDONLY # define O_RDWR _O_RDWR # define O_CREAT _O_CREAT # define O_EXCL _O_EXCL # define O_TRUNC _O_TRUNC #endif static char *cmd; /* the command to run */ static char tempread[100]; /* name of temp file for prog's stdout */ static char tempwrite[100]; /* name of temp file for prog's stdout */ static int fd; /* file descriptor for reading or writing */ static int status; /* exit status of the program */ /* Declares which program we'll run, and what we'll be doing with it. * This function should return True if successful. If there is an error, * it should issue an error message via msg(), and return False. */ BOOLEAN prgopen(char *command, BOOLEAN willwrite, BOOLEAN willread) { /* remember the command we're supposed to run */ cmd = command; /* if we're going to be reading, then choose a tempread name now */ if (willread) { strcpy(tempread, o_directory ? dirpath(tochar8(o_directory), "rdXXXXXX") : "rdXXXXXX"); mktemp(tempread); /* open it and close it, just to make sure it exists */ fd = open(tempread, O_WRONLY|O_CREAT|O_EXCL, 0600); if (fd < 0) { msg(MSG_ERROR, "[s]can't create temp file $1", tempread); return False; } close(fd); } else tempread[0] = '\0'; /* if we'll be writing, then choose a tempwrite name and open it */ if (willwrite) { strcpy(tempwrite, o_directory ? dirpath(tochar8(o_directory), "wrXXXXXX") : "wrXXXXXX"); mktemp(tempwrite); fd = open(tempwrite, O_WRONLY|O_CREAT|O_EXCL, 0600); if (fd < 0) { msg(MSG_ERROR, "[s]can't create temp file $1", tempwrite); if (tempread[0]) remove(tempread); return False; } } else tempwrite[0] = '\0'; return True; } /* Write the contents of buf to the program's stdin, and return nbytes * if successful, or -1 for error. Note that this text should * be subjected to the same kind of transformations as textwrite(). * In fact, it may use textwrite() internally. * * For DOS, this is simply a write() to the temp file. */ int prgwrite(CHAR *buf, int nbytes) { return write(fd, buf, nbytes); } /* Marks the end of writing. Returns True if all is okay, or False if * error. */ BOOLEAN prggo(void) { int old0; /* elvis' stdin */ int old1; /* elvis' stdout */ int old2; /* elvis' stderr */ CHAR *arg[3];/* arguments when evaluating command string */ /* are we supposed to redirect stdin? */ if (tempwrite[0]) { /* close the file we've been writing to */ close(fd); /* save the old stdin as another fd so we can switch back later */ old0 = dup(0); assert(old0 > 2); /* open the temp file as stdin */ close(0); #ifdef NDEBUG (void)open(tempwrite, O_RDONLY); #else assert(open(tempwrite, O_RDONLY) == 0); #endif } /* are we supposed to redirect stdout/stderr ? */ if (tempread[0]) { /* save the old stdout and stderr as other fds */ old1 = dup(1); old2 = dup(2); assert(old1 > 2 && old2 > 2); /* open the temp file as stdout/stderr */ close(1); close(2); #ifdef NDEBUG (void)open(tempread, O_WRONLY); dup(1); #else assert(open(tempread, O_WRONLY) == 1); assert(dup(1) == 2); #endif } #if 0 /* if redirecting anything, then evaluate the command string like a * message, substituting the input and/or output files for $1 and $2 */ if ((tempwrite[0] || tempread[0]) && CHARchr(cmd, '$')) { arg[0] = toCHAR(tempwrite); arg[1] = toCHAR(tempread); arg[2] = NULL; cmd = tochar8(calculate(toCHAR(cmd), arg, True)); if (!cmd) { if (tempwrite[0]) remove(tempwrite); if (tempread[0]) remove(tempread); return False; } } #endif /* run the program */ status = system(cmd); /* if we redirected stdin, undo it now */ if (tempwrite[0]) { /* undo the redirection */ close(0); #ifdef NDEBUG (void)dup(old0); #else assert(dup(old0) == 0); #endif close(old0); /* delete the temp file */ remove(tempwrite); } /* if we redirected stdout/stderr, undo it now and open the temp file */ if (tempread[0]) { /* undo the redirection */ close(1); close(2); #ifdef NDEBUG (void)dup(old1); (void)dup(old2); #else assert(dup(old1) == 1); assert(dup(old2) == 2); #endif close(old1); close(old2); /* open the temp file */ fd = open(tempread, O_RDONLY); assert(fd > 0); } return True; } /* Reads text from the program's stdout, and returns the number of * characters read. At EOF, it returns 0. Note that this text * should be subjected to the same kinds of transformations as * textread(). */ int prgread(CHAR *buf, int nbytes) { return read(fd, buf, nbytes); } /* Clean up, and return the program's exit status. The exit status * should be 0 normally. */ int prgclose(void) { /* if we were reading stdout, then close & delete that temp file */ if (tempread[0]) { close(fd); remove(tempread); } /* return the program's exit status */ return status; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.