Annotation of 43BSD/contrib/spms/src/bin/pexec/execcmd.c, revision 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.