|
|
1.1 ! root 1: /* ! 2: * sh/exec1.c ! 3: * The Bourne shell. ! 4: * Shell part of execution. ! 5: */ ! 6: ! 7: #include "sh.h" ! 8: ! 9: char *lastcmd = ""; ! 10: ! 11: char *skipredir(); ! 12: ! 13: /* ! 14: * Execute the given node, wait for completion, return status. ! 15: */ ! 16: command(np) ! 17: register NODE *np; ! 18: { ! 19: register int f; /* Pid of command */ ! 20: int mynllflag; /* Saved fork not forced flag */ ! 21: CON con; /* Control link for break/continue */ ! 22: char *innp, **inlp; /* for NFOR */ ! 23: NODE *cnode; /* for NCASE */ ! 24: char *cname; /* for NCASE */ ! 25: ! 26: mynllflag = nllflag; ! 27: innp = inlp = NULL; ! 28: cnode = NULL; ! 29: f = 0; ! 30: ! 31: con.c_next = sesp->s_con; ! 32: con.c_node = np; ! 33: con.c_bpp = savebuf(); ! 34: sesp->s_con = &con; ! 35: ! 36: switch (setjmp(con.c_envl)) { ! 37: case 0: /* initial setjmp */ ! 38: break; ! 39: case 1: /* continue */ ! 40: np = con.c_node; ! 41: break; ! 42: case 2: /* break */ ! 43: goto break2; ! 44: default: ! 45: panic(1); ! 46: NOTREACHED; ! 47: } ! 48: ! 49: for ( ; np != NULL; np=np->n_next) { ! 50: recover(ICMD); ! 51: f = 0; ! 52: nllflag = mynllflag; ! 53: ! 54: switch (np->n_type) { ! 55: case NCOMS: ! 56: f = comscom(np->n_auxp); ! 57: break; ! 58: case NFOR: ! 59: if (innp == NULL) { ! 60: innp = np->n_strp; ! 61: nargc = 0; ! 62: nargv = makargl(); ! 63: for (np = np->n_next->n_auxp; np; np = np->n_next) ! 64: eval(np->n_strp, EARGS); ! 65: inlp = nargv; ! 66: np = con.c_node; ! 67: } ! 68: continue; ! 69: case NFOR2: ! 70: /* do_done_list->n_next == this node */ ! 71: if (*inlp == NULL || assnvar(innp, *inlp++) == NULL) ! 72: break; ! 73: continue; ! 74: case NWHILE: ! 75: /* do_done_list->n_next == this node */ ! 76: nllflag = 0; ! 77: if (command(np->n_auxp)) ! 78: break; ! 79: continue; ! 80: case NUNTIL: ! 81: /* do_done_list->n_next == this node */ ! 82: nllflag = 0; ! 83: if ( ! command(np->n_auxp)) ! 84: break; ! 85: continue; ! 86: case NBRAC: ! 87: command(np->n_auxp); ! 88: break; ! 89: case NPARN: ! 90: if (nllflag || (f=clone()) == 0) { ! 91: exit(command(np->n_auxp)); ! 92: NOTREACHED; ! 93: } ! 94: break; ! 95: case NIF: ! 96: nllflag = 0; ! 97: if (!command(np->n_auxp->n_auxp)) ! 98: np = np->n_auxp; ! 99: else if (np->n_next == NULL) ! 100: slret = 0; /* exit status 0 if no elsepart */ ! 101: continue; ! 102: case NELSE: ! 103: command(np->n_auxp); ! 104: break; ! 105: case NCASE: ! 106: eval(np->n_strp, EWORD); ! 107: if (errflag) ! 108: break; ! 109: cname = duplstr(strt, 0); ! 110: continue; ! 111: case NCASE2: ! 112: cnode = np->n_auxp; ! 113: continue; ! 114: case NCASE3: ! 115: /* end of pattern list == next NCASE2 node */ ! 116: eval(np->n_strp, EPATT); ! 117: if (errflag) ! 118: break; ! 119: if (match(strt, cname)) { ! 120: command(cnode); ! 121: break; ! 122: } ! 123: continue; ! 124: case NLIST: ! 125: nllflag = 0; ! 126: command(np->n_auxp); ! 127: continue; ! 128: case NANDF: ! 129: nllflag = 0; ! 130: if (command(np->n_auxp)) ! 131: break; ! 132: continue; ! 133: case NORF: ! 134: nllflag = 0; ! 135: if ( ! command(np->n_auxp)) ! 136: break; ! 137: continue; ! 138: case NBACK: ! 139: if ((f=clone()) == 0) { ! 140: static char *iov[] = { "0</dev/null", NULL }; ! 141: ! 142: bckflag++; ! 143: dflttrp(IBACK); ! 144: redirect(iov); ! 145: exit(command(np->n_auxp)); ! 146: NOTREACHED; ! 147: } ! 148: sback = f; ! 149: prints("%d\n", f); ! 150: f = 0; ! 151: continue; ! 152: case NPIPE: ! 153: f = pipecoms(np); ! 154: break; ! 155: default: ! 156: panic(2); ! 157: NOTREACHED; ! 158: } ! 159: break; ! 160: ! 161: } ! 162: break2: ! 163: nllflag = mynllflag; ! 164: if (sesp->s_con != NULL) ! 165: sesp->s_con = sesp->s_con->c_next; ! 166: if (f) ! 167: waitc(f); ! 168: if (slret) ! 169: assnvar("LASTERROR", lastcmd); ! 170: freebuf(con.c_bpp); ! 171: if (eflag && (slret || errflag)) { ! 172: reset(RUABORT); ! 173: NOTREACHED; ! 174: } ! 175: return slret; ! 176: } ! 177: ! 178: /* ! 179: * Run a simple command. ! 180: * Anything but. ! 181: */ ! 182: #define FARGS 1 ! 183: #define FIORS 2 ! 184: #define FASSG 4 ! 185: ! 186: comscom(np) ! 187: register NODE *np; ! 188: { ! 189: register int f; ! 190: register char **app, *s, *s1, *sp; ! 191: int nputs, nargs; ! 192: ! 193: nargc = 1; ! 194: nargv = makargl(); ! 195: nargv = addargl(nargv, "sh"); ! 196: niovp = makargl(); ! 197: nenvp = makargl(); ! 198: nctlp = NULL; ! 199: /* ! 200: * Scan for arguments. ! 201: * or a control node. ! 202: */ ! 203: nputs = 0; ! 204: f = 0; ! 205: for ( ; np; np = np->n_next) { ! 206: switch (np->n_type) { ! 207: case NIORS: ! 208: f |= FIORS; ! 209: #if 0 ! 210: /* Old code. */ ! 211: eval(np->n_strp, EWORD); ! 212: niovp = addargl(niovp, duplstr(strt, 0)); ! 213: if (xflag) ! 214: nputs += puta(nputs, strt); ! 215: #else ! 216: /* ! 217: * New code by steve 1/24/91. ! 218: * This allows globs in redirection args. ! 219: */ ! 220: s = skipredir(np->n_strp); ! 221: nargs = nargc; ! 222: eval(s, EARGS); /* expand as arg */ ! 223: for (s1 = np->n_strp, sp = strt; s1 < s; ) ! 224: *sp++ = *s1++; ! 225: strcpy(sp, nargv[nargs]); /* build redir arg */ ! 226: niovp = addargl(niovp, duplstr(strt, 0)); ! 227: if (xflag) ! 228: nputs += puta(nputs, strt); ! 229: --nargc; ! 230: for (app = nargv+nargs; *app; app++) { ! 231: *app = *(app + 1); /* shift remaining args */ ! 232: if (xflag && *app != NULL) ! 233: nputs += puta(nputs, *app); ! 234: } ! 235: #endif ! 236: continue; ! 237: case NARGS: ! 238: f |= FARGS; ! 239: nargs = nargc; ! 240: eval(np->n_strp, EARGS); ! 241: if (xflag) ! 242: for (app = nargv+nargs; *app; ) ! 243: nputs += puta(nputs, *app++); ! 244: continue; ! 245: case NASSG: ! 246: if (kflag || (f&FARGS)==0) { ! 247: f |= FASSG; ! 248: eval(np->n_strp, EWORD); ! 249: nenvp = addargl(nenvp, duplstr(strt, 0)); ! 250: if (xflag) ! 251: nputs += puta(nputs, strt); ! 252: } else { ! 253: nargs = nargc; ! 254: eval(np->n_strp, EARGS); ! 255: if (xflag) ! 256: for (app = nargv+nargs; *app; ) ! 257: nputs += puta(nputs, *app++); ! 258: } ! 259: continue; ! 260: case NCTRL: ! 261: if (nctlp!=NULL) { ! 262: panic(3); ! 263: NOTREACHED; ! 264: } ! 265: f |= FARGS; ! 266: nctlp = np; ! 267: continue; ! 268: default: ! 269: panic(4); ! 270: NOTREACHED; ! 271: } ! 272: } ! 273: if (xflag && nputs) ! 274: prints("\n"); ! 275: #ifdef VERBOSE ! 276: if (xflag) { ! 277: prints("\t<%o flag, %d put, %d arg, %o arv, %o env, %o iov>\n", ! 278: f, nputs, nargc-1, *(nargv+1), *nenvp, *niovp); ! 279: } ! 280: #endif ! 281: ! 282: nargv += 1; /* Skip over "sh" */ ! 283: nargc -= 1; ! 284: ! 285: /* Last chance to quit */ ! 286: #ifdef VERBOSE ! 287: if (xflag) prints("errflag = %o\n", errflag); ! 288: #endif ! 289: if (errflag || nflag) ! 290: return (0); ! 291: ! 292: /* And away we go */ ! 293: sfree(lastcmd); ! 294: if (*nargv) ! 295: lastcmd = duplstr(*nargv, 1); ! 296: else ! 297: lastcmd = ""; ! 298: switch (f) { ! 299: case 0: ! 300: return (0); ! 301: case FARGS: ! 302: if (nctlp) { ! 303: command(nctlp->n_auxp); ! 304: return (0); ! 305: } ! 306: case FARGS| FIORS: ! 307: case FARGS| FASSG: ! 308: case FARGS| FIORS| FASSG: ! 309: if (inline()) ! 310: return (0); ! 311: break; ! 312: case FIORS: ! 313: break; ! 314: case FASSG: ! 315: case FIORS| FASSG: ! 316: for (app = nenvp; *app!=NULL; ) ! 317: setsvar(*app++); ! 318: if ((f&~FASSG)==0) { ! 319: slret = 0; ! 320: return (0); ! 321: } ! 322: break; ! 323: default: ! 324: panic(5); ! 325: NOTREACHED; ! 326: } ! 327: if (nllflag || (f=clone()) == 0) { ! 328: if (redirect(niovp) < 0) { ! 329: slret = 1; ! 330: } else if (nargc) { ! 331: dflttrp(ICMD); ! 332: nenvp = envlvar(nenvp); ! 333: flexec(); ! 334: slret = 1; ! 335: } else if (nctlp) { ! 336: command(nctlp->n_auxp); ! 337: } ! 338: exit(slret); ! 339: NOTREACHED; ! 340: } ! 341: return (f); ! 342: } ! 343: ! 344: puta(n, p) ! 345: char *p; ! 346: { ! 347: if (n) ! 348: prints(" "); ! 349: #ifdef VERBOSE ! 350: else ! 351: prints("<%d> ", getpid()); ! 352: #endif ! 353: prints("%s", p); ! 354: return (1); ! 355: } ! 356: ! 357: /* ! 358: * Execute a pipe command. ! 359: * Fork, if necessary, a subshell to execute the pipe. ! 360: * Fork each segment off. ! 361: * Wait for last, save slret, wait for all, return slret from last. ! 362: */ ! 363: pipecoms(np) ! 364: register NODE *np; ! 365: { ! 366: register int f; ! 367: register int p1st = 0; ! 368: int pipev[2]; ! 369: ! 370: if ( ! nllflag && (f = clone()) != 0) ! 371: return (f); ! 372: while (np->n_type == NPIPE) { ! 373: if (f = pipeline(pipev)) { ! 374: /* Parent takes right hand side */ ! 375: np = np->n_next; ! 376: if (p1st == 0) ! 377: p1st = f; ! 378: dup2(pipev[0], 0); ! 379: if (pipev[0] != 0) ! 380: close(pipev[0]); ! 381: close(pipev[1]); ! 382: } else { ! 383: /* Child takes left hand side */ ! 384: np = np->n_auxp; ! 385: dup2(pipev[1], 1); ! 386: close(pipev[0]); ! 387: if (pipev[1] != 1) ! 388: close(pipev[1]); ! 389: exit(command(np)); ! 390: NOTREACHED; ! 391: } ! 392: } ! 393: if (f = clone()) { ! 394: /* Parent waits out pipe line */ ! 395: spipe = p1st; ! 396: close(0); ! 397: if (f = waitc(f)) ! 398: waitc(p1st); ! 399: exit(f); ! 400: NOTREACHED; ! 401: } else { ! 402: /* Child takes the pipe tail */ ! 403: exit(command(np)); ! 404: NOTREACHED; ! 405: } ! 406: } ! 407: ! 408: /* ! 409: * Skip a redirection arg, return pointer to following nonspace. ! 410: */ ! 411: char * ! 412: skipredir(s) register char *s; ! 413: { ! 414: if (*s >= '1' && *s <= '9') ! 415: ++s; ! 416: if (*s == '>' || *s == '<') ! 417: ++s; ! 418: if (*s == '>' || *s == '<') ! 419: ++s; ! 420: if (*s == '&') ! 421: ++s; ! 422: while (*s == ' ' || *s == '\t') ! 423: ++s; ! 424: return s; ! 425: } ! 426: ! 427: /* end of sh/exec1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.