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