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