|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcs_id[] = "$Header: command.c,v 1.13 87/09/11 08:18:00 toddb Exp $"; ! 3: #endif lint ! 4: /* ! 5: * COPYRIGHT 1987 ! 6: * DIGITAL EQUIPMENT CORPORATION ! 7: * MAYNARD, MASSACHUSETTS ! 8: * ALL RIGHTS RESERVED. ! 9: * ! 10: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND ! 11: * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ! 12: * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ! 13: * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ! 14: * ! 15: * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, ! 16: * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT ! 17: * SET FORTH ABOVE. ! 18: * ! 19: * ! 20: * Permission to use, copy, modify, and distribute this software and its ! 21: * documentation for any purpose and without fee is hereby granted, provided ! 22: * that the above copyright notice appear in all copies and that both that ! 23: * copyright notice and this permission notice appear in supporting documentation, ! 24: * and that the name of Digital Equipment Corporation not be used in advertising ! 25: * or publicity pertaining to distribution of the software without specific, ! 26: * written prior permission. ! 27: */ ! 28: ! 29: /* command.c -- interface to exec mh commands. */ ! 30: ! 31: #include "xmh.h" ! 32: #include <sys/types.h> ! 33: #include <sys/stat.h> ! 34: #include <sys/signal.h> ! 35: #include <sys/wait.h> ! 36: #include <sys/time.h> ! 37: #include <sys/resource.h> ! 38: #include <sys/file.h> ! 39: ! 40: #ifndef FD_SET ! 41: #define NFDBITS (8*sizeof(fd_set)) ! 42: #define FD_SETSIZE NFDBITS ! 43: #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) ! 44: #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) ! 45: #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) ! 46: #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) ! 47: #endif ! 48: ! 49: ! 50: ! 51: /* Return the full path name of the given mh command. */ ! 52: ! 53: static char *FullPathOfCommand(str) ! 54: char *str; ! 55: { ! 56: static char result[100]; ! 57: (void) sprintf(result, "%s/%s", defMhPath, str); ! 58: return result; ! 59: } ! 60: ! 61: ! 62: static int childdone; /* Gets nonzero when the child process ! 63: finishes. */ ! 64: ChildDone() ! 65: { ! 66: childdone++; ! 67: } ! 68: ! 69: /* Execute the given command, and wait until it has finished. While the ! 70: command is executing, watch the X socket and cause Xlib to read in any ! 71: incoming data. This will prevent the socket from overflowing during ! 72: long commands. */ ! 73: ! 74: DoCommand(argv, inputfile, outputfile) ! 75: char **argv; /* The command to execute, and its args. */ ! 76: char *inputfile; /* Input file for command. */ ! 77: char *outputfile; /* Output file for command. */ ! 78: { ! 79: FILEPTR fid; ! 80: int pid; ! 81: fd_set readfds, fds; ! 82: FD_ZERO(&fds); ! 83: FD_SET(QConnectionNumber(theDisplay), &fds); ! 84: if (debug) {(void)fprintf(stderr, "Executing %s ...", argv[0]); (void) fflush(stderr);} ! 85: childdone = FALSE; ! 86: (void) signal(SIGCHLD, ChildDone); ! 87: pid = fork(); ! 88: if (pid == -1) Punt("Couldn't fork!"); ! 89: if (pid) { /* We're the parent process. */ ! 90: while (!childdone) { ! 91: readfds = fds; ! 92: (void) select(QConnectionNumber(theDisplay)+1, (int *) &readfds, ! 93: (int *) NULL, (int *) NULL, (struct timeval *) NULL); ! 94: if (FD_ISSET(QConnectionNumber(theDisplay), &readfds)) { ! 95: (void) QXPending(theDisplay); ! 96: } ! 97: } ! 98: (void) wait((union wait *) NULL); ! 99: if (debug) (void)fprintf(stderr, " done\n"); ! 100: } else { /* We're the child process. */ ! 101: if (inputfile) { ! 102: fid = FOpenAndCheck(inputfile, "r"); ! 103: (void) dup2(fileno(fid), fileno(stdin)); ! 104: } ! 105: if (outputfile) { ! 106: fid = FOpenAndCheck(outputfile, "w"); ! 107: (void) dup2(fileno(fid), fileno(stdout)); ! 108: } ! 109: if (!debug) { /* Throw away error messages. */ ! 110: fid = FOpenAndCheck("/dev/null", "w"); ! 111: (void) dup2(fileno(fid), fileno(stderr)); ! 112: if (!outputfile) ! 113: (void) dup2(fileno(fid), fileno(stderr)); ! 114: } ! 115: (void) execv(FullPathOfCommand(argv[0]), argv); ! 116: (void) execvp(argv[0], argv); ! 117: Punt("Execvp failed!"); ! 118: } ! 119: } ! 120: ! 121: ! 122: ! 123: /* Execute the given command, waiting until it's finished. Put the output ! 124: in a newly mallocced string, and return a pointer to that string. */ ! 125: ! 126: char *DoCommandToString(argv) ! 127: char ** argv; ! 128: { ! 129: char *result; ! 130: char *file; ! 131: int fid, length; ! 132: file = DoCommandToFile(argv); ! 133: length = GetFileLength(file); ! 134: result = XtMalloc((unsigned) length + 1); ! 135: fid = myopen(file, O_RDONLY, 0666); ! 136: if (length != read(fid, result, length)) ! 137: Punt("Couldn't read result from DoCommandToString"); ! 138: result[length] = 0; ! 139: if (debug) (void) fprintf(stderr, "('%s')\n", result); ! 140: (void) myclose(fid); ! 141: DeleteFileAndCheck(file); ! 142: return result; ! 143: } ! 144: ! 145: ! 146: #ifdef NOTDEF /* This implementation doesn't work right on null return. */ ! 147: char *DoCommandToString(argv) ! 148: char **argv; ! 149: { ! 150: static char result[1030]; ! 151: int fildes[2], pid, l; ! 152: if (debug) {(void)fprintf(stderr, "Executing %s ...", argv[0]); (void) fflush(stderr);} ! 153: (void) pipe(fildes); ! 154: pid = vfork(); ! 155: if (pid == -1) Punt("Couldn't fork!"); ! 156: if (pid) { ! 157: while (wait((union wait *) 0) == -1) ; ! 158: l = read(fildes[0], result, 1024); ! 159: if (l <= 0) Punt("Couldn't read result from DoCommandToString"); ! 160: (void) myclose(fildes[0]); ! 161: result[l] = 0; ! 162: while (result[--l] == 0) ; ! 163: while (result[l] == '\n') result[l--] = 0; ! 164: if (debug) (void)fprintf(stderr, " done: '%s'\n", result); ! 165: return result; ! 166: } else { ! 167: (void) dup2(fildes[1], fileno(stdout)); ! 168: (void) execv(FullPathOfCommand(argv[0]), argv); ! 169: (void) execvp(argv[0], argv); ! 170: Punt("Execvp failed!"); ! 171: return NULL; ! 172: } ! 173: } ! 174: #endif ! 175: ! 176: ! 177: ! 178: /* Execute the command to a temporary file, and return the name of the file. */ ! 179: ! 180: char *DoCommandToFile(argv) ! 181: char **argv; ! 182: { ! 183: char *name; ! 184: name = MakeNewTempFileName(); ! 185: DoCommand(argv, (char *) NULL, name); ! 186: return name; ! 187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.