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