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

Defined functions

onintr defined in line 113; used 5 times
quit defined in line 126; used 2 times

Defined variables

Isfg defined in line 16; used 2 times
Status defined in line 17; used 9 times
Want_to_quit defined in line 18; used 3 times
Last modified: 1985-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 920
Valid CSS Valid XHTML 1.0 Strict