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