include fixes
[unix-history] / usr / src / bin / csh / func.c
CommitLineData
2f2a0649 1static char *sccsid = "@(#)func.c 4.10 83/06/11";
d43c89f3
BJ
2
3#include "sh.h"
4#include <sys/ioctl.h>
5
6/*
7 * C shell
8 */
9
10struct biltins *
11isbfunc(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
44func(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
60dolabel()
61{
62
63}
64
65doonintr(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)
2f2a0649 78 sighold(SIGINT);
d43c89f3 79 else
2f2a0649 80 sigset(SIGINT, SIG_DFL);
d43c89f3
BJ
81 gointr = 0;
82 } else if (eq((vv = strip(vv)), "-")) {
2f2a0649 83 sigset(SIGINT, SIG_IGN);
d43c89f3
BJ
84 gointr = "-";
85 } else {
86 gointr = savestr(vv);
2f2a0649 87 sigset(SIGINT, pintr);
d43c89f3
BJ
88 }
89}
90
91donohup()
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
104dozip()
105{
106
107 ;
108}
109
110prvars()
111{
112
113 plist(&shvhed);
114}
115
116doalias(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
139unalias(v)
140 char **v;
141{
142
143 unset1(v, &aliases);
144}
145
146dologout()
147{
148
149 islogin();
150 goodbye();
151}
152
153dologin(v)
154 char **v;
155{
156
157 islogin();
5640dff7 158 rechist();
d43c89f3
BJ
159 signal(SIGTERM, parterm);
160 execl("/bin/login", "login", v[1], 0);
161 untty();
162 exit(1);
163}
164
ec1a81af 165#ifdef NEWGRP
d43c89f3
BJ
166donewgrp(v)
167 char **v;
168{
169
6ff5edaf
BJ
170 if (chkstop == 0 && setintr)
171 panystop(0);
d43c89f3
BJ
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}
ec1a81af 178#endif
d43c89f3
BJ
179
180islogin()
181{
182
183 if (chkstop == 0 && setintr)
184 panystop(0);
185 if (loginsh)
186 return;
187 error("Not login shell");
188}
189
190doif(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 */
230reexecute(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
245doelse()
246{
247
248 search(ZELSE, 0);
249}
250
251dogoto(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
276doswitch(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)
288syntax:
289 error("Syntax error");
290 search(ZSWITCH, 0, lp = globone(cp));
291 xfree(lp);
292}
293
294dobreak()
295{
296
297 if (whyles)
298 toend();
299 else
300 bferr("Not in while/foreach");
301}
302
303doexit(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
323doforeach(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
358dowhile(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
398preread()
399{
400
401 whyles->w_end = -1;
402 if (setintr)
2f2a0649 403 sigrelse(SIGINT);
d43c89f3
BJ
404 search(ZBREAK, 0);
405 if (setintr)
2f2a0649 406 sighold(SIGINT);
d43c89f3
BJ
407 whyles->w_end = btell();
408}
409
410doend()
411{
412
413 if (!whyles)
414 bferr("Not in while/foreach");
415 whyles->w_end = btell();
416 doagain();
417}
418
419docontin()
420{
421
422 if (!whyles)
423 bferr("Not in while/foreach");
424 doagain();
425}
426
427doagain()
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
448dorepeat(v, kp)
449 char **v;
450 struct command *kp;
451{
452 register int i;
453
454 i = getn(v[1]);
455 if (setintr)
2f2a0649 456 sighold(SIGINT);
d43c89f3
BJ
457 lshift(v, 2);
458 while (i > 0) {
459 if (setintr)
2f2a0649 460 sigrelse(SIGINT);
d43c89f3
BJ
461 reexecute(kp);
462 --i;
463 }
464 donefds();
465 if (setintr)
2f2a0649 466 sigrelse(SIGINT);
d43c89f3
BJ
467}
468
469doswbrk()
470{
471
472 search(ZBRKSW, 0);
473}
474
475srchx(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
486char Stype;
487char *Sgoal;
488
489/*VARARGS2*/
490search(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
582getword(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);
77626c91
BJ
593 if (c == '#')
594 do
595 c = readc(1);
596 while (c >= 0 && c != '\n');
d43c89f3
BJ
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
626past:
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
649toend()
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
660wfree()
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
679doecho(v)
680 char **v;
681{
682
683 echo(' ', v);
684}
685
686doglob(v)
687 char **v;
688{
689
690 echo(0, v);
691 flush();
692}
693
694echo(sep, v)
695 char sep;
696 register char **v;
697{
698 register char *cp;
699 int nonl = 0;
700
701 if (setintr)
2f2a0649 702 sigrelse(SIGINT);
d43c89f3
BJ
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)
2f2a0649 728 sighold(SIGINT);
d43c89f3
BJ
729 if (gargv)
730 blkfree(gargv), gargv = 0;
731}
732
733char **environ;
734
735dosetenv(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
748dounsetenv(v)
749 register char **v;
750{
751
752 v++;
753 do
754 unsetenv(*v++);
755 while (*v);
756}
757
758setenv(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
783unsetenv(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
805doumask(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
d43c89f3
BJ
825
826struct limits {
827 int limconst;
828 char *limname;
829 int limdiv;
830 char *limscale;
831} limits[] = {
ea775389
SL
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",
d43c89f3
BJ
838 -1, 0,
839};
840
841struct limits *
842findlim(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
859dolimit(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);
d43c89f3
BJ
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
880getval(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 }
d43c89f3
BJ
896 switch (*cp) {
897
898 case ':':
ea775389 899 if (lp->limconst != RLIMIT_CPU)
d43c89f3
BJ
900 goto badscal;
901 return ((int)(f * 60.0 + atof(cp+1)));
902
903 case 'h':
ea775389 904 if (lp->limconst != RLIMIT_CPU)
d43c89f3
BJ
905 goto badscal;
906 limtail(cp, "hours");
907 f *= 3600.;
908 break;
909
910 case 'm':
ea775389 911 if (lp->limconst == RLIMIT_CPU) {
d43c89f3
BJ
912 limtail(cp, "minutes");
913 f *= 60.;
914 break;
915 }
916 case 'M':
ea775389 917 if (lp->limconst == RLIMIT_CPU)
d43c89f3
BJ
918 goto badscal;
919 *cp = 'm';
920 limtail(cp, "megabytes");
921 f *= 1024.*1024.;
922 break;
923
924 case 's':
ea775389 925 if (lp->limconst != RLIMIT_CPU)
d43c89f3
BJ
926 goto badscal;
927 limtail(cp, "seconds");
928 break;
929
930 case 'k':
ea775389 931 if (lp->limconst == RLIMIT_CPU)
d43c89f3
BJ
932 goto badscal;
933 limtail(cp, "kbytes");
934 f *= 1024;
935 break;
936
937 case 'u':
938 limtail(cp, "unlimited");
ea775389 939 return (RLIM_INFINITY);
d43c89f3
BJ
940
941 default:
942badscal:
943 bferr("Improper or unknown scale factor");
944 }
945 return ((int)(f+0.5));
946}
947
948limtail(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
959plim(lp)
960 register struct limits *lp;
961{
ea775389 962 struct rlimit rlim;
d43c89f3
BJ
963
964 printf("%s \t", lp->limname);
ea775389
SL
965 getrlimit(lp->limconst, &rlim);
966 if (rlim.rlim_cur == RLIM_INFINITY)
d43c89f3 967 printf("unlimited");
ea775389
SL
968 else if (lp->limconst == RLIMIT_CPU)
969 psecs((long)rlim.rlim_cur);
d43c89f3 970 else
ea775389 971 printf("%d %s", rlim.rlim_cur / lp->limdiv, lp->limscale);
d43c89f3
BJ
972 printf("\n");
973}
974
975dounlimit(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++)
ea775389 983 setlim(lp, RLIM_INFINITY);
d43c89f3
BJ
984 return;
985 }
986 while (*v) {
987 lp = findlim(*v++);
ea775389 988 setlim(lp, RLIM_INFINITY);
d43c89f3
BJ
989 }
990}
991
992setlim(lp, limit)
993 register struct limits *lp;
994{
ea775389 995 struct rlimit rlim;
d43c89f3 996
ea775389
SL
997 getrlimit(lp->limconst, &rlim);
998 rlim.rlim_cur = limit;
999 if (setrlimit(lp->limconst, &rlim) < 0)
d43c89f3
BJ
1000 Perror(bname);
1001}
1002
1003dosuspend()
1004{
ec1a81af 1005 int (*old)(), ldisc;
cc519405 1006 int ctpgrp;
d43c89f3
BJ
1007
1008 if (loginsh)
1009 error("Can't suspend a login shell (yet)");
1010 untty();
2f2a0649 1011 old = sigsys(SIGTSTP, SIG_DFL);
d43c89f3
BJ
1012 kill(0, SIGTSTP);
1013 /* the shell stops here */
2f2a0649 1014 sigsys(SIGTSTP, old);
d43c89f3
BJ
1015 if (tpgrp != -1) {
1016retry:
1017 ioctl(FSHTTY, TIOCGPGRP, &ctpgrp);
1018 if (ctpgrp != opgrp) {
2f2a0649 1019 old = sigsys(SIGTTIN, SIG_DFL);
d43c89f3 1020 kill(0, SIGTTIN);
2f2a0649 1021 sigsys(SIGTTIN, old);
d43c89f3
BJ
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
1035doeval(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}