|
|
1.1 root 1: static char *sccsid = "@(#)sh.func.c 4.1 10/9/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.