Annotation of 43BSD/contrib/spms/src/bin/pexec/execcmd.c, revision 1.1.1.1

1.1       root        1: /* $Header$ */
                      2: 
                      3: /*
                      4:  * Author: Peter J. Nicklin
                      5:  */
                      6: #include <ctype.h>
                      7: #include <signal.h>
                      8: #include <stdio.h>
                      9: #include <sys/param.h>
                     10: #include "bin.h"
                     11: #include "path.h"
                     12: #include "system.h"
                     13: #include "yesno.h"
                     14: 
                     15: extern char **environ;                 /* global environment cell */
                     16: static int Isfg;                       /* is process in forground? */
                     17: static int Status;                     /* exit status */
                     18: static int Want_to_quit;               /* do we want to quit? */
                     19: 
                     20: /*
                     21:  * execcmd() executes the COMMAND string in the current directory by
                     22:  * forking the shell in the SHELL project environment variable. The
                     23:  * PROJECT environment variable is updated before each fork in case
                     24:  * the directory belongs to a subproject. If the forking process is in
                     25:  * foreground, then an interrupt or quit signal may cause the shell
                     26:  * to terminate. Returns non-zero error status if error.
                     27:  */
                     28: execcmd(project)
                     29:        char *project;                  /* project root directory pathname */
                     30: {
                     31:        extern char *COMMAND;           /* command string to be executed */
                     32:        extern char *SHELLNAME;         /* name of command shell */
                     33:        extern char *SHELLPATH;         /* pathname of command shell */
                     34:        extern int CSHELL;              /* use csh or sh? */
                     35:        extern int CSHRC;               /* execute .cshrc if csh shell */
                     36:        extern int ERRSTATUS;           /* pexec error status */
                     37:        extern int IGNORE_BAD_EXIT;     /* exit if shell doesn't return 0 */
                     38:        extern int PVINDEX;             /* environ index for PROJECT variable */
                     39:        register int (*istat)();        /* interrupt status */
                     40:        register int (*qstat)();        /* quit status */
                     41:        static char pv[PATHSIZE+8] = "PROJECT=";
                     42:                                        /* PROJECT env variable buffer */
                     43:        char *strcpy();                 /* string copy */
                     44:        int isfg();                     /* is a foreground job? */
                     45:        int onintr();                   /* function called on interrupt */
                     46:        int pid;                        /* process id of forked child */
                     47:        int quit();                     /* do we want to quit? */
                     48:        int w;                          /* process id of dead child */
                     49: 
                     50:        /*
                     51:         * The PROJECT environment variable is updated before being
                     52:         * passed to a child process. This could be done by putting
                     53:         * "setenv PROJECT xxxxxx" or "export PROJECT; PROJECT=xxxxxx"
                     54:         * (depending on the shell) in the COMMAND string.
                     55:         */
                     56:        strcpy(pv+8, project);
                     57:        environ[PVINDEX] = pv;
                     58: 
                     59:        if ((pid = FORK()) == 0)
                     60:                {
                     61:                if (CSHELL && CSHRC == NO)
                     62:                        {
                     63:                        execl(SHELLPATH, SHELLNAME, "-f", "-c", COMMAND, 0);
                     64:                        }
                     65:                else    {
                     66:                        execl(SHELLPATH, SHELLNAME, "-c", COMMAND, 0);
                     67:                        }
                     68:                _exit(127);
                     69:                }
                     70:        if ((Isfg = isfg()) == YES)
                     71:                {
                     72:                qstat = signal(SIGQUIT, SIG_IGN);
                     73:                if ((istat = signal(SIGINT, SIG_IGN)) != SIG_IGN)
                     74:                        {
                     75:                        signal(SIGINT, onintr);
                     76:                        signal(SIGQUIT, onintr);
                     77:                        }
                     78:                }
                     79:        else    {
                     80:                istat = signal(SIGINT, SIG_IGN);
                     81:                qstat = signal(SIGQUIT, SIG_IGN);
                     82:                }
                     83:        while ((w = wait(&Status)) != pid && w != -1)
                     84:                continue;
                     85:        if (w == -1)
                     86:                Status = ERRSTATUS;
                     87:        else    {
                     88:                Status >>= NBBY;
                     89:                Status &=  0xff;
                     90:                }
                     91:        if (Want_to_quit)
                     92:                {
                     93:                if (quit() == YES)
                     94:                        exit(Status);
                     95:                Want_to_quit = 0;
                     96:                Status = 0;
                     97:                }
                     98:        if (Isfg == NO)                         /* if in foreground, we */
                     99:                {                               /* always want to catch */
                    100:                signal(SIGINT, istat);          /* interrupts after they */
                    101:                signal(SIGQUIT, qstat);         /* are first turned on */
                    102:                }
                    103:        if (Status != 0 && IGNORE_BAD_EXIT == NO)
                    104:                exit(Status);
                    105:        return(Status);
                    106: }
                    107: 
                    108: 
                    109: 
                    110: /*
                    111:  * onintr() resets signals and indicates that the process may want to exit.
                    112:  */
                    113: onintr()
                    114: {
                    115:        signal(SIGINT, onintr);
                    116:        signal(SIGQUIT, onintr);
                    117: 
                    118:        Want_to_quit = 1;
                    119: }
                    120: 
                    121: 
                    122: 
                    123: /*
                    124:  * quit() returns YES if the process should exit, otherwise NO.
                    125:  */
                    126: quit()
                    127: {
                    128:        register int (*istat)();        /* interrupt status */
                    129:        register int (*qstat)();        /* quit status */
                    130:        extern int NOQUERY;             /* query user about quitting? */
                    131:        char *bp;                       /* buffer pointer */
                    132:        char buf[BUFSIZ];               /* input buffer */
                    133:        char *quitmsg;                  /* quit message string */
                    134:        int fd;                         /* I/O file descriptor */
                    135:        int strlen();                   /* string length */
                    136: 
                    137:        istat = signal(SIGINT, SIG_IGN);
                    138:        qstat = signal(SIGQUIT, SIG_IGN);
                    139: 
                    140:        if (NOQUERY)
                    141:                return(YES);
                    142:        if ((fd = OPEN("/dev/tty", O_RDWR, 0600)) == -1)
                    143:                {
                    144:                pperror("/dev/tty");
                    145:                pxexit();
                    146:                }
                    147:        quitmsg = "Do you really want to quit? [yn](y): ";
                    148:        write(fd, quitmsg, strlen(quitmsg));
                    149:        if (read(fd, buf, BUFSIZ) <= 0)
                    150:                return(YES);
                    151:        for (bp = buf; isspace(*bp); bp++)
                    152:                continue;
                    153:        if (*bp != 'n')
                    154:                return(YES);
                    155:        close(fd);
                    156: 
                    157:        signal(SIGINT, istat);
                    158:        signal(SIGQUIT, qstat);
                    159: 
                    160:        return(NO);
                    161: }

unix.superglobalmegacorp.com

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