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