# 2.11BSD#431 - /usr/src/bin/csh/sh.sem.c

##### Functions

    chkclob           X
    doio              X
    execute           X
    mypipe            X
    vffree            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley Software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)sh.sem.c	5.4.1 (2.11BSD GTE) 12/9/94";
       9: #endif
      10:
      11: #include "sh.h"
      12: #include "sh.proc.h"
      13: #include <fcntl.h>
      14: #include <sys/ioctl.h>
      15:
      16: /*
      17:  * C shell
      18:  */
      19:
      20: /*VARARGS 1*/
      21: execute(t, wanttty, pipein, pipeout)
      22:     register struct command *t;
      23:     int wanttty, *pipein, *pipeout;
      24: {
      25:     bool forked = 0;
      26:     struct biltins *bifunc;
      27:     int pid = 0;
      28:     int pv[2];
      29:
      30:     if (t == 0)
      31:         return;
      32:     if ((t->t_dflg & FAND) && wanttty > 0)
      33:         wanttty = 0;
      34:     switch (t->t_dtyp) {
      35:
      36:     case TCOM:
      37:         if ((t->t_dcom[0][0] & (QUOTE|TRIM)) == QUOTE)
      38:             (void) strcpy(t->t_dcom[0], t->t_dcom[0] + 1);
      39:         if ((t->t_dflg & FREDO) == 0)
      40:             Dfix(t);        /* $ " ' \ */
      41:         if (t->t_dcom[0] == 0)
      42:             return;
      43:         /* fall into... */
      44:
      45:     case TPAR:
      46:         if (t->t_dflg & FPOU)
      47:             mypipe(pipeout);
      48:         /*
      49: 		 * Must do << early so parent will know
      50: 		 * where input pointer should be.
      51: 		 * If noexec then this is all we do.
      52: 		 */
      53:         if (t->t_dflg & FHERE) {
      54:             (void) close(0);
      55:             heredoc(t->t_dlef);
      56:             if (noexec)
      57:                 (void) close(0);
      58:         }
      59:         if (noexec)
      60:             break;
      61:
      62:         set("status", "0");
      63:
      64:         /*
      65: 		 * This mess is the necessary kludge to handle the prefix
      66: 		 * builtins: nice, nohup, time.  These commands can also
      67: 		 * be used by themselves, and this is not handled here.
      68: 		 * This will also work when loops are parsed.
      69: 		 */
      70:         while (t->t_dtyp == TCOM)
      71:             if (eq(t->t_dcom[0], "nice"))
      72:                 if (t->t_dcom[1])
      73:                     if (any(t->t_dcom[1][0], "+-"))
      74:                         if (t->t_dcom[2]) {
      75:                             setname("nice");
      76:                             t->t_nice = getn(t->t_dcom[1]);
      77:                             lshift(t->t_dcom, 2);
      78:                             t->t_dflg |= FNICE;
      79:                         } else
      80:                             break;
      81:                     else {
      82:                         t->t_nice = 4;
      83:                         lshift(t->t_dcom, 1);
      84:                         t->t_dflg |= FNICE;
      85:                     }
      86:                 else
      87:                     break;
      88:             else if (eq(t->t_dcom[0], "nohup"))
      89:                 if (t->t_dcom[1]) {
      90:                     t->t_dflg |= FNOHUP;
      91:                     lshift(t->t_dcom, 1);
      92:                 } else
      93:                     break;
      94:             else if (eq(t->t_dcom[0], "time"))
      95:                 if (t->t_dcom[1]) {
      96:                     t->t_dflg |= FTIME;
      97:                     lshift(t->t_dcom, 1);
      98:                 } else
      99:                     break;
     100:             else
     101:                 break;
     102:         /*
     103: 		 * Check if we have a builtin function and remember which one.
     104: 		 */
     105:         bifunc = t->t_dtyp == TCOM ? isbfunc(t) : (struct biltins *) 0;
     106:
     107:         /*
     108: 		 * We fork only if we are timed, or are not the end of
     109: 		 * a parenthesized list and not a simple builtin function.
     110: 		 * Simple meaning one that is not pipedout, niced, nohupped,
     111: 		 * or &'d.
     112: 		 * It would be nice(?) to not fork in some of these cases.
     113: 		 */
     114:         if (((t->t_dflg & FTIME) || (t->t_dflg & FPAR) == 0 &&
     115:              (!bifunc || t->t_dflg & (FPOU|FAND|FNICE|FNOHUP))))
     116: #ifdef VFORK
     117:             if (t->t_dtyp == TPAR || t->t_dflg&(FREDO|FAND) || bifunc)
     118: #endif
     119:             { forked++; pid = pfork(t, wanttty); }
     120: #ifdef VFORK
     121:             else {
     122:             int vffree();
     123:             int ochild, osetintr, ohaderr, odidfds;
     124:             int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp;
     125:             long omask;
     126:
     127:             /*
     128: 			 * Prepare for the vfork by saving everything
     129: 			 * that the child corrupts before it exec's.
     130: 			 * Note that in some signal implementations
     131: 			 * which keep the signal info in user space
     132: 			 * (e.g. Sun's) it will also be necessary to
     133:  			 * save and restore the current sigvec's for
     134: 			 * the signals the child touches before it
     135: 			 * exec's.
     136: 			 */
     137:             omask = sigblock(sigmask(SIGCHLD));
     138:             ochild = child; osetintr = setintr;
     139:             ohaderr = haderr; odidfds = didfds;
     140:             oSHIN = SHIN; oSHOUT = SHOUT;
     141:             oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp;
     142:             Vsav = Vdp = 0; Vav = 0;
     143:             pid = vfork();
     144:             if (pid < 0) {
     145:                 (void) sigsetmask(omask);
     146:                 error("No more processes");
     147:             }
     148:             forked++;
     149:             if (pid) {  /* parent */
     150:                 register char **v;
     151:
     152:                 child = ochild; setintr = osetintr;
     153:                 haderr = ohaderr; didfds = odidfds;
     154:                 SHIN = oSHIN;
     155:                 SHOUT = oSHOUT; SHDIAG = oSHDIAG;
     156:                 OLDSTD = oOLDSTD; tpgrp = otpgrp;
     157:                 xfree(Vsav); Vsav = 0;
     158:                 xfree(Vdp); Vdp = 0;
     159:                 xfree((char *)Vav); Vav = 0;
     160:                 if (v = gargv)
     161:                     gargv = 0, blkfree(v);
     162:                 if (v = pargv)
     163:                     pargv = 0, blkfree(v);
     164:                 /* this is from pfork() */
     165:                 palloc(pid, t);
     166:                 (void) sigsetmask(omask);
     167:             } else {    /* child */
     168:                 /* this is from pfork() */
     169:                 int pgrp;
     170:                 bool ignint = 0;
     171:
     172:                 if (setintr)
     173:                     ignint =
     174:                         (tpgrp == -1 && (t->t_dflg&FINT))
     175:                         || gointr && eq(gointr, "-");
     176:                 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
     177:                 child++;
     178:                 if (setintr) {
     179:                     setintr = 0;
     180: #ifdef notdef
     181:                     (void) signal(SIGCHLD, SIG_DFL);
     182: #endif
     183:                     (void) signal(SIGINT, ignint ?
     184:                         SIG_IGN : vffree);
     185:                     (void) signal(SIGQUIT, ignint ?
     186:                         SIG_IGN : SIG_DFL);
     187:                     if (wanttty >= 0) {
     188:                         (void) signal(SIGTSTP, SIG_DFL);
     189:                         (void) signal(SIGTTIN, SIG_DFL);
     190:                         (void) signal(SIGTTOU, SIG_DFL);
     191:                     }
     192:                     (void) signal(SIGTERM, parterm);
     193:                 } else if (tpgrp == -1 && (t->t_dflg&FINT)) {
     194:                     (void) signal(SIGINT, SIG_IGN);
     195:                     (void) signal(SIGQUIT, SIG_IGN);
     196:                 }
     197:                 if (wanttty > 0)
     198:                     (void) ioctl(FSHTTY, TIOCSPGRP,
     199:                         (char *)&pgrp);
     200:                 if (wanttty >= 0 && tpgrp >= 0)
     201:                     (void) setpgrp(0, pgrp);
     202:                 if (tpgrp > 0)
     203:                     tpgrp = 0;
     204:                 if (t->t_dflg & FNOHUP)
     205:                     (void) signal(SIGHUP, SIG_IGN);
     206:                 if (t->t_dflg & FNICE)
     207:                     (void) setpriority(PRIO_PROCESS,
     208:                         0, t->t_nice);
     209:             }
     210:
     211:             }
     212: #endif
     213:         if (pid != 0) {
     214:             /*
     215: 			 * It would be better if we could wait for the
     216: 			 * whole job when we knew the last process
     217: 			 * had been started.  Pwait, in fact, does
     218: 			 * wait for the whole job anyway, but this test
     219: 			 * doesn't really express our intentions.
     220: 			 */
     221:             if (didfds==0 && t->t_dflg&FPIN) {
     222:                 (void) close(pipein[0]);
     223:                 (void) close(pipein[1]);
     224:             }
     225:             if ((t->t_dflg & (FPOU|FAND)) == 0)
     226:                 pwait();
     227:             break;
     228:         }
     229:         doio(t, pipein, pipeout);
     230:         if (t->t_dflg & FPOU) {
     231:             (void) close(pipeout[0]);
     232:             (void) close(pipeout[1]);
     233:         }
     234:
     235:         /*
     236: 		 * Perform a builtin function.
     237: 		 * If we are not forked, arrange for possible stopping
     238: 		 */
     239:         if (bifunc) {
     240:             func(t, bifunc);
     241:             if (forked)
     242:                 exitstat();
     243:             break;
     244:         }
     245:         if (t->t_dtyp != TPAR) {
     246:             doexec(t);
     247:             /*NOTREACHED*/
     248:         }
     249:         /*
     250: 		 * For () commands must put new 0,1,2 in FSH* and recurse
     251: 		 */
     252:         OLDSTD = dcopy(0, FOLDSTD);
     253:         SHOUT = dcopy(1, FSHOUT);
     254:         SHDIAG = dcopy(2, FSHDIAG);
     255:         (void) close(SHIN);
     256:         SHIN = -1;
     257:         didfds = 0;
     258:         wanttty = -1;
     259:         t->t_dspr->t_dflg |= t->t_dflg & FINT;
     260:         execute(t->t_dspr, wanttty);
     261:         exitstat();
     262:
     263:     case TFIL:
     264:         t->t_dcar->t_dflg |= FPOU |
     265:             (t->t_dflg & (FPIN|FAND|FDIAG|FINT));
     266:         execute(t->t_dcar, wanttty, pipein, pv);
     267:         t->t_dcdr->t_dflg |= FPIN |
     268:             (t->t_dflg & (FPOU|FAND|FPAR|FINT));
     269:         if (wanttty > 0)
     270:             wanttty = 0;        /* got tty already */
     271:         execute(t->t_dcdr, wanttty, pv, pipeout);
     272:         break;
     273:
     274:     case TLST:
     275:         if (t->t_dcar) {
     276:             t->t_dcar->t_dflg |= t->t_dflg & FINT;
     277:             execute(t->t_dcar, wanttty);
     278:             /*
     279: 			 * In strange case of A&B make a new job after A
     280: 			 */
     281:             if (t->t_dcar->t_dflg&FAND && t->t_dcdr &&
     282:                 (t->t_dcdr->t_dflg&FAND) == 0)
     283:                 pendjob();
     284:         }
     285:         if (t->t_dcdr) {
     286:             t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
     287:             execute(t->t_dcdr, wanttty);
     288:         }
     289:         break;
     290:
     291:     case TOR:
     292:     case TAND:
     293:         if (t->t_dcar) {
     294:             t->t_dcar->t_dflg |= t->t_dflg & FINT;
     295:             execute(t->t_dcar, wanttty);
     296:             if ((getn(value("status")) == 0) != (t->t_dtyp == TAND))
     297:                 return;
     298:         }
     299:         if (t->t_dcdr) {
     300:             t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
     301:             execute(t->t_dcdr, wanttty);
     302:         }
     303:         break;
     304:     }
     305:     /*
     306: 	 * Fall through for all breaks from switch
     307: 	 *
     308: 	 * If there will be no more executions of this
     309: 	 * command, flush all file descriptors.
     310: 	 * Places that turn on the FREDO bit are responsible
     311: 	 * for doing donefds after the last re-execution
     312: 	 */
     313:     if (didfds && !(t->t_dflg & FREDO))
     314:         donefds();
     315: }
     316:
     317: #ifdef VFORK
     318: vffree()
     319: {
     320:     register char **v;
     321:
     322:     if (v = gargv)
     323:         gargv = 0, blkfree(v);
     324:     if (v = pargv)
     325:         pargv = 0, blkfree(v);
     326:     _exit(1);
     327: }
     328: #endif
     329:
     330: /*
     331:  * Perform io redirection.
     332:  * We may or maynot be forked here.
     333:  */
     334: doio(t, pipein, pipeout)
     335:     register struct command *t;
     336:     int *pipein, *pipeout;
     337: {
     338:     register char *cp;
     339:     register int flags = t->t_dflg;
     340:
     341:     if (didfds || (flags & FREDO))
     342:         return;
     343:     if ((flags & FHERE) == 0) { /* FHERE already done */
     344:         (void) close(0);
     345:         if (cp = t->t_dlef) {
     346:             cp = globone(Dfix1(cp));
     347:             xfree(cp);
     348:             if (open(cp, 0) < 0)
     349:                 Perror(cp);
     350:         } else if (flags & FPIN) {
     351:             (void) dup(pipein[0]);
     352:             (void) close(pipein[0]);
     353:             (void) close(pipein[1]);
     354:         } else if ((flags & FINT) && tpgrp == -1) {
     355:             (void) close(0);
     356:             (void) open("/dev/null", 0);
     357:         } else
     358:             (void) dup(OLDSTD);
     359:     }
     360:     (void) close(1);
     361:     if (cp = t->t_drit) {
     362:         cp = globone(Dfix1(cp));
     363:         xfree(cp);
     364:         if ((flags & FCAT) && open(cp, O_WRONLY | O_APPEND) >= 0)
     365:             ;
     366:         else {
     367:             if (!(flags & FANY) && adrof("noclobber")) {
     368:                 if (flags & FCAT)
     369:                     Perror(cp);
     370:                 chkclob(cp);
     371:             }
     372:             if (creat(cp, 0666) < 0)
     373:                 Perror(cp);
     374:         }
     375:     } else if (flags & FPOU)
     376:         (void) dup(pipeout[1]);
     377:     else
     378:         (void) dup(SHOUT);
     379:
     380:     (void) close(2);
     381:     if (flags & FDIAG)
     382:         (void) dup(1);
     383:     else
     384:         (void) dup(SHDIAG);
     385:     didfds = 1;
     386: }
     387:
     388: mypipe(pv)
     389:     register int *pv;
     390: {
     391:
     392:     if (pipe(pv) < 0)
     393:         goto oops;
     394:     pv[0] = dmove(pv[0], -1);
     395:     pv[1] = dmove(pv[1], -1);
     396:     if (pv[0] >= 0 && pv[1] >= 0)
     397:         return;
     398: oops:
     399:     error("Can't make pipe");
     400: }
     401:
     402: chkclob(cp)
     403:     register char *cp;
     404: {
     405:     struct stat stb;
     406:
     407:     if (stat(cp, &stb) < 0)
     408:         return;
     409:     if ((stb.st_mode & S_IFMT) == S_IFCHR)
     410:         return;
     411:     error("%s: File exists", cp);
     412: }

#### Defined functions

chkclob defined in line 402; used 1 times

- in line 370

doio defined in line 334; used 1 times

- in line 229

execute defined in line 21; used 11 times

- in line 260, 266-271(2), 277, 287, 295, 301
- in /usr/src/bin/csh/sh.c line 796
- in /usr/src/bin/csh/sh.exp.c line 513
- in /usr/src/bin/csh/sh.func.c line 260
- in /usr/src/bin/csh/sh.glob.c line 671

mypipe defined in line 388; used 2 times

- in line 47
- in /usr/src/bin/csh/sh.glob.c line 647

vffree defined in line 318; used 2 times

- in line 122, 184

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1994-12-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1886 |