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