1 static char *sccsid = "@(#)func.c 4.1 10/09/80"; 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/limit.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 } 1067