Annotation of researchv9/X11/src/X.V11R1/clients/xmh/command.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.