|
|
1.1 ! root 1: /* ! 2: * sh/exec2.c ! 3: * Bourne shell. ! 4: * System part of execution. ! 5: */ ! 6: ! 7: #include "sh.h" ! 8: #include <errno.h> ! 9: #include <sys/param.h> ! 10: #include <signal.h> ! 11: #include <sys/stat.h> ! 12: ! 13: /* ! 14: * Wait for the given process to complete. ! 15: */ ! 16: waitc(pid) ! 17: int pid; ! 18: { ! 19: register int f; ! 20: unsigned s; ! 21: register int w, n; ! 22: int (*ssig)(); ! 23: ! 24: if (pid < 0) ! 25: f = -pid; ! 26: else ! 27: f = pid; ! 28: if ((ssig=signal(SIGINT, SIG_IGN)) != SIG_IGN) ! 29: signal(SIGINT, sigintr); ! 30: for (;;) { ! 31: if ((w=wait(&s)) >= 0) { ! 32: if (n = (s&0177)) { ! 33: if (n==SIGINT) ! 34: sigintr(n); ! 35: else if (n==SIGPIPE && spipe ! 36: && (w >= spipe && w <= f)) ! 37: ; ! 38: else { ! 39: if (w != f) ! 40: prints("%d: ", w); ! 41: if (n==SIGSYS && (s&0200)==0) ! 42: prints("exec failed"); ! 43: else if (n>0 && n<=NSIG) ! 44: prints("%s", signame[n]); ! 45: else ! 46: prints("status %d", n); ! 47: if (s & 0200) ! 48: prints(" -- core dumped"); ! 49: prints("\n"); ! 50: } ! 51: s = 200 + n; ! 52: } else ! 53: s >>= 8; ! 54: if (w == f) { ! 55: slret = s; ! 56: break; ! 57: } ! 58: } else if (errno==EINTR) { ! 59: if (pid > 0) ! 60: continue; ! 61: else { ! 62: slret = 0; ! 63: break; ! 64: } ! 65: } else if (errno==ECHILD) { ! 66: if (pid == 0) ! 67: slret = 0; ! 68: else ! 69: slret = ECHILD; ! 70: break; ! 71: } else { ! 72: panic(6); ! 73: NOTREACHED; ! 74: } ! 75: } ! 76: signal(SIGINT, ssig); ! 77: return (slret); ! 78: } ! 79: ! 80: /* ! 81: * Make an imperfect copy of ourself. ! 82: */ ! 83: clone() ! 84: { ! 85: register int f; ! 86: register SES *sp; ! 87: ! 88: if ((f=fork()) < 0) { ! 89: prints("Try again\n"); ! 90: reset(RSYSER); ! 91: NOTREACHED; ! 92: } else if (f == 0) { ! 93: nllflag = 1; ! 94: sflag = iflag = cflag = no1flag = lgnflag = 0; ! 95: slret = spipe = 0; ! 96: sp = sesp; ! 97: sp->s_con->c_next = NULL; ! 98: while (sp) { ! 99: if (sp->s_type == SFILE) ! 100: fclose(sp->s_ifp); ! 101: sp = sp->s_next; ! 102: } ! 103: dflttrp(IFORK); ! 104: } ! 105: return (f); ! 106: } ! 107: ! 108: /* ! 109: * Open a pipe, panic on failure. ! 110: * Otherwise return as a clone. ! 111: */ ! 112: pipeline(pv) ! 113: int *pv; ! 114: { ! 115: if (pipe(pv) < 0) { ! 116: prints("Pipe failed\n"); ! 117: reset(RSYSER); ! 118: NOTREACHED; ! 119: } ! 120: return (clone()); ! 121: } ! 122: ! 123: /* ! 124: * Try to execute a file in several ways. ! 125: * A return is always an error. ! 126: * Used by exec in inline. ! 127: */ ! 128: flexec() ! 129: { ! 130: ffind(NULL); ! 131: while (ffind(vpath, *nargv, 1)) { ! 132: execve(strt, nargv, nenvp); ! 133: if (errno==ENOEXEC) { ! 134: scmdp = duplstr(strt, 0); ! 135: nargc += 1; ! 136: nargv -= 1; ! 137: nargv = vdupl(nargv); ! 138: nenvp = vdupl(nenvp); ! 139: while (sesp) { ! 140: freebuf(sesp->s_bpp); ! 141: sesp = sesp->s_next; ! 142: } ! 143: longjmp(restart, 1); ! 144: } ! 145: if (errno==E2BIG) { ! 146: e2big(nargv[0]); ! 147: return(-1); ! 148: } ! 149: } ! 150: ecantfind(nargv[0]); ! 151: return (-1); ! 152: } ! 153: ! 154: /* ! 155: * Process a redirection vector. ! 156: * Abort and return -1 at the first failure, return 0 for success. ! 157: */ ! 158: redirect(iovp) ! 159: char **iovp; ! 160: { ! 161: register char **iopp; ! 162: register char *io; ! 163: register int op; ! 164: int u1, u2; ! 165: ! 166: for (iopp = iovp;(io = *iopp++)!=NULL; ) { ! 167: if (class(*io, MDIGI)) ! 168: u1 = *io++ - '0'; ! 169: else ! 170: u1 = *io=='<' ? 0 : 1; ! 171: for (op=0; ; io+=1) ! 172: if (*io=='>') ! 173: op += 1; ! 174: else if (*io=='<') ! 175: op -= 1; ! 176: else ! 177: break; ! 178: if (*io++ == '&') { ! 179: if (op != 1 && op != -1) { ! 180: panic(7); ! 181: NOTREACHED; ! 182: } ! 183: u2 = *io++; ! 184: if (u2 == '-') { ! 185: close(u1); ! 186: continue; ! 187: } else if (!class(u2, MDIGI)) { ! 188: eredir(); ! 189: return (-1); ! 190: } else { ! 191: u2 -= '0'; ! 192: dup2(u2, u1); ! 193: continue; ! 194: } ! 195: } ! 196: for (io-=1; *io==' '||*io=='\t'; io+=1); ! 197: switch (op) { ! 198: case -2: /* Unquoted here */ ! 199: /* Fall through */ ! 200: case -1: /* Input file, quoted here */ ! 201: if ((u2 = open(io, 0)) < 0) { ! 202: ecantopen(io); ! 203: return (-1); ! 204: } ! 205: if (op == -2 && (u2 = evalhere(u2)) < 0) ! 206: return (-1); ! 207: dup2(u2, u1); ! 208: close(u2); ! 209: continue; ! 210: case 2: /* Append to output */ ! 211: if ((u2 = open(io, 1)) >= 0) { ! 212: lseek(u2, 0L, 2); ! 213: dup2(u2, u1); ! 214: close(u2); ! 215: continue; ! 216: } /* else fall through */ ! 217: case 1: /* Output file */ ! 218: if ((u2 = creat(io, 0666)) < 0) { ! 219: ecantmake(io); ! 220: return (-1); ! 221: } ! 222: dup2(u2, u1); ! 223: close(u2); ! 224: continue; ! 225: default: ! 226: panic(8); ! 227: NOTREACHED; ! 228: } ! 229: } ! 230: return (0); ! 231: } ! 232: ! 233: #ifdef NAMEPIPE ! 234: /* ! 235: * Create a named pipe. ! 236: */ ! 237: npipe(np) ! 238: register NODE *np; ! 239: { ! 240: register char *tmp; ! 241: register int f; ! 242: char *tvec[2]; ! 243: ! 244: tmp = shtmp(); ! 245: mknod(tmp, S_IFPIP, 0); ! 246: if ((f = clone()) == 0) { ! 247: if (np->n_type==NRPIPE) ! 248: strt[0] = '<'; ! 249: else ! 250: strt[0] = '>'; ! 251: strt[1] = '\0'; ! 252: tvec[0] = strcat(strt, tmp); ! 253: tvec[1] = NULL; ! 254: redirect(tvec); ! 255: command(np->n_auxp); ! 256: exit(slret); ! 257: NOTREACHED; ! 258: } ! 259: cleanup(0, tmp); ! 260: strcpy(strt, tmp); ! 261: return; ! 262: } ! 263: #endif ! 264: ! 265: /* ! 266: * Search a path, perhaps repeatedly, for a file with access mode. ! 267: * Is called with paths == NULL to reset pointers. ! 268: * UGLY, but it works. ! 269: */ ! 270: ffind(paths, file, mode) ! 271: char *paths, *file; ! 272: { ! 273: register char c, *cp1, *cp2; ! 274: static char *fp, *ff, *fcp; ! 275: ! 276: if (paths==NULL) { ! 277: fp = ff = fcp = NULL; ! 278: return (0); ! 279: } ! 280: if (ff!=file) { ! 281: fp = fcp = paths; ! 282: ff = file; ! 283: if (index(ff, '/')!=NULL) ! 284: fcp = ""; ! 285: } ! 286: for (c=':'; c==':'; ) { ! 287: cp1 = fcp; ! 288: cp2 = strt; ! 289: while (*cp1 && *cp1!=':') ! 290: *cp2++ = *cp1++; ! 291: if (cp2 != strt) ! 292: *cp2++ = '/'; ! 293: c = *cp1++; ! 294: fcp = cp1; ! 295: cp1 = ff; ! 296: while (*cp2++ = *cp1++); ! 297: if (access(strt, mode)>=0) ! 298: return (1); ! 299: } ! 300: return (0); ! 301: } ! 302: ! 303: /* ! 304: * execute a non standard shell. ! 305: */ ! 306: exshell(vp) VAR *vp; ! 307: { ! 308: char *vshell; ! 309: register char *p; ! 310: ! 311: vshell = vp->v_strp; ! 312: while (*vshell && *vshell++ != '='); ! 313: /* Construct -name argv[0] */ ! 314: if ((p = rindex(vshell, '/')) != NULL) ! 315: p += 1; ! 316: else ! 317: p = vshell; ! 318: strcpy(strt, "-"); ! 319: strcat(strt, p); ! 320: /* Construct argv */ ! 321: nargv = makargl(); ! 322: nargv = addargl(nargv, "sh"); ! 323: nargv = addargl(nargv, duplstr(strt, 0)); ! 324: nargc = 2; ! 325: /* Construct envp */ ! 326: nenvp = makargl(); ! 327: nenvp = envlvar(nenvp); ! 328: /* Try exec */ ! 329: execve(vshell, nargv+1, nenvp); ! 330: ! 331: if (errno==ENOEXEC) { ! 332: fakearg(1, nargc, nargv, nenvp); ! 333: sargc = 0; ! 334: sargp = nargv+2; ! 335: sarg0 = nargv[1]; ! 336: nllflag = 0; ! 337: return session(SFILE, vshell); ! 338: } ! 339: fprintf(stderr, "No shell: %s\n", vshell); ! 340: exit(1); ! 341: } ! 342: ! 343: /* ! 344: * Check to see if we have mail. ! 345: */ ! 346: checkmail() ! 347: { ! 348: static long mailsize = -1; ! 349: struct stat sbuf; ! 350: ! 351: if (*vmail == '\0') ! 352: return; ! 353: if (stat(vmail, &sbuf)<0) { ! 354: mailsize = 0; ! 355: } else { ! 356: if (sbuf.st_size != 0 ! 357: && sbuf.st_size > mailsize) { ! 358: if (mailsize == -1) ! 359: prints("You have mail.\n"); ! 360: else ! 361: prints("You have new mail.\n"); ! 362: } ! 363: mailsize = sbuf.st_size; ! 364: } ! 365: } ! 366: ! 367: /* end of sh/exec2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.