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