X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2b84abb596f52ab2068d52108adc96838ad4340a..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/csh/sh.func.c diff --git a/usr/src/cmd/csh/sh.func.c b/usr/src/cmd/csh/sh.func.c index 59062c53ae..b353ddd384 100644 --- a/usr/src/cmd/csh/sh.func.c +++ b/usr/src/cmd/csh/sh.func.c @@ -1,19 +1,37 @@ -/* Copyright (c) 1979 Regents of the University of California */ +static char *sccsid = "@(#)sh.func.c 4.1 10/9/80"; + #include "sh.h" +#include /* * C shell */ struct biltins * -isbfunc(cp) - register char *cp; +isbfunc(t) + register struct command *t; { + register char *cp = t->t_dcom[0]; register char *dp; register struct biltins *bp; - - if (lastchr(cp) == ':') - return ((struct biltins *) 1); + int dolabel(), dofg1(), dobg1(); + static struct biltins label = { "", dolabel, 0, 0 }; + static struct biltins foregnd = { "%job", dofg1, 0, 0 }; + static struct biltins backgnd = { "%job &", dobg1, 0, 0 }; + + if (lastchr(cp) == ':') { + label.bname = cp; + return (&label); + } + if (*cp == '%') { + if (t->t_dflg & FAND) { + t->t_dflg &= ~FAND; + backgnd.bname = cp; + return (&backgnd); + } + foregnd.bname = cp; + return (&foregnd); + } for (bp = bfunc; dp = bp->bname; bp++) { if (dp[0] == cp[0] && eq(dp, cp)) return (bp); @@ -23,28 +41,12 @@ isbfunc(cp) return (0); } -func(t) +func(t, bp) register struct command *t; -{ register struct biltins *bp; +{ int i; - bp = bfunc; - if (lastchr(t->t_dcom[0]) == ':') { - xechoit(t->t_dcom); - if (!eq(t->t_dcom[0], ":") && t->t_dcom[1]) - error("No args on labels"); - return (1); - } - bp = isbfunc(t->t_dcom[0]); - if (bp == 0) - return (0); - /* timed builtins must go in background if output is pipe, or &'ed */ - if (eq(bp->bname, "time")) - if ((t->t_dflg & FAND) || (t->t_dflg & FPOU)) - return (0); - if (eq(bp->bname, "nohup") && t->t_dcom[1]) - return (0); xechoit(t->t_dcom); setname(bp->bname); i = blklen(t->t_dcom) - 1; @@ -52,9 +54,12 @@ func(t) bferr("Too few arguments"); if (i > bp->maxargs) bferr("Too many arguments"); - i = (*bp->bfunct)(t->t_dcom, t); - /* time and nice may not do their deeds, all others guarantee too */ - return (eq(bp->bname, "time") || eq(bp->bname, "nice") ? i : 1); + (*bp->bfunct)(t->t_dcom, t); +} + +dolabel() +{ + } doonintr(v) @@ -69,14 +74,17 @@ doonintr(v) bferr("Can't from terminal"); cp = gointr, gointr = 0, xfree(cp); if (vv == 0) { - signal(SIGINT, setintr ? SIG_IGN : SIG_DFL); + if (setintr) + sighold(SIGINT); + else + sigset(SIGINT, SIG_DFL); gointr = 0; } else if (eq((vv = strip(vv)), "-")) { - signal(SIGINT, SIG_IGN); + sigset(SIGINT, SIG_IGN); gointr = "-"; } else { gointr = savestr(vv); - signal(SIGINT, pintr); + sigset(SIGINT, pintr); } } @@ -99,28 +107,6 @@ dozip() ; } -chngd(vp) - register char **vp; -{ - register int i; - register char *dp; - - vp++; - dp = *vp; - if (dp) - dp = globone(dp); - else { - dp = value("home"); - if (*dp == 0) - bferr("No home"); - } - i = chdir(dp); - if (*vp) - xfree(dp); - if (i < 0) - Perror(dp); -} - prvars() { @@ -169,7 +155,9 @@ dologin(v) { islogin(); + signal(SIGTERM, parterm); execl("/bin/login", "login", v[1], 0); + untty(); exit(1); } @@ -177,13 +165,18 @@ donewgrp(v) char **v; { + signal(SIGTERM, parterm); execl("/bin/newgrp", "newgrp", v[1], 0); execl("/usr/bin/newgrp", "newgrp", v[1], 0); + untty(); + exit(1); } islogin() { + if (chkstop == 0 && setintr) + panystop(0); if (loginsh) return; error("Not login shell"); @@ -199,9 +192,10 @@ doif(v, kp) v++; i = exp(&v); vv = v; - if (*vv && eq(*vv, "then")) { - vv++; - if (*vv) + if (*vv == NOSTR) + bferr("Empty if"); + if (eq(*vv, "then")) { + if (*++vv) bferr("Improper then"); setname("then"); /* @@ -232,8 +226,15 @@ reexecute(kp) register struct command *kp; { - kp->t_dflg = FREDO; - execute(kp); + kp->t_dflg &= FSAVE; + kp->t_dflg |= FREDO; + /* + * If tty is still ours to arbitrate, arbitrate it; + * otherwise dont even set pgrp's as the jobs would + * then have no way to get the tty (we can't give it + * to them, and our parent wouldn't know their pgrp, etc. + */ + execute(kp, tpgrp > 0 ? tpgrp : -1); } doelse() @@ -254,9 +255,10 @@ dogoto(v) * don't really parse. */ for (wp = whyles; wp; wp = wp->w_next) - if (wp->w_end == 0) - wp->w_end = search(ZBREAK, 0); - else + if (wp->w_end == 0) { + search(ZBREAK, 0); + wp->w_end = btell(); + } else bseek(wp->w_end); search(ZGOTO, 0, lp = globone(v[1])); xfree(lp); @@ -297,6 +299,8 @@ doexit(v) char **v; { + if (chkstop == 0) + panystop(0); /* * Don't DEMAND parentheses here either. */ @@ -350,7 +354,8 @@ dowhile(v) char **v; { register int status; - register bool again = whyles != 0 && whyles->w_start == lineloc; + register bool again = whyles != 0 && whyles->w_start == lineloc && + whyles->w_fename == 0; v++; /* @@ -387,14 +392,13 @@ dowhile(v) preread() { - register int (*oldint)(); whyles->w_end = -1; if (setintr) - oldint = signal(SIGINT, pintr); + sigrelse(SIGINT); search(ZBREAK, 0); if (setintr) - signal(SIGINT, oldint); + sighold(SIGINT); whyles->w_end = btell(); } @@ -441,21 +445,20 @@ dorepeat(v, kp) struct command *kp; { register int i; - register int (*saveintr)(); i = getn(v[1]); if (setintr) - saveintr = signal(SIGINT, SIG_IGN); + sighold(SIGINT); lshift(v, 2); while (i > 0) { if (setintr) - signal(SIGINT, pintr); + sigrelse(SIGINT); reexecute(kp); --i; } donefds(); if (setintr) - signal(SIGINT, saveintr); + sigrelse(SIGINT); } doswbrk() @@ -567,7 +570,7 @@ search(type, level, goal) level = -1; break; } - getword(0); + getword(NOSTR); } while (level >= 0); } @@ -659,7 +662,7 @@ wfree() blkfree(wp->w_fe0); if (wp->w_fename) xfree(wp->w_fename); - xfree(wp); + xfree((char *)wp); whyles = nwp; } } @@ -684,10 +687,10 @@ echo(sep, v) register char **v; { register char *cp; - int (*saveintr)(); - if (setintr) - saveintr = signal(SIGINT, pintr); + int nonl = 0; + if (setintr) + sigrelse(SIGINT); v++; if (*v == 0) return; @@ -698,34 +701,26 @@ echo(sep, v) bferr("No match"); } else scan(v, trim); + if (sep == ' ' && !strcmp(*v, "-n")) + nonl++, v++; while (cp = *v++) { register int c; - while (c = *cp++) { - if (sep == ' ' && *cp && c == '\\') { - c = *cp++; - if (c == 'c') { - flush(); - return; - } else if (c == 'n') - c = '\n'; - else - putchar('\\'); - } + while (c = *cp++) putchar(c | QUOTE); - } if (*v) putchar(sep | QUOTE); } - if (sep) + if (sep && nonl == 0) putchar('\n'); + else + flush(); if (setintr) - signal(SIGINT, saveintr); + sighold(SIGINT); if (gargv) blkfree(gargv), gargv = 0; } -#ifndef V6 char **environ; dosetenv(v) @@ -734,9 +729,23 @@ dosetenv(v) char *lp = globone(v[2]); setenv(v[1], lp); + if (eq(v[1], "PATH")) { + importpath(lp); + dohash(); + } xfree(lp); } +dounsetenv(v) + register char **v; +{ + + v++; + do + unsetenv(*v++); + while (*v); +} + setenv(name, value) char *name, *value; { @@ -758,10 +767,32 @@ setenv(name, value) } blk[0] = strspl(name, "="); blk[1] = 0; environ = blkspl(environ, blk); - xfree(oep); + xfree((char *)oep); setenv(name, value); } +unsetenv(name) + char *name; +{ + register char **ep = environ; + register char *cp, *dp; + char **oep = ep; + + for (; *ep; ep++) { + for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) + continue; + if (*cp != 0 || *dp != '=') + continue; + cp = *ep; + *ep = 0; + environ = blkspl(environ, ep+1); + *ep = cp; + xfree(cp); + xfree((char *)oep); + return; + } +} + doumask(v) register char **v; { @@ -781,4 +812,255 @@ doumask(v) bferr("Improper mask"); umask(i); } -#endif + +#include + +struct limits { + int limconst; + char *limname; + int limdiv; + char *limscale; +} limits[] = { + LIM_NORAISE, "noraise", 1, "", + LIM_CPU, "cputime", 1, "seconds", + LIM_FSIZE, "filesize", 1024, "kbytes", + LIM_DATA, "datasize", 1024, "kbytes", + LIM_STACK, "stacksize", 1024, "kbytes", + LIM_CORE, "coredumpsize", 1024, "kbytes", + -1, 0, +}; + +struct limits * +findlim(cp) + char *cp; +{ + register struct limits *lp, *res; + + res = 0; + for (lp = limits; lp->limconst >= 0; lp++) + if (prefix(cp, lp->limname)) { + if (res) + bferr("Ambiguous"); + res = lp; + } + if (res) + return (res); + bferr("No such limit"); +} + +dolimit(v) + register char **v; +{ + register struct limits *lp; + register int limit; + + v++; + if (*v == 0) { + for (lp = limits+1; lp->limconst >= 0; lp++) + plim(lp); + if (vlimit(LIM_NORAISE, -1) && getuid()) + printf("Limits cannot be raised\n"); + return; + } + lp = findlim(v[0]); + if (v[1] == 0) { + plim(lp); + return; + } + limit = getval(lp, v+1); + setlim(lp, limit); +} + +getval(lp, v) + register struct limits *lp; + char **v; +{ + register float f; + double atof(); + char *cp = *v++; + + f = atof(cp); + while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') + cp++; + if (*cp == 0) { + if (*v == 0) + return ((int)(f+0.5) * lp->limdiv); + cp = *v; + } + if (lp->limconst == LIM_NORAISE) + goto badscal; + switch (*cp) { + + case ':': + if (lp->limconst != LIM_CPU) + goto badscal; + return ((int)(f * 60.0 + atof(cp+1))); + + case 'h': + if (lp->limconst != LIM_CPU) + goto badscal; + limtail(cp, "hours"); + f *= 3600.; + break; + + case 'm': + if (lp->limconst == LIM_CPU) { + limtail(cp, "minutes"); + f *= 60.; + break; + } + case 'M': + if (lp->limconst == LIM_CPU) + goto badscal; + *cp = 'm'; + limtail(cp, "megabytes"); + f *= 1024.*1024.; + break; + + case 's': + if (lp->limconst != LIM_CPU) + goto badscal; + limtail(cp, "seconds"); + break; + + case 'k': + if (lp->limconst == LIM_CPU) + goto badscal; + limtail(cp, "kbytes"); + f *= 1024; + break; + + case 'u': + limtail(cp, "unlimited"); + return (INFINITY); + + default: +badscal: + bferr("Improper or unknown scale factor"); + } + return ((int)(f+0.5)); +} + +limtail(cp, str0) + char *cp, *str0; +{ + register char *str = str0; + + while (*cp && *cp == *str) + cp++, str++; + if (*cp) + error("Bad scaling; did you mean ``%s''?", str0); +} + +plim(lp) + register struct limits *lp; +{ + register int lim; + + printf("%s \t", lp->limname); + lim = vlimit(lp->limconst, -1); + if (lim == INFINITY) + printf("unlimited"); + else if (lp->limconst == LIM_CPU) + psecs((long)lim); + else + printf("%d %s", lim / lp->limdiv, lp->limscale); + printf("\n"); +} + +dounlimit(v) + register char **v; +{ + register struct limits *lp; + + v++; + if (*v == 0) { + for (lp = limits+1; lp->limconst >= 0; lp++) + setlim(lp, INFINITY); + return; + } + while (*v) { + lp = findlim(*v++); + setlim(lp, INFINITY); + } +} + +setlim(lp, limit) + register struct limits *lp; +{ + + if (vlimit(lp->limconst, limit) < 0) + Perror(bname); +} + +dosuspend() +{ + int old, ldisc; + short ctpgrp; + + if (loginsh) + error("Can't suspend a login shell (yet)"); + untty(); + old = sigsys(SIGTSTP, SIG_DFL); + kill(0, SIGTSTP); + /* the shell stops here */ + sigsys(SIGTSTP, old); + if (tpgrp != -1) { +retry: + ioctl(FSHTTY, TIOCGPGRP, &ctpgrp); + if (ctpgrp != opgrp) { + old = sigsys(SIGTTIN, SIG_DFL); + kill(0, SIGTTIN); + sigsys(SIGTTIN, old); + goto retry; + } + ioctl(FSHTTY, TIOCSPGRP, &shpgrp); + setpgrp(0, shpgrp); + } + ioctl(FSHTTY, TIOCGETD, &oldisc); + if (oldisc != NTTYDISC) { + printf("Switching to new tty driver...\n"); + ldisc = NTTYDISC; + ioctl(FSHTTY, TIOCSETD, &ldisc); + } +} + +doeval(v) + char **v; +{ + char **oevalvec = evalvec; + char *oevalp = evalp; + jmp_buf osetexit; + int reenter; + char **gv = 0; + + v++; + if (*v == 0) + return; + gflag = 0; rscan(v, tglob); + if (gflag) { + gv = v = glob(v); + gargv = 0; + if (v == 0) + error("No match"); + v = copyblk(v); + } else + scan(v, trim); + getexit(osetexit); + reenter = 0; + setexit(); + reenter++; + if (reenter == 1) { + evalvec = v; + evalp = 0; + process(0); + } + evalvec = oevalvec; + evalp = oevalp; + doneinp = 0; + if (gv) + blkfree(gv); + resexit(osetexit); + if (reenter >= 2) + error(NOSTR); +}