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