1: /*	@(#)sh.sem.c	2.1	SCCS id keyword	*/
   2: /* Copyright (c) 1980 Regents of the University of California */
   3: #include "sh.h"
   4: 
   5: /*
   6:  * C shell
   7:  */
   8: 
   9: execute(t, pipein, pipeout)
  10:     register struct command *t;
  11:     int *pipein, *pipeout;
  12: {
  13:     int pid, flags, pv[2];
  14:     register struct command *t1;
  15:     register char *cp;
  16:     bool forked = 0;
  17:     bool shudint, shudhup;
  18: #ifdef VFORK
  19:     int (*savint)(), vffree();
  20:     int ochild, osetintr, ohaderr, otimflg, odidfds, odidcch;
  21:     int oSHIN, oSHOUT, oSHDIAG, oOLDSTD;
  22:     int isvfork = 0;
  23: #endif
  24: 
  25:     if (t == 0)
  26:         return;
  27:     switch (t->t_dtyp) {
  28: 
  29:     case TCOM:
  30:         cp = t->t_dcom[0];
  31:         if ((cp[0] & (QUOTE|TRIM)) == QUOTE)
  32:             strcpy(cp, cp + 1);
  33:         if ((t->t_dflg & FREDO) == 0)
  34:             Dfix(t);        /* $ " ' \ */
  35:         if (t->t_dcom[0] == 0)
  36:             return;
  37:         /* fall into... */
  38: 
  39:     case TPAR:
  40:         flags = t->t_dflg;
  41:         if (flags & FPOU)
  42:             mypipe(pipeout);
  43:         /*
  44: 		 * A child will be interruptible only under very
  45: 		 * certain conditions:
  46: 		 *	we must be monkeying with interrupts
  47: 		 *	the child must not be &'ed
  48: 		 *	we must not have had an "onintr -"
  49: 		 */
  50:         shudint = setintr && (flags & FINT) == 0 && (!gointr || !eq(gointr, "-"));
  51:         shudhup = (flags & FAND) == 0;
  52: 
  53:         /*
  54: 		 * Must do << early so parent will know
  55: 		 * where input pointer should be
  56: 		 */
  57:         if (flags & FHERE)
  58:             close(0), heredoc(t->t_dlef);
  59: 
  60:         /*
  61: 		 * If not executing commands then
  62: 		 * all we must do is read forward in the input to
  63: 		 * account for << redirection if present.
  64: 		 */
  65:         if (noexec) {
  66:             if (flags & FHERE)
  67:                 close(0);
  68:             return;
  69:         }
  70: 
  71:         set("status", "0");
  72:         pid = 0;
  73: 
  74:         /*
  75: 		 * Built-in functions
  76: 		 */
  77:         if (t->t_dtyp == TCOM && isbfunc(t->t_dcom[0])) {
  78:             /*
  79: 			 * If output is piped, or running & and we would
  80: 			 * eventually fork for non-builtin commands,
  81: 			 * then do it now, so we won't block.
  82: 			 */
  83:             if ((flags & (FPOU|FAND)) && (flags & FPAR) == 0)
  84:                 pid = dofork(shudint, shudhup), forked++;
  85: 
  86:             /*
  87: 			 * If the builtin is actually executed (some, e.g.
  88: 			 * time and nice may refuse to execute here)
  89: 			 * then either exit (if we forked) or close i/o
  90: 			 * and continue execution (if we didn't).
  91: 			 */
  92:             if (pid == 0) {
  93:                 doio(t, pipein, pipeout);
  94:                 if (flags & FPOU) {
  95:                     close(pipeout[0]), close(pipeout[1]);
  96:                     pipeout[0] = pipeout[1] = -1;
  97:                 }
  98:                 if (setintr && forked) {
  99:                     if (shudint)
 100:                         signal(SIGINT, SIG_DFL), signal(SIGQUIT, SIG_DFL);
 101:                     signal(SIGTERM, parterm);
 102:                     if (flags & FINT)
 103:                         setintr = 0;
 104:                 }
 105:                 if (func(t, pipein, pipeout)) {
 106:                     if (forked)
 107:                         exitstat();
 108:                     if (didfds && !(t->t_dflg & FREDO))
 109:                         donefds();
 110:                     return;
 111:                 }
 112:             }
 113:         }
 114: 
 115:         /*
 116: 		 * Now, we must make a new process since either the
 117: 		 * command is non-builtin, a parenthesized list,
 118: 		 * or builtin such as time or nice which really
 119: 		 * requires a child.
 120: 		 */
 121:         if (!forked && (flags & FPAR) == 0)
 122: #ifdef VFORK
 123:             if (t->t_dtyp == TPAR || (flags&FREDO) ||
 124:                 eq(t->t_dcom[0], "nice") || eq(t->t_dcom[0], "nohup"))
 125: #endif
 126:                 pid = dofork(shudint, shudhup);
 127: #ifdef VFORK
 128:             else {
 129:                 savint = signal(SIGINT, SIG_IGN);
 130:                 ochild = child; osetintr = setintr;
 131:                 ohaderr = haderr; otimflg = timflg;
 132:                 odidfds = didfds; odidcch = didcch;
 133:                 oSHIN = SHIN; oSHOUT = SHOUT;
 134:                 oSHDIAG = SHDIAG; oOLDSTD = OLDSTD;
 135:                 Vsav = Vdp = 0; Vav = 0;
 136:                 isvfork++;
 137:                 pid = vfork();
 138:                 if (pid < 0) {
 139:                     signal(SIGINT, savint);
 140:                     error("No more processes");
 141:                 }
 142:                 if (pid == 0) {
 143:                     child++;
 144:                     signal(SIGINT, shudint ? SIG_DFL : savint);
 145:                     if (!shudhup)
 146:                         signal(SIGHUP, SIG_IGN);
 147:                 } else {
 148:                     child = ochild; setintr = osetintr;
 149:                     haderr = ohaderr; timflg = otimflg;
 150:                     didfds = odidfds; didcch = odidcch;
 151:                     SHIN = oSHIN; SHOUT = oSHOUT;
 152:                     SHDIAG = oSHDIAG; OLDSTD = oOLDSTD;
 153:                     xfree(Vsav), Vsav = 0;
 154:                     xfree(Vdp), Vdp = 0;
 155:                     xfree(Vav), Vav = 0;
 156:                     signal(SIGINT, savint);
 157:                 }
 158:             }
 159: #endif
 160:         if (pid != 0) {
 161:             /*
 162: 			 * The parent path (or nobody does this if
 163: 			 * (flags & FPAR), i.e. date in (set;date))
 164: 			 */
 165:             if (didfds == 0 && (flags & FPIN))
 166:                 close(pipein[0]), close(pipein[1]);
 167:             if (didfds && !(t->t_dflg & FREDO))
 168:                 donefds();
 169:             if (flags & FPRS)
 170:                 printf("%d\n", pid), set("child", putn(pid));
 171:             /*
 172: 			 * Unless output is piped or command is &
 173: 			 * wait for it.
 174: 			 */
 175:             if (t->t_dtyp == TCOM)
 176:                 cadd(pid, t->t_dcom[0]);
 177:             else
 178:                 cadd(pid, "()");
 179:             if ((flags & (FPOU|FAND)) == 0)
 180:                 pwait(pid);
 181:             return;
 182:         }
 183: 
 184:         /*
 185: 		 * Insure that this (child) shell doesn't muck on
 186: 		 */
 187:         child++;
 188: 
 189:         /*
 190: 		 * If havent yet, finally set up the file descriptors.
 191: 		 */
 192:         doio(t, pipein, pipeout);
 193:         if (flags & FPOU)
 194:             close(pipeout[0]), close(pipeout[1]);
 195: 
 196:         /*
 197: 		 * If mucking with interrupts fix interrupt, quit,
 198: 		 * and terminate handling ... in any case set setintr
 199: 		 * to 0 if we are not interruptible so that no further
 200: 		 * interrupt mucking occurs.
 201: 		 */
 202:         if (setintr) {
 203:             if (shudint) {
 204:                 signal(SIGQUIT, SIG_DFL);
 205: #ifdef VFORK
 206:                 if (isvfork)
 207:                     signal(SIGINT, vffree);
 208:                 else
 209: #endif
 210:                     signal(SIGINT, SIG_DFL);
 211:             }
 212:             signal(SIGTERM, parterm);
 213:             if (flags & FINT)
 214:                 setintr = 0;
 215:         }
 216: 
 217:         /*
 218: 		 * For () commands must put new 0,1,2 in FSH* and recurse
 219: 		 */
 220:         if (t->t_dtyp == TPAR) {
 221:             t1 = t->t_dspr;
 222:             t1->t_dflg |= flags & FINT;
 223:             OLDSTD = dcopy(0, FOLDSTD);
 224:             SHOUT = dcopy(1, FSHOUT);
 225:             SHDIAG = dcopy(2, FSHDIAG);
 226:             close(SHIN), SHIN = -1;
 227:             didcch = 0, didfds = 0;
 228:             execute(t1);
 229:             exitstat();
 230:         }
 231:         if (eq(t->t_dcom[0], "nice")) {
 232: /* sigh...
 233: 			nice(20);
 234: 			nice(-10);
 235: */
 236:             cp = t->t_dcom[1];
 237:             if (any(cp[0], "+-"))
 238:                 nice(getn(cp)), lshift(t->t_dcom, 2);
 239:             else
 240:                 nice(4), lshift(t->t_dcom, 1);
 241:             t->t_dflg = FPAR | FREDO;
 242:             execute(t);
 243:             exitstat();
 244:         }
 245:         if (eq(t->t_dcom[0], "nohup")) {
 246:             if (setintr == 0)
 247:                 signal(SIGHUP, SIG_IGN);
 248:             signal(SIGTERM, SIG_IGN);
 249:             lshift(t->t_dcom, 1);
 250:             t->t_dflg = FPAR | FREDO;
 251:             execute(t);
 252:             exitstat();
 253:         }
 254:         doexec(t);
 255:         /* no return */
 256: 
 257:     case TFIL:
 258:         flags = t->t_dflg;
 259:         t1 = t->t_dcar;
 260:         t1->t_dflg |= FPOU | (flags & (FPIN|FINT|FPRS|FDIAG));
 261:         execute(t1, pipein, pv);
 262:         t1 = t->t_dcdr;
 263:         t1->t_dflg |= FPIN | (flags & (FPOU|FINT|FAND|FPRS|FPAR));
 264:         execute(t1, pv, pipeout);
 265:         return;
 266: 
 267:     case TLST:
 268:         flags = t->t_dflg & FINT;
 269:         if (t1 = t->t_dcar)
 270:             t1->t_dflg |= flags, execute(t1);
 271:         if (t1 = t->t_dcdr)
 272:             t1->t_dflg |= t->t_dflg & (FINT|FPAR), execute(t1);
 273:         return;
 274: 
 275:     case TOR:
 276:     case TAND:
 277:         flags = t->t_dflg & FINT;
 278:         if (t1 = t->t_dcar) {
 279:             t1->t_dflg |= flags, execute(t1);
 280:             if ((getn(value("status")) == 0) != (t->t_dtyp == TAND))
 281:                 return;
 282:         }
 283:         if (t1 = t->t_dcdr)
 284:             t1->t_dflg |= t->t_dflg & (FINT|FPAR), execute(t1);
 285:         return;
 286:     }
 287: }
 288: 
 289: #ifdef VFORK
 290: vffree()
 291: {
 292:     register char **v;
 293: 
 294:     if (v = gargv)
 295:         gargv = 0, xfree(gargv);
 296:     if (v = pargv)
 297:         pargv = 0, xfree(pargv);
 298:     _exit(1);
 299: }
 300: #endif
 301: 
 302: doio(t, pipein, pipeout)
 303:     register struct command *t;
 304:     int *pipein, *pipeout;
 305: {
 306:     register char *cp;
 307:     register int flags = t->t_dflg;
 308:     char *dp;
 309: 
 310:     if (didfds || (flags & FREDO))
 311:         return;
 312:     if (flags & FHERE)
 313:         goto skipin;
 314:     close(0);
 315:     if (cp = t->t_dlef) {
 316:         cp = globone(dp = Dfix1(cp));
 317:         xfree(dp);
 318:         xfree(cp);
 319:         if (open(cp, 0) < 0)
 320:             Perror(cp);
 321:     } else if (flags & FPIN)
 322:         dup(pipein[0]), close(pipein[0]), close(pipein[1]);
 323:     else if (flags & FINT)
 324:         close(0), open("/dev/null", 0);
 325:     else
 326:         dup(OLDSTD);
 327: 
 328: skipin:
 329:     close(1);
 330:     if (cp = t->t_drit) {
 331:         cp = globone(dp = Dfix1(cp));
 332:         xfree(dp);
 333:         xfree(cp);
 334:         if ((flags & FCAT) && open(cp, 1) >= 0)
 335:             lseek(1, 0l, 2);
 336:         else {
 337:             if (!(flags & FANY) && adrof("noclobber")) {
 338:                 if (flags & FCAT)
 339:                     Perror(cp);
 340:                 chkclob(cp);
 341:             }
 342: #ifdef V6
 343:             if (creat(cp, 0644) < 0)
 344:                 Perror(cp);
 345: #else
 346:             if (creat(cp, 0666) < 0)
 347:                 Perror(cp);
 348: #endif
 349:         }
 350:     } else
 351:         dup((flags & FPOU) ? pipeout[1] : SHOUT);
 352: 
 353:     close(2);
 354:     dup((flags & FDIAG) ? 1 : SHDIAG);
 355:     didfds = 1;
 356: }
 357: 
 358: dofork(shudint, shudhup)
 359:     bool shudint, shudhup;
 360: {
 361:     register int pid, (*savint)();
 362: 
 363:     savint = signal(SIGINT, SIG_IGN);
 364:     pid = fork();
 365:     if (pid < 0) {
 366:         signal(SIGINT, savint);
 367:         error("No more processes");
 368:     }
 369:     if (pid == 0) {
 370:         child++;
 371:         signal(SIGINT, shudint ? SIG_DFL : savint);
 372:         if (!shudhup)
 373:             signal(SIGHUP, SIG_IGN);
 374:     } else
 375:         signal(SIGINT, savint);
 376:     return (pid);
 377: }
 378: 
 379: mypipe(pv)
 380:     register int *pv;
 381: {
 382: 
 383:     if (pipe(pv) < 0)
 384:         goto oops;
 385:     pv[0] = dmove(pv[0], -1);
 386:     pv[1] = dmove(pv[1], -1);
 387:     if (pv[0] >= 0 && pv[1] >= 0)
 388:         return;
 389: oops:
 390:     error("Can't make pipe");
 391: }
 392: 
 393: chkclob(cp)
 394:     register char *cp;
 395: {
 396:     struct stat stb;
 397: 
 398:     if (stat(cp, &stb) < 0)
 399:         return;
 400:     if ((stb.st_mode & S_IFMT) == S_IFCHR)
 401:         return;
 402:     error("%s: File exists", cp);
 403: }

Defined functions

chkclob defined in line 393; used 1 times
dofork defined in line 358; used 2 times
doio defined in line 302; used 2 times
mypipe defined in line 379; used 2 times
vffree defined in line 290; used 2 times
Last modified: 1981-10-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1127
Valid CSS Valid XHTML 1.0 Strict