home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / sh / xec.c < prev   
Encoding:
C/C++ Source or Header  |  1979-01-12  |  8.2 KB  |  422 lines

  1. #
  2. /*
  3.  * UNIX shell
  4.  *
  5.  * S. R. Bourne
  6.  * Bell Telephone Laboratories
  7.  *
  8.  */
  9.  
  10. #include    "defs.h"
  11. #include    "sym.h"
  12.  
  13. LOCAL INT    parent;
  14.  
  15. SYSTAB        commands;
  16.  
  17.  
  18.  
  19. /* ========    command execution    ========*/
  20.  
  21.  
  22. execute(argt, execflg, pf1, pf2)
  23.     TREPTR        argt;
  24.     INT        *pf1, *pf2;
  25. {
  26.     /* `stakbot' is preserved by this routine */
  27.     REG TREPTR    t;
  28.     STKPTR        sav=savstak();
  29.  
  30.     sigchk();
  31.  
  32.     IF (t=argt) ANDF execbrk==0
  33.     THEN    REG INT        treeflgs;
  34.         INT        oldexit, type;
  35.         REG STRING    *com;
  36.  
  37.         treeflgs = t->tretyp; type = treeflgs&COMMSK;
  38.         oldexit=exitval; exitval=0;
  39.  
  40.         SWITCH type IN
  41.  
  42.         case TCOM:
  43.             BEGIN
  44.             STRING        a1;
  45.             INT        argn, internal;
  46.             ARGPTR        schain=gchain;
  47.             IOPTR        io=t->treio;
  48.             gchain=0;
  49.             argn = getarg(t);
  50.             com=scan(argn);
  51.             a1=com[1]; gchain=schain;
  52.  
  53.             IF (internal=syslook(com[0],commands)) ORF argn==0
  54.             THEN    setlist(t->comset, 0);
  55.             FI
  56.  
  57.             IF argn ANDF (flags&noexec)==0
  58.             THEN    /* print command if execpr */
  59.                 IF flags&execpr
  60.                 THEN    argn=0;    prs(execpmsg);
  61.                     WHILE com[argn]!=ENDARGS
  62.                     DO prs(com[argn++]); blank() OD
  63.                     newline();
  64.                 FI
  65.  
  66.                 SWITCH internal IN
  67.  
  68.                 case SYSDOT:
  69.                     IF a1
  70.                     THEN    REG INT        f;
  71.     
  72.                         IF (f=pathopen(getpath(a1), a1)) < 0
  73.                         THEN failed(a1,notfound);
  74.                         ELSE execexp(0,f);
  75.                         FI
  76.                     FI
  77.                     break;
  78.     
  79.                 case SYSTIMES:
  80.                     {
  81.                     L_INT    t[4]; times(t);
  82.                     prt(t[2]); blank(); prt(t[3]); newline();
  83.                     }
  84.                     break;
  85.     
  86.                 case SYSEXIT:
  87.                     exitsh(a1?stoi(a1):oldexit);
  88.     
  89.                 case SYSNULL:
  90.                     io=0;
  91.                     break;
  92.     
  93.                 case SYSCONT:
  94.                     execbrk = -loopcnt; break;
  95.     
  96.                 case SYSBREAK:
  97.                     IF (execbrk=loopcnt) ANDF a1
  98.                     THEN breakcnt=stoi(a1);
  99.                     FI
  100.                     break;
  101.     
  102.                 case SYSTRAP:
  103.                     IF a1
  104.                     THEN    BOOL    clear;
  105.                         IF (clear=digit(*a1))==0
  106.                         THEN    ++com;
  107.                         FI
  108.                         WHILE *++com
  109.                         DO INT    i;
  110.                            IF (i=stoi(*com))>=MAXTRAP ORF i<MINTRAP
  111.                            THEN    failed(*com,badtrap);
  112.                            ELIF clear
  113.                            THEN    clrsig(i);
  114.                            ELSE    replace(&trapcom[i],a1);
  115.                             IF *a1
  116.                             THEN    getsig(i);
  117.                             ELSE    ignsig(i);
  118.                             FI
  119.                            FI
  120.                         OD
  121.                     ELSE    /* print out current traps */
  122.                         INT        i;
  123.     
  124.                         FOR i=0; i<MAXTRAP; i++
  125.                         DO IF trapcom[i]
  126.                            THEN    prn(i); prs(colon); prs(trapcom[i]); newline();
  127.                            FI
  128.                         OD
  129.                     FI
  130.                     break;
  131.     
  132.                 case SYSEXEC:
  133.                     com++;
  134.                     initio(io); ioset=0; io=0;
  135.                     IF a1==0 THEN break FI
  136.     
  137.                 case SYSLOGIN:
  138.                     flags |= forked;
  139.                     oldsigs(); execa(com); done();
  140.     
  141.                 case SYSCD:
  142.                     IF flags&rshflg
  143.                     THEN    failed(com[0],restricted);
  144.                     ELIF (a1==0 ANDF (a1=homenod.namval)==0) ORF chdir(a1)<0
  145.                     THEN    failed(a1,baddir);
  146.                     FI
  147.                     break;
  148.     
  149.                 case SYSSHFT:
  150.                     IF dolc<1
  151.                     THEN    error(badshift);
  152.                     ELSE    dolv++; dolc--;
  153.                     FI
  154.                     assnum(&dolladr, dolc);
  155.                     break;
  156.     
  157.                 case SYSWAIT:
  158.                     await(-1);
  159.                     break;
  160.     
  161.                 case SYSREAD:
  162.                     exitval=readvar(&com[1]);
  163.                     break;
  164.  
  165. /*
  166.                 case SYSTST:
  167.                     exitval=testcmd(com);
  168.                     break;
  169. */
  170.  
  171.                 case SYSSET:
  172.                     IF a1
  173.                     THEN    INT    argc;
  174.                         argc = options(argn,com);
  175.                         IF argc>1
  176.                         THEN    setargs(com+argn-argc);
  177.                         FI
  178.                     ELIF t->comset==0
  179.                     THEN    /*scan name chain and print*/
  180.                         namscan(printnam);
  181.                     FI
  182.                     break;
  183.     
  184.                 case SYSRDONLY:
  185.                     exitval=N_RDONLY;
  186.                 case SYSXPORT:
  187.                     IF exitval==0 THEN exitval=N_EXPORT; FI
  188.     
  189.                     IF a1
  190.                     THEN    WHILE *++com
  191.                         DO attrib(lookup(*com), exitval) OD
  192.                     ELSE    namscan(printflg);
  193.                     FI
  194.                     exitval=0;
  195.                     break;
  196.     
  197.                 case SYSEVAL:
  198.                     IF a1
  199.                     THEN    execexp(a1,&com[2]);
  200.                     FI
  201.                     break;
  202.  
  203.                                 case SYSUMASK:
  204.                                         if (a1) {
  205.                                                 int c, i
  206.                                                 i = 0;
  207.                                                 while ((c = *a1++) >= '0' &&
  208.                                                         c <= '7')
  209.                                                         i = (i << 3) + c - '0';
  210.                                                 umask(i);
  211.                                         } else {
  212.                                                 int i, j;
  213.                                                 umask(i = umask(0));
  214.                                                 prc('0');
  215.                                                 for (j = 6; j >= 0; j -= 3)
  216.                                                         prc(((i>>j)&07) + '0');
  217.                                                 newline();
  218.                                         }
  219.                                         break;
  220.     
  221.                 default:
  222.                     internal=builtin(argn,com);
  223.     
  224.                 ENDSW
  225.  
  226.                 IF internal
  227.                 THEN    IF io THEN error(illegal) FI
  228.                     chktrap();
  229.                     break;
  230.                 FI
  231.             ELIF t->treio==0
  232.             THEN    break;
  233.             FI
  234.             END
  235.     
  236.         case TFORK:
  237.             IF execflg ANDF (treeflgs&(FAMP|FPOU))==0
  238.             THEN    parent=0;
  239.             ELSE    WHILE (parent=fork()) == -1
  240.                 DO sigchk(); alarm(10); pause() OD
  241.             FI
  242.  
  243.             IF parent
  244.             THEN    /* This is the parent branch of fork;    */
  245.                 /* it may or may not wait for the child. */
  246.                 IF treeflgs&FPRS ANDF flags&ttyflg
  247.                 THEN    prn(parent); newline();
  248.                 FI
  249.                 IF treeflgs&FPCL THEN closepipe(pf1) FI
  250.                 IF (treeflgs&(FAMP|FPOU))==0
  251.                 THEN    await(parent);
  252.                 ELIF (treeflgs&FAMP)==0
  253.                 THEN    post(parent);
  254.                 ELSE    assnum(&pcsadr, parent);
  255.                 FI
  256.  
  257.                 chktrap();
  258.                 break;
  259.  
  260.  
  261.             ELSE    /* this is the forked branch (child) of execute */
  262.                 flags |= forked; iotemp=0;
  263.                 postclr();
  264.                 settmp();
  265.  
  266.                 /* Turn off INTR and QUIT if `FINT'  */
  267.                 /* Reset ramaining signals to parent */
  268.                 /* except for those `lost' by trap   */
  269.                 oldsigs();
  270.                 IF treeflgs&FINT
  271.                 THEN    signal(INTR,1); signal(QUIT,1);
  272.                 FI
  273.  
  274.                 /* pipe in or out */
  275.                 IF treeflgs&FPIN
  276.                 THEN    rename(pf1[INPIPE],0);
  277.                     close(pf1[OTPIPE]);
  278.                 FI
  279.                 IF treeflgs&FPOU
  280.                 THEN    rename(pf2[OTPIPE],1);
  281.                     close(pf2[INPIPE]);
  282.                 FI
  283.  
  284.                 /* default std input for & */
  285.                 IF treeflgs&FINT ANDF ioset==0
  286.                 THEN    rename(chkopen(devnull),0);
  287.                 FI
  288.  
  289.                 /* io redirection */
  290.                 initio(t->treio);
  291.                 IF type!=TCOM
  292.                 THEN    execute(t->forktre,1);
  293.                 ELIF com[0]!=ENDARGS
  294.                 THEN    setlist(t->comset,N_EXPORT);
  295.                     execa(com);
  296.                 FI
  297.                 done();
  298.             FI
  299.  
  300.         case TPAR:
  301.             rename(dup(2),output);
  302.             execute(t->partre,execflg);
  303.             done();
  304.  
  305.         case TFIL:
  306.             BEGIN
  307.                INT pv[2]; chkpipe(pv);
  308.                IF execute(t->lstlef, 0, pf1, pv)==0
  309.                THEN    execute(t->lstrit, execflg, pv, pf2);
  310.                ELSE    closepipe(pv);
  311.                FI
  312.             END
  313.             break;
  314.  
  315.         case TLST:
  316.             execute(t->lstlef,0);
  317.             execute(t->lstrit,execflg);
  318.             break;
  319.  
  320.         case TAND:
  321.             IF execute(t->lstlef,0)==0
  322.             THEN    execute(t->lstrit,execflg);
  323.             FI
  324.             break;
  325.  
  326.         case TORF:
  327.             IF execute(t->lstlef,0)!=0
  328.             THEN    execute(t->lstrit,execflg);
  329.             FI
  330.             break;
  331.  
  332.         case TFOR:
  333.             BEGIN
  334.                NAMPTR    n = lookup(t->fornam);
  335.                STRING    *args;
  336.                DOLPTR    argsav=0;
  337.  
  338.                IF t->forlst==0
  339.                THEN    args=dolv+1;
  340.                    argsav=useargs();
  341.                ELSE       ARGPTR    schain=gchain;
  342.                    gchain=0;
  343.                    trim((args=scan(getarg(t->forlst)))[0]);
  344.                    gchain=schain;
  345.                FI
  346.                loopcnt++;
  347.                WHILE *args!=ENDARGS ANDF execbrk==0
  348.                DO    assign(n,*args++);
  349.                 execute(t->fortre,0);
  350.                 IF execbrk<0 THEN execbrk=0 FI
  351.                OD
  352.                IF breakcnt THEN breakcnt-- FI
  353.                execbrk=breakcnt; loopcnt--;
  354.                argfor=freeargs(argsav);
  355.             END
  356.             break;
  357.  
  358.         case TWH:
  359.         case TUN:
  360.             BEGIN
  361.                INT        i=0;
  362.  
  363.                loopcnt++;
  364.                WHILE execbrk==0 ANDF (execute(t->whtre,0)==0)==(type==TWH)
  365.                DO i=execute(t->dotre,0);
  366.                   IF execbrk<0 THEN execbrk=0 FI
  367.                OD
  368.                IF breakcnt THEN breakcnt-- FI
  369.                execbrk=breakcnt; loopcnt--; exitval=i;
  370.             END
  371.             break;
  372.  
  373.         case TIF:
  374.             IF execute(t->iftre,0)==0
  375.             THEN    execute(t->thtre,execflg);
  376.             ELSE    execute(t->eltre,execflg);
  377.             FI
  378.             break;
  379.  
  380.         case TSW:
  381.             BEGIN
  382.                REG STRING    r = mactrim(t->swarg);
  383.                t=t->swlst;
  384.                WHILE t
  385.                DO    ARGPTR        rex=t->regptr;
  386.                 WHILE rex
  387.                 DO    REG STRING    s;
  388.                     IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
  389.                     THEN    execute(t->regcom,0);
  390.                         t=0; break;
  391.                     ELSE    rex=rex->argnxt;
  392.                     FI
  393.                 OD
  394.                 IF t THEN t=t->regnxt FI
  395.                OD
  396.             END
  397.             break;
  398.         ENDSW
  399.         exitset();
  400.     FI
  401.  
  402.     sigchk();
  403.     tdystak(sav);
  404.     return(exitval);
  405. }
  406.  
  407.  
  408. execexp(s,f)
  409.     STRING        s;
  410.     UFD        f;
  411. {
  412.     FILEBLK        fb;
  413.     push(&fb);
  414.     IF s
  415.     THEN    estabf(s); fb.feval=f;
  416.     ELIF f>=0
  417.     THEN    initf(f);
  418.     FI
  419.     execute(cmd(NL, NLFLG|MTFLG),0);
  420.     pop();
  421. }
  422.