|
|
1.1 ! root 1: static char *sccsid = "@(#)sh.func.c 4.10 83/06/11"; ! 2: ! 3: #include "sh.h" ! 4: #include <sys/ioctl.h> ! 5: ! 6: /* ! 7: * C shell ! 8: */ ! 9: ! 10: struct biltins * ! 11: isbfunc(t) ! 12: register struct command *t; ! 13: { ! 14: register char *cp = t->t_dcom[0]; ! 15: register char *dp; ! 16: register struct biltins *bp; ! 17: int dolabel(), dofg1(), dobg1(); ! 18: static struct biltins label = { "", dolabel, 0, 0 }; ! 19: static struct biltins foregnd = { "%job", dofg1, 0, 0 }; ! 20: static struct biltins backgnd = { "%job &", dobg1, 0, 0 }; ! 21: ! 22: if (lastchr(cp) == ':') { ! 23: label.bname = cp; ! 24: return (&label); ! 25: } ! 26: if (*cp == '%') { ! 27: if (t->t_dflg & FAND) { ! 28: t->t_dflg &= ~FAND; ! 29: backgnd.bname = cp; ! 30: return (&backgnd); ! 31: } ! 32: foregnd.bname = cp; ! 33: return (&foregnd); ! 34: } ! 35: for (bp = bfunc; dp = bp->bname; bp++) { ! 36: if (dp[0] == cp[0] && eq(dp, cp)) ! 37: return (bp); ! 38: if (dp[0] > cp[0]) ! 39: break; ! 40: } ! 41: return (0); ! 42: } ! 43: ! 44: func(t, bp) ! 45: register struct command *t; ! 46: register struct biltins *bp; ! 47: { ! 48: int i; ! 49: ! 50: xechoit(t->t_dcom); ! 51: setname(bp->bname); ! 52: i = blklen(t->t_dcom) - 1; ! 53: if (i < bp->minargs) ! 54: bferr("Too few arguments"); ! 55: if (i > bp->maxargs) ! 56: bferr("Too many arguments"); ! 57: (*bp->bfunct)(t->t_dcom, t); ! 58: } ! 59: ! 60: dolabel() ! 61: { ! 62: ! 63: } ! 64: ! 65: doonintr(v) ! 66: char **v; ! 67: { ! 68: register char *cp; ! 69: register char *vv = v[1]; ! 70: ! 71: if (parintr == SIG_IGN) ! 72: return; ! 73: if (setintr && intty) ! 74: bferr("Can't from terminal"); ! 75: cp = gointr, gointr = 0, xfree(cp); ! 76: if (vv == 0) { ! 77: if (setintr) ! 78: sighold(SIGINT); ! 79: else ! 80: sigset(SIGINT, SIG_DFL); ! 81: gointr = 0; ! 82: } else if (eq((vv = strip(vv)), "-")) { ! 83: sigset(SIGINT, SIG_IGN); ! 84: gointr = "-"; ! 85: } else { ! 86: gointr = savestr(vv); ! 87: sigset(SIGINT, pintr); ! 88: } ! 89: } ! 90: ! 91: donohup() ! 92: { ! 93: ! 94: if (intty) ! 95: bferr("Can't from terminal"); ! 96: if (setintr == 0) { ! 97: signal(SIGHUP, SIG_IGN); ! 98: #ifdef CC ! 99: submit(getpid()); ! 100: #endif ! 101: } ! 102: } ! 103: ! 104: dozip() ! 105: { ! 106: ! 107: ; ! 108: } ! 109: ! 110: prvars() ! 111: { ! 112: ! 113: plist(&shvhed); ! 114: } ! 115: ! 116: doalias(v) ! 117: register char **v; ! 118: { ! 119: register struct varent *vp; ! 120: register char *p; ! 121: ! 122: v++; ! 123: p = *v++; ! 124: if (p == 0) ! 125: plist(&aliases); ! 126: else if (*v == 0) { ! 127: vp = adrof1(strip(p), &aliases); ! 128: if (vp) ! 129: blkpr(vp->vec), printf("\n"); ! 130: } else { ! 131: if (eq(p, "alias") || eq(p, "unalias")) { ! 132: setname(p); ! 133: bferr("Too dangerous to alias that"); ! 134: } ! 135: set1(strip(p), saveblk(v), &aliases); ! 136: } ! 137: } ! 138: ! 139: unalias(v) ! 140: char **v; ! 141: { ! 142: ! 143: unset1(v, &aliases); ! 144: } ! 145: ! 146: dologout() ! 147: { ! 148: ! 149: islogin(); ! 150: goodbye(); ! 151: } ! 152: ! 153: dologin(v) ! 154: char **v; ! 155: { ! 156: ! 157: islogin(); ! 158: rechist(); ! 159: signal(SIGTERM, parterm); ! 160: execl("/bin/login", "login", v[1], 0); ! 161: untty(); ! 162: exit(1); ! 163: } ! 164: ! 165: #ifdef NEWGRP ! 166: donewgrp(v) ! 167: char **v; ! 168: { ! 169: ! 170: if (chkstop == 0 && setintr) ! 171: panystop(0); ! 172: signal(SIGTERM, parterm); ! 173: execl("/bin/newgrp", "newgrp", v[1], 0); ! 174: execl("/usr/bin/newgrp", "newgrp", v[1], 0); ! 175: untty(); ! 176: exit(1); ! 177: } ! 178: #endif ! 179: ! 180: islogin() ! 181: { ! 182: ! 183: if (chkstop == 0 && setintr) ! 184: panystop(0); ! 185: if (loginsh) ! 186: return; ! 187: error("Not login shell"); ! 188: } ! 189: ! 190: doif(v, kp) ! 191: char **v; ! 192: struct command *kp; ! 193: { ! 194: register int i; ! 195: register char **vv; ! 196: ! 197: v++; ! 198: i = exp(&v); ! 199: vv = v; ! 200: if (*vv == NOSTR) ! 201: bferr("Empty if"); ! 202: if (eq(*vv, "then")) { ! 203: if (*++vv) ! 204: bferr("Improper then"); ! 205: setname("then"); ! 206: /* ! 207: * If expression was zero, then scan to else, ! 208: * otherwise just fall into following code. ! 209: */ ! 210: if (!i) ! 211: search(ZIF, 0); ! 212: return; ! 213: } ! 214: /* ! 215: * Simple command attached to this if. ! 216: * Left shift the node in this tree, munging it ! 217: * so we can reexecute it. ! 218: */ ! 219: if (i) { ! 220: lshift(kp->t_dcom, vv - kp->t_dcom); ! 221: reexecute(kp); ! 222: donefds(); ! 223: } ! 224: } ! 225: ! 226: /* ! 227: * Reexecute a command, being careful not ! 228: * to redo i/o redirection, which is already set up. ! 229: */ ! 230: reexecute(kp) ! 231: register struct command *kp; ! 232: { ! 233: ! 234: kp->t_dflg &= FSAVE; ! 235: kp->t_dflg |= FREDO; ! 236: /* ! 237: * If tty is still ours to arbitrate, arbitrate it; ! 238: * otherwise dont even set pgrp's as the jobs would ! 239: * then have no way to get the tty (we can't give it ! 240: * to them, and our parent wouldn't know their pgrp, etc. ! 241: */ ! 242: execute(kp, tpgrp > 0 ? tpgrp : -1); ! 243: } ! 244: ! 245: doelse() ! 246: { ! 247: ! 248: search(ZELSE, 0); ! 249: } ! 250: ! 251: dogoto(v) ! 252: char **v; ! 253: { ! 254: register struct whyle *wp; ! 255: char *lp; ! 256: ! 257: /* ! 258: * While we still can, locate any unknown ends of existing loops. ! 259: * This obscure code is the WORST result of the fact that we ! 260: * don't really parse. ! 261: */ ! 262: for (wp = whyles; wp; wp = wp->w_next) ! 263: if (wp->w_end == 0) { ! 264: search(ZBREAK, 0); ! 265: wp->w_end = btell(); ! 266: } else ! 267: bseek(wp->w_end); ! 268: search(ZGOTO, 0, lp = globone(v[1])); ! 269: xfree(lp); ! 270: /* ! 271: * Eliminate loops which were exited. ! 272: */ ! 273: wfree(); ! 274: } ! 275: ! 276: doswitch(v) ! 277: register char **v; ! 278: { ! 279: register char *cp, *lp; ! 280: ! 281: v++; ! 282: if (!*v || *(*v++) != '(') ! 283: goto syntax; ! 284: cp = **v == ')' ? "" : *v++; ! 285: if (*(*v++) != ')') ! 286: v--; ! 287: if (*v) ! 288: syntax: ! 289: error("Syntax error"); ! 290: search(ZSWITCH, 0, lp = globone(cp)); ! 291: xfree(lp); ! 292: } ! 293: ! 294: dobreak() ! 295: { ! 296: ! 297: if (whyles) ! 298: toend(); ! 299: else ! 300: bferr("Not in while/foreach"); ! 301: } ! 302: ! 303: doexit(v) ! 304: char **v; ! 305: { ! 306: ! 307: if (chkstop == 0) ! 308: panystop(0); ! 309: /* ! 310: * Don't DEMAND parentheses here either. ! 311: */ ! 312: v++; ! 313: if (*v) { ! 314: set("status", putn(exp(&v))); ! 315: if (*v) ! 316: bferr("Expression syntax"); ! 317: } ! 318: btoeof(); ! 319: if (intty) ! 320: close(SHIN); ! 321: } ! 322: ! 323: doforeach(v) ! 324: register char **v; ! 325: { ! 326: register char *cp; ! 327: register struct whyle *nwp; ! 328: ! 329: v++; ! 330: cp = strip(*v); ! 331: while (*cp && letter(*cp)) ! 332: cp++; ! 333: if (*cp || strlen(*v) >= 20) ! 334: bferr("Invalid variable"); ! 335: cp = *v++; ! 336: if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')') ! 337: bferr("Words not ()'ed"); ! 338: v++; ! 339: gflag = 0, rscan(v, tglob); ! 340: v = glob(v); ! 341: if (v == 0) ! 342: bferr("No match"); ! 343: nwp = (struct whyle *) calloc(1, sizeof *nwp); ! 344: nwp->w_fe = nwp->w_fe0 = v; gargv = 0; ! 345: nwp->w_start = btell(); ! 346: nwp->w_fename = savestr(cp); ! 347: nwp->w_next = whyles; ! 348: whyles = nwp; ! 349: /* ! 350: * Pre-read the loop so as to be more ! 351: * comprehensible to a terminal user. ! 352: */ ! 353: if (intty) ! 354: preread(); ! 355: doagain(); ! 356: } ! 357: ! 358: dowhile(v) ! 359: char **v; ! 360: { ! 361: register int status; ! 362: register bool again = whyles != 0 && whyles->w_start == lineloc && ! 363: whyles->w_fename == 0; ! 364: ! 365: v++; ! 366: /* ! 367: * Implement prereading here also, taking care not to ! 368: * evaluate the expression before the loop has been read up ! 369: * from a terminal. ! 370: */ ! 371: if (intty && !again) ! 372: status = !exp0(&v, 1); ! 373: else ! 374: status = !exp(&v); ! 375: if (*v) ! 376: bferr("Expression syntax"); ! 377: if (!again) { ! 378: register struct whyle *nwp = (struct whyle *) calloc(1, sizeof (*nwp)); ! 379: ! 380: nwp->w_start = lineloc; ! 381: nwp->w_end = 0; ! 382: nwp->w_next = whyles; ! 383: whyles = nwp; ! 384: if (intty) { ! 385: /* ! 386: * The tty preread ! 387: */ ! 388: preread(); ! 389: doagain(); ! 390: return; ! 391: } ! 392: } ! 393: if (status) ! 394: /* We ain't gonna loop no more, no more! */ ! 395: toend(); ! 396: } ! 397: ! 398: preread() ! 399: { ! 400: ! 401: whyles->w_end = -1; ! 402: if (setintr) ! 403: sigrelse(SIGINT); ! 404: search(ZBREAK, 0); ! 405: if (setintr) ! 406: sighold(SIGINT); ! 407: whyles->w_end = btell(); ! 408: } ! 409: ! 410: doend() ! 411: { ! 412: ! 413: if (!whyles) ! 414: bferr("Not in while/foreach"); ! 415: whyles->w_end = btell(); ! 416: doagain(); ! 417: } ! 418: ! 419: docontin() ! 420: { ! 421: ! 422: if (!whyles) ! 423: bferr("Not in while/foreach"); ! 424: doagain(); ! 425: } ! 426: ! 427: doagain() ! 428: { ! 429: ! 430: /* Repeating a while is simple */ ! 431: if (whyles->w_fename == 0) { ! 432: bseek(whyles->w_start); ! 433: return; ! 434: } ! 435: /* ! 436: * The foreach variable list actually has a spurious word ! 437: * ")" at the end of the w_fe list. Thus we are at the ! 438: * of the list if one word beyond this is 0. ! 439: */ ! 440: if (!whyles->w_fe[1]) { ! 441: dobreak(); ! 442: return; ! 443: } ! 444: set(whyles->w_fename, savestr(*whyles->w_fe++)); ! 445: bseek(whyles->w_start); ! 446: } ! 447: ! 448: dorepeat(v, kp) ! 449: char **v; ! 450: struct command *kp; ! 451: { ! 452: register int i; ! 453: ! 454: i = getn(v[1]); ! 455: if (setintr) ! 456: sighold(SIGINT); ! 457: lshift(v, 2); ! 458: while (i > 0) { ! 459: if (setintr) ! 460: sigrelse(SIGINT); ! 461: reexecute(kp); ! 462: --i; ! 463: } ! 464: donefds(); ! 465: if (setintr) ! 466: sigrelse(SIGINT); ! 467: } ! 468: ! 469: doswbrk() ! 470: { ! 471: ! 472: search(ZBRKSW, 0); ! 473: } ! 474: ! 475: srchx(cp) ! 476: register char *cp; ! 477: { ! 478: register struct srch *sp; ! 479: ! 480: for (sp = srchn; sp->s_name; sp++) ! 481: if (eq(cp, sp->s_name)) ! 482: return (sp->s_value); ! 483: return (-1); ! 484: } ! 485: ! 486: char Stype; ! 487: char *Sgoal; ! 488: ! 489: /*VARARGS2*/ ! 490: search(type, level, goal) ! 491: int type; ! 492: register int level; ! 493: char *goal; ! 494: { ! 495: char wordbuf[BUFSIZ]; ! 496: register char *aword = wordbuf; ! 497: register char *cp; ! 498: ! 499: Stype = type; Sgoal = goal; ! 500: if (type == ZGOTO) ! 501: bseek(0l); ! 502: do { ! 503: if (intty && fseekp == feobp) ! 504: printf("? "), flush(); ! 505: aword[0] = 0, getword(aword); ! 506: switch (srchx(aword)) { ! 507: ! 508: case ZELSE: ! 509: if (level == 0 && type == ZIF) ! 510: return; ! 511: break; ! 512: ! 513: case ZIF: ! 514: while (getword(aword)) ! 515: continue; ! 516: if ((type == ZIF || type == ZELSE) && eq(aword, "then")) ! 517: level++; ! 518: break; ! 519: ! 520: case ZENDIF: ! 521: if (type == ZIF || type == ZELSE) ! 522: level--; ! 523: break; ! 524: ! 525: case ZFOREACH: ! 526: case ZWHILE: ! 527: if (type == ZBREAK) ! 528: level++; ! 529: break; ! 530: ! 531: case ZEND: ! 532: if (type == ZBREAK) ! 533: level--; ! 534: break; ! 535: ! 536: case ZSWITCH: ! 537: if (type == ZSWITCH || type == ZBRKSW) ! 538: level++; ! 539: break; ! 540: ! 541: case ZENDSW: ! 542: if (type == ZSWITCH || type == ZBRKSW) ! 543: level--; ! 544: break; ! 545: ! 546: case ZLABEL: ! 547: if (type == ZGOTO && getword(aword) && eq(aword, goal)) ! 548: level = -1; ! 549: break; ! 550: ! 551: default: ! 552: if (type != ZGOTO && (type != ZSWITCH || level != 0)) ! 553: break; ! 554: if (lastchr(aword) != ':') ! 555: break; ! 556: aword[strlen(aword) - 1] = 0; ! 557: if (type == ZGOTO && eq(aword, goal) || type == ZSWITCH && eq(aword, "default")) ! 558: level = -1; ! 559: break; ! 560: ! 561: case ZCASE: ! 562: if (type != ZSWITCH || level != 0) ! 563: break; ! 564: getword(aword); ! 565: if (lastchr(aword) == ':') ! 566: aword[strlen(aword) - 1] = 0; ! 567: cp = strip(Dfix1(aword)); ! 568: if (Gmatch(goal, cp)) ! 569: level = -1; ! 570: xfree(cp); ! 571: break; ! 572: ! 573: case ZDEFAULT: ! 574: if (type == ZSWITCH && level == 0) ! 575: level = -1; ! 576: break; ! 577: } ! 578: getword(NOSTR); ! 579: } while (level >= 0); ! 580: } ! 581: ! 582: getword(wp) ! 583: register char *wp; ! 584: { ! 585: register int found = 0; ! 586: register int c, d; ! 587: ! 588: c = readc(1); ! 589: d = 0; ! 590: do { ! 591: while (c == ' ' || c == '\t') ! 592: c = readc(1); ! 593: if (c == '#') ! 594: do ! 595: c = readc(1); ! 596: while (c >= 0 && c != '\n'); ! 597: if (c < 0) ! 598: goto past; ! 599: if (c == '\n') { ! 600: if (wp) ! 601: break; ! 602: return (0); ! 603: } ! 604: unreadc(c); ! 605: found = 1; ! 606: do { ! 607: c = readc(1); ! 608: if (c == '\\' && (c = readc(1)) == '\n') ! 609: c = ' '; ! 610: if (any(c, "'\"")) ! 611: if (d == 0) ! 612: d = c; ! 613: else if (d == c) ! 614: d = 0; ! 615: if (c < 0) ! 616: goto past; ! 617: if (wp) ! 618: *wp++ = c; ! 619: } while ((d || c != ' ' && c != '\t') && c != '\n'); ! 620: } while (wp == 0); ! 621: unreadc(c); ! 622: if (found) ! 623: *--wp = 0; ! 624: return (found); ! 625: ! 626: past: ! 627: switch (Stype) { ! 628: ! 629: case ZIF: ! 630: bferr("then/endif not found"); ! 631: ! 632: case ZELSE: ! 633: bferr("endif not found"); ! 634: ! 635: case ZBRKSW: ! 636: case ZSWITCH: ! 637: bferr("endsw not found"); ! 638: ! 639: case ZBREAK: ! 640: bferr("end not found"); ! 641: ! 642: case ZGOTO: ! 643: setname(Sgoal); ! 644: bferr("label not found"); ! 645: } ! 646: /*NOTREACHED*/ ! 647: } ! 648: ! 649: toend() ! 650: { ! 651: ! 652: if (whyles->w_end == 0) { ! 653: search(ZBREAK, 0); ! 654: whyles->w_end = btell() - 1; ! 655: } else ! 656: bseek(whyles->w_end); ! 657: wfree(); ! 658: } ! 659: ! 660: wfree() ! 661: { ! 662: long o = btell(); ! 663: ! 664: while (whyles) { ! 665: register struct whyle *wp = whyles; ! 666: register struct whyle *nwp = wp->w_next; ! 667: ! 668: if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end)) ! 669: break; ! 670: if (wp->w_fe0) ! 671: blkfree(wp->w_fe0); ! 672: if (wp->w_fename) ! 673: xfree(wp->w_fename); ! 674: xfree((char *)wp); ! 675: whyles = nwp; ! 676: } ! 677: } ! 678: ! 679: doecho(v) ! 680: char **v; ! 681: { ! 682: ! 683: echo(' ', v); ! 684: } ! 685: ! 686: doglob(v) ! 687: char **v; ! 688: { ! 689: ! 690: echo(0, v); ! 691: flush(); ! 692: } ! 693: ! 694: echo(sep, v) ! 695: char sep; ! 696: register char **v; ! 697: { ! 698: register char *cp; ! 699: int nonl = 0; ! 700: ! 701: if (setintr) ! 702: sigrelse(SIGINT); ! 703: v++; ! 704: if (*v == 0) ! 705: return; ! 706: gflag = 0; rscan(v, tglob); ! 707: if (gflag) { ! 708: v = glob(v); ! 709: if (v == 0) ! 710: bferr("No match"); ! 711: } else ! 712: scan(v, trim); ! 713: if (sep == ' ' && !strcmp(*v, "-n")) ! 714: nonl++, v++; ! 715: while (cp = *v++) { ! 716: register int c; ! 717: ! 718: while (c = *cp++) ! 719: putchar(c | QUOTE); ! 720: if (*v) ! 721: putchar(sep | QUOTE); ! 722: } ! 723: if (sep && nonl == 0) ! 724: putchar('\n'); ! 725: else ! 726: flush(); ! 727: if (setintr) ! 728: sighold(SIGINT); ! 729: if (gargv) ! 730: blkfree(gargv), gargv = 0; ! 731: } ! 732: ! 733: char **environ; ! 734: ! 735: dosetenv(v) ! 736: register char **v; ! 737: { ! 738: char *lp = globone(v[2]); ! 739: ! 740: setenv(v[1], lp); ! 741: if (eq(v[1], "PATH")) { ! 742: importpath(lp); ! 743: dohash(); ! 744: } ! 745: xfree(lp); ! 746: } ! 747: ! 748: dounsetenv(v) ! 749: register char **v; ! 750: { ! 751: ! 752: v++; ! 753: do ! 754: unsetenv(*v++); ! 755: while (*v); ! 756: } ! 757: ! 758: setenv(name, value) ! 759: char *name, *value; ! 760: { ! 761: register char **ep = environ; ! 762: register char *cp, *dp; ! 763: char *blk[2], **oep = ep; ! 764: ! 765: for (; *ep; ep++) { ! 766: for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) ! 767: continue; ! 768: if (*cp != 0 || *dp != '=') ! 769: continue; ! 770: cp = strspl("=", value); ! 771: xfree(*ep); ! 772: *ep = strspl(name, cp); ! 773: xfree(cp); ! 774: scan(ep, trim); ! 775: return; ! 776: } ! 777: blk[0] = strspl(name, "="); blk[1] = 0; ! 778: environ = blkspl(environ, blk); ! 779: xfree((char *)oep); ! 780: setenv(name, value); ! 781: } ! 782: ! 783: unsetenv(name) ! 784: char *name; ! 785: { ! 786: register char **ep = environ; ! 787: register char *cp, *dp; ! 788: char **oep = ep; ! 789: ! 790: for (; *ep; ep++) { ! 791: for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) ! 792: continue; ! 793: if (*cp != 0 || *dp != '=') ! 794: continue; ! 795: cp = *ep; ! 796: *ep = 0; ! 797: environ = blkspl(environ, ep+1); ! 798: *ep = cp; ! 799: xfree(cp); ! 800: xfree((char *)oep); ! 801: return; ! 802: } ! 803: } ! 804: ! 805: doumask(v) ! 806: register char **v; ! 807: { ! 808: register char *cp = v[1]; ! 809: register int i; ! 810: ! 811: if (cp == 0) { ! 812: i = umask(0); ! 813: umask(i); ! 814: printf("%o\n", i); ! 815: return; ! 816: } ! 817: i = 0; ! 818: while (digit(*cp) && *cp != '8' && *cp != '9') ! 819: i = i * 8 + *cp++ - '0'; ! 820: if (*cp || i < 0 || i > 0777) ! 821: bferr("Improper mask"); ! 822: umask(i); ! 823: } ! 824: ! 825: ! 826: struct limits { ! 827: int limconst; ! 828: char *limname; ! 829: int limdiv; ! 830: char *limscale; ! 831: } limits[] = { ! 832: RLIMIT_CPU, "cputime", 1, "seconds", ! 833: RLIMIT_FSIZE, "filesize", 1024, "kbytes", ! 834: RLIMIT_DATA, "datasize", 1024, "kbytes", ! 835: RLIMIT_STACK, "stacksize", 1024, "kbytes", ! 836: RLIMIT_CORE, "coredumpsize", 1024, "kbytes", ! 837: RLIMIT_RSS, "memoryuse", 1024, "kbytes", ! 838: -1, 0, ! 839: }; ! 840: ! 841: struct limits * ! 842: findlim(cp) ! 843: char *cp; ! 844: { ! 845: register struct limits *lp, *res; ! 846: ! 847: res = 0; ! 848: for (lp = limits; lp->limconst >= 0; lp++) ! 849: if (prefix(cp, lp->limname)) { ! 850: if (res) ! 851: bferr("Ambiguous"); ! 852: res = lp; ! 853: } ! 854: if (res) ! 855: return (res); ! 856: bferr("No such limit"); ! 857: } ! 858: ! 859: dolimit(v) ! 860: register char **v; ! 861: { ! 862: register struct limits *lp; ! 863: register int limit; ! 864: ! 865: v++; ! 866: if (*v == 0) { ! 867: for (lp = limits+1; lp->limconst >= 0; lp++) ! 868: plim(lp); ! 869: return; ! 870: } ! 871: lp = findlim(v[0]); ! 872: if (v[1] == 0) { ! 873: plim(lp); ! 874: return; ! 875: } ! 876: limit = getval(lp, v+1); ! 877: setlim(lp, limit); ! 878: } ! 879: ! 880: getval(lp, v) ! 881: register struct limits *lp; ! 882: char **v; ! 883: { ! 884: register float f; ! 885: double atof(); ! 886: char *cp = *v++; ! 887: ! 888: f = atof(cp); ! 889: while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') ! 890: cp++; ! 891: if (*cp == 0) { ! 892: if (*v == 0) ! 893: return ((int)(f+0.5) * lp->limdiv); ! 894: cp = *v; ! 895: } ! 896: switch (*cp) { ! 897: ! 898: case ':': ! 899: if (lp->limconst != RLIMIT_CPU) ! 900: goto badscal; ! 901: return ((int)(f * 60.0 + atof(cp+1))); ! 902: ! 903: case 'h': ! 904: if (lp->limconst != RLIMIT_CPU) ! 905: goto badscal; ! 906: limtail(cp, "hours"); ! 907: f *= 3600.; ! 908: break; ! 909: ! 910: case 'm': ! 911: if (lp->limconst == RLIMIT_CPU) { ! 912: limtail(cp, "minutes"); ! 913: f *= 60.; ! 914: break; ! 915: } ! 916: case 'M': ! 917: if (lp->limconst == RLIMIT_CPU) ! 918: goto badscal; ! 919: *cp = 'm'; ! 920: limtail(cp, "megabytes"); ! 921: f *= 1024.*1024.; ! 922: break; ! 923: ! 924: case 's': ! 925: if (lp->limconst != RLIMIT_CPU) ! 926: goto badscal; ! 927: limtail(cp, "seconds"); ! 928: break; ! 929: ! 930: case 'k': ! 931: if (lp->limconst == RLIMIT_CPU) ! 932: goto badscal; ! 933: limtail(cp, "kbytes"); ! 934: f *= 1024; ! 935: break; ! 936: ! 937: case 'u': ! 938: limtail(cp, "unlimited"); ! 939: return (RLIM_INFINITY); ! 940: ! 941: default: ! 942: badscal: ! 943: bferr("Improper or unknown scale factor"); ! 944: } ! 945: return ((int)(f+0.5)); ! 946: } ! 947: ! 948: limtail(cp, str0) ! 949: char *cp, *str0; ! 950: { ! 951: register char *str = str0; ! 952: ! 953: while (*cp && *cp == *str) ! 954: cp++, str++; ! 955: if (*cp) ! 956: error("Bad scaling; did you mean ``%s''?", str0); ! 957: } ! 958: ! 959: plim(lp) ! 960: register struct limits *lp; ! 961: { ! 962: struct rlimit rlim; ! 963: ! 964: printf("%s \t", lp->limname); ! 965: getrlimit(lp->limconst, &rlim); ! 966: if (rlim.rlim_cur == RLIM_INFINITY) ! 967: printf("unlimited"); ! 968: else if (lp->limconst == RLIMIT_CPU) ! 969: psecs((long)rlim.rlim_cur); ! 970: else ! 971: printf("%d %s", rlim.rlim_cur / lp->limdiv, lp->limscale); ! 972: printf("\n"); ! 973: } ! 974: ! 975: dounlimit(v) ! 976: register char **v; ! 977: { ! 978: register struct limits *lp; ! 979: ! 980: v++; ! 981: if (*v == 0) { ! 982: for (lp = limits+1; lp->limconst >= 0; lp++) ! 983: setlim(lp, RLIM_INFINITY); ! 984: return; ! 985: } ! 986: while (*v) { ! 987: lp = findlim(*v++); ! 988: setlim(lp, RLIM_INFINITY); ! 989: } ! 990: } ! 991: ! 992: setlim(lp, limit) ! 993: register struct limits *lp; ! 994: { ! 995: struct rlimit rlim; ! 996: ! 997: getrlimit(lp->limconst, &rlim); ! 998: rlim.rlim_cur = limit; ! 999: if (setrlimit(lp->limconst, &rlim) < 0) ! 1000: Perror(bname); ! 1001: } ! 1002: ! 1003: dosuspend() ! 1004: { ! 1005: int (*old)(), ldisc; ! 1006: int ctpgrp; ! 1007: ! 1008: if (loginsh) ! 1009: error("Can't suspend a login shell (yet)"); ! 1010: untty(); ! 1011: old = sigsys(SIGTSTP, SIG_DFL); ! 1012: kill(0, SIGTSTP); ! 1013: /* the shell stops here */ ! 1014: sigsys(SIGTSTP, old); ! 1015: if (tpgrp != -1) { ! 1016: retry: ! 1017: ioctl(FSHTTY, TIOCGPGRP, &ctpgrp); ! 1018: if (ctpgrp != opgrp) { ! 1019: old = sigsys(SIGTTIN, SIG_DFL); ! 1020: kill(0, SIGTTIN); ! 1021: sigsys(SIGTTIN, old); ! 1022: goto retry; ! 1023: } ! 1024: ioctl(FSHTTY, TIOCSPGRP, &shpgrp); ! 1025: setpgrp(0, shpgrp); ! 1026: } ! 1027: ioctl(FSHTTY, TIOCGETD, &oldisc); ! 1028: if (oldisc != NTTYDISC) { ! 1029: printf("Switching to new tty driver...\n"); ! 1030: ldisc = NTTYDISC; ! 1031: ioctl(FSHTTY, TIOCSETD, &ldisc); ! 1032: } ! 1033: } ! 1034: ! 1035: doeval(v) ! 1036: char **v; ! 1037: { ! 1038: char **oevalvec = evalvec; ! 1039: char *oevalp = evalp; ! 1040: jmp_buf osetexit; ! 1041: int reenter; ! 1042: char **gv = 0; ! 1043: ! 1044: v++; ! 1045: if (*v == 0) ! 1046: return; ! 1047: gflag = 0; rscan(v, tglob); ! 1048: if (gflag) { ! 1049: gv = v = glob(v); ! 1050: gargv = 0; ! 1051: if (v == 0) ! 1052: error("No match"); ! 1053: v = copyblk(v); ! 1054: } else ! 1055: scan(v, trim); ! 1056: getexit(osetexit); ! 1057: reenter = 0; ! 1058: setexit(); ! 1059: reenter++; ! 1060: if (reenter == 1) { ! 1061: evalvec = v; ! 1062: evalp = 0; ! 1063: process(0); ! 1064: } ! 1065: evalvec = oevalvec; ! 1066: evalp = oevalp; ! 1067: doneinp = 0; ! 1068: if (gv) ! 1069: blkfree(gv); ! 1070: resexit(osetexit); ! 1071: if (reenter >= 2) ! 1072: error(NOSTR); ! 1073: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.