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