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