diff options
Diffstat (limited to 'contrib/tcsh/sh.func.c')
-rw-r--r-- | contrib/tcsh/sh.func.c | 2401 |
1 files changed, 0 insertions, 2401 deletions
diff --git a/contrib/tcsh/sh.func.c b/contrib/tcsh/sh.func.c deleted file mode 100644 index 2138bce90c7d..000000000000 --- a/contrib/tcsh/sh.func.c +++ /dev/null @@ -1,2401 +0,0 @@ -/* $Header: /src/pub/tcsh/sh.func.c,v 3.86 2000/01/14 22:57:27 christos Exp $ */ -/* - * sh.func.c: csh builtin functions - */ -/*- - * Copyright (c) 1980, 1991 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include "sh.h" - -RCSID("$Id: sh.func.c,v 3.86 2000/01/14 22:57:27 christos Exp $") - -#include "ed.h" -#include "tw.h" -#include "tc.h" -#ifdef WINNT -#include "nt.const.h" -#endif /* WINNT */ - -/* - * C shell - */ -extern int just_signaled; -extern char **environ; - -extern bool MapsAreInited; -extern bool NLSMapsAreInited; -extern bool NoNLSRebind; -extern bool GotTermCaps; - -static int zlast = -1; - -static void islogin __P((void)); -static void preread __P((void)); -static void doagain __P((void)); -static char *isrchx __P((int)); -static void search __P((int, int, Char *)); -static int getword __P((Char *)); -static void toend __P((void)); -static void xecho __P((int, Char **)); -static bool islocale_var __P((Char *)); - -struct biltins * -isbfunc(t) - struct command *t; -{ - register Char *cp = t->t_dcom[0]; - register struct biltins *bp, *bp1, *bp2; - static struct biltins label = {"", dozip, 0, 0}; - static struct biltins foregnd = {"%job", dofg1, 0, 0}; - static struct biltins backgnd = {"%job &", dobg1, 0, 0}; - - /* - * We never match a builtin that has quoted the first - * character; this has been the traditional way to escape - * builtin commands. - */ - if (*cp & QUOTE) - return NULL; - - if (*cp != ':' && lastchr(cp) == ':') { - label.bname = short2str(cp); - return (&label); - } - if (*cp == '%') { - if (t->t_dflg & F_AMPERSAND) { - t->t_dflg &= ~F_AMPERSAND; - backgnd.bname = short2str(cp); - return (&backgnd); - } - foregnd.bname = short2str(cp); - return (&foregnd); - } -#ifdef WARP - /* - * This is a perhaps kludgy way to determine if the warp builtin is to be - * acknowledged or not. If checkwarp() fails, then we are to assume that - * the warp command is invalid, and carry on as we would handle any other - * non-builtin command. -- JDK 2/4/88 - */ - if (eq(STRwarp, cp) && !checkwarp()) { - return (0); /* this builtin disabled */ - } -#endif /* WARP */ - /* - * Binary search Bp1 is the beginning of the current search range. Bp2 is - * one past the end. - */ - for (bp1 = bfunc, bp2 = bfunc + nbfunc; bp1 < bp2;) { - int i; - - bp = bp1 + ((bp2 - bp1) >> 1); - if ((i = ((char) *cp) - *bp->bname) == 0 && - (i = StrQcmp(cp, str2short(bp->bname))) == 0) - return bp; - if (i < 0) - bp2 = bp; - else - bp1 = bp + 1; - } -#ifdef WINNT - return nt_check_additional_builtins(cp); -#endif /*WINNT*/ - return (0); -} - -void -func(t, bp) - register struct command *t; - register struct biltins *bp; -{ - int i; - - xechoit(t->t_dcom); - setname(bp->bname); - i = blklen(t->t_dcom) - 1; - if (i < bp->minargs) - stderror(ERR_NAME | ERR_TOOFEW); - if (i > bp->maxargs) - stderror(ERR_NAME | ERR_TOOMANY); - (*bp->bfunct) (t->t_dcom, t); -} - -/*ARGSUSED*/ -void -doonintr(v, c) - Char **v; - struct command *c; -{ - register Char *cp; - register Char *vv = v[1]; - - USE(c); - if (parintr == SIG_IGN) - return; - if (setintr && intty) - stderror(ERR_NAME | ERR_TERMINAL); - cp = gointr; - gointr = 0; - xfree((ptr_t) cp); - if (vv == 0) { -#ifdef BSDSIGS - if (setintr) { - (void) sigblock(sigmask(SIGINT)); - (void) signal(SIGINT, pintr); - } - else - (void) signal(SIGINT, SIG_DFL); -#else /* !BSDSIGS */ - if (setintr) { - (void) sighold(SIGINT); - (void) sigset(SIGINT, pintr); - } - else - (void) sigset(SIGINT, SIG_DFL); -#endif /* BSDSIGS */ - gointr = 0; - } - else if (eq((vv = strip(vv)), STRminus)) { -#ifdef BSDSIGS - (void) signal(SIGINT, SIG_IGN); -#else /* !BSDSIGS */ - (void) sigset(SIGINT, SIG_IGN); -#endif /* BSDSIGS */ - gointr = Strsave(STRminus); - } - else { - gointr = Strsave(vv); -#ifdef BSDSIGS - (void) signal(SIGINT, pintr); -#else /* !BSDSIGS */ - (void) sigset(SIGINT, pintr); -#endif /* BSDSIGS */ - } -} - -/*ARGSUSED*/ -void -donohup(v, c) - Char **v; - struct command *c; -{ - USE(c); - USE(v); - if (intty) - stderror(ERR_NAME | ERR_TERMINAL); - if (setintr == 0) { - (void) signal(SIGHUP, SIG_IGN); -#ifdef CC - submit(getpid()); -#endif /* CC */ - } -} - -/*ARGSUSED*/ -void -dohup(v, c) - Char **v; - struct command *c; -{ - USE(c); - USE(v); - if (intty) - stderror(ERR_NAME | ERR_TERMINAL); - if (setintr == 0) - (void) signal(SIGHUP, SIG_DFL); -} - - -/*ARGSUSED*/ -void -dozip(v, c) - Char **v; - struct command *c; -{ - USE(c); - USE(v); -} - -/*ARGSUSED*/ -void -dofiletest(v, c) - Char **v; - struct command *c; -{ - Char **fileptr, *ftest, *res; - - if (*(ftest = *++v) != '-') - stderror(ERR_NAME | ERR_FILEINQ); - ++v; - - gflag = 0; - tglob(v); - if (gflag) { - v = globall(v); - if (v == 0) - stderror(ERR_NAME | ERR_NOMATCH); - } - else - v = gargv = saveblk(v); - trim(v); - - while (*(fileptr = v++) != '\0') { - xprintf("%S", res = filetest(ftest, &fileptr, 0)); - xfree((ptr_t) res); - if (*v) - xprintf(" "); - } - xprintf("\n"); - - if (gargv) { - blkfree(gargv); - gargv = 0; - } -} - -void -prvars() -{ - plist(&shvhed, VAR_ALL); -} - -/*ARGSUSED*/ -void -doalias(v, c) - register Char **v; - struct command *c; -{ - register struct varent *vp; - register Char *p; - - USE(c); - v++; - p = *v++; - if (p == 0) - plist(&aliases, VAR_ALL); - else if (*v == 0) { - vp = adrof1(strip(p), &aliases); - if (vp) - blkpr(vp->vec), xputchar('\n'); - } - else { - if (eq(p, STRalias) || eq(p, STRunalias)) { - setname(short2str(p)); - stderror(ERR_NAME | ERR_DANGER); - } - set1(strip(p), saveblk(v), &aliases, VAR_READWRITE); - tw_cmd_free(); - } -} - -/*ARGSUSED*/ -void -unalias(v, c) - Char **v; - struct command *c; -{ - USE(c); - unset1(v, &aliases); - tw_cmd_free(); -} - -/*ARGSUSED*/ -void -dologout(v, c) - Char **v; - struct command *c; -{ - USE(c); - USE(v); - islogin(); - goodbye(NULL, NULL); -} - -/*ARGSUSED*/ -void -dologin(v, c) - Char **v; - struct command *c; -{ - USE(c); -#ifdef WINNT - USE(v); -#else /* !WINNT */ - islogin(); - rechist(NULL, adrof(STRsavehist) != NULL); - (void) signal(SIGTERM, parterm); - (void) execl(_PATH_BIN_LOGIN, "login", short2str(v[1]), NULL); - (void) execl(_PATH_USRBIN_LOGIN, "login", short2str(v[1]), NULL); - untty(); - xexit(1); -#endif /* !WINNT */ -} - - -#ifdef NEWGRP -/*ARGSUSED*/ -void -donewgrp(v, c) - Char **v; - struct command *c; -{ - char **p; - if (chkstop == 0 && setintr) - panystop(0); - (void) signal(SIGTERM, parterm); - p = short2blk(v); - /* - * From Beto Appleton (beto@aixwiz.austin.ibm.com) - * Newgrp can take 2 arguments... - */ - (void) execv(_PATH_BIN_NEWGRP, p); - (void) execv(_PATH_USRBIN_NEWGRP, p); - blkfree((Char **) p); - untty(); - xexit(1); -} -#endif /* NEWGRP */ - -static void -islogin() -{ - if (chkstop == 0 && setintr) - panystop(0); - if (loginsh) - return; - stderror(ERR_NOTLOGIN); -} - -void -doif(v, kp) - Char **v; - struct command *kp; -{ - register int i; - register Char **vv; - - v++; - i = expr(&v); - vv = v; - if (*vv == NULL) - stderror(ERR_NAME | ERR_EMPTYIF); - if (eq(*vv, STRthen)) { - if (*++vv) - stderror(ERR_NAME | ERR_IMPRTHEN); - setname(short2str(STRthen)); - /* - * If expression was zero, then scan to else , otherwise just fall into - * following code. - */ - if (!i) - search(TC_IF, 0, NULL); - return; - } - /* - * Simple command attached to this if. Left shift the node in this tree, - * munging it so we can reexecute it. - */ - if (i) { - lshift(kp->t_dcom, vv - kp->t_dcom); - reexecute(kp); - donefds(); - } -} - -/* - * Reexecute a command, being careful not - * to redo i/o redirection, which is already set up. - */ -void -reexecute(kp) - register struct command *kp; -{ - kp->t_dflg &= F_SAVE; - kp->t_dflg |= F_REPEAT; - /* - * 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), NULL, NULL); -} - -/*ARGSUSED*/ -void -doelse (v, c) - Char **v; - struct command *c; -{ - USE(c); - USE(v); - search(TC_ELSE, 0, NULL); -} - -/*ARGSUSED*/ -void -dogoto(v, c) - Char **v; - struct command *c; -{ - Char *lp; - - USE(c); - gotolab(lp = globone(v[1], G_ERROR)); - xfree((ptr_t) lp); -} - -void -gotolab(lab) - Char *lab; -{ - register struct whyle *wp; - /* - * While we still can, locate any unknown ends of existing loops. This - * obscure code is the WORST result of the fact that we don't really parse. - */ - zlast = TC_GOTO; - for (wp = whyles; wp; wp = wp->w_next) - if (wp->w_end.type == F_SEEK && wp->w_end.f_seek == 0) { - search(TC_BREAK, 0, NULL); - btell(&wp->w_end); - } - else { - bseek(&wp->w_end); - } - search(TC_GOTO, 0, lab); - /* - * Eliminate loops which were exited. - */ - wfree(); -} - -/*ARGSUSED*/ -void -doswitch(v, c) - register Char **v; - struct command *c; -{ - register Char *cp, *lp; - - USE(c); - v++; - if (!*v || *(*v++) != '(') - stderror(ERR_SYNTAX); - cp = **v == ')' ? STRNULL : *v++; - if (*(*v++) != ')') - v--; - if (*v) - stderror(ERR_SYNTAX); - search(TC_SWITCH, 0, lp = globone(cp, G_ERROR)); - xfree((ptr_t) lp); -} - -/*ARGSUSED*/ -void -dobreak(v, c) - Char **v; - struct command *c; -{ - USE(v); - USE(c); - if (whyles) - toend(); - else - stderror(ERR_NAME | ERR_NOTWHILE); -} - -/*ARGSUSED*/ -void -doexit(v, c) - Char **v; - struct command *c; -{ - USE(c); - - if (chkstop == 0 && (intty || intact) && evalvec == 0) - panystop(0); - /* - * Don't DEMAND parentheses here either. - */ - v++; - if (*v) { - set(STRstatus, putn(expr(&v)), VAR_READWRITE); - if (*v) - stderror(ERR_NAME | ERR_EXPRESSION); - } - btoeof(); -#if 0 - if (intty) -#endif - /* Always close, why only on ttys? */ - (void) close(SHIN); -} - -/*ARGSUSED*/ -void -doforeach(v, c) - register Char **v; - struct command *c; -{ - register Char *cp, *sp; - register struct whyle *nwp; - - USE(c); - v++; - sp = cp = strip(*v); - if (!letter(*sp)) - stderror(ERR_NAME | ERR_VARBEGIN); - while (*cp && alnum(*cp)) - cp++; - if (*cp) - stderror(ERR_NAME | ERR_VARALNUM); - if ((cp - sp) > MAXVARLEN) - stderror(ERR_NAME | ERR_VARTOOLONG); - cp = *v++; - if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')') - stderror(ERR_NAME | ERR_NOPAREN); - v++; - gflag = 0, tglob(v); - if (gflag) { - v = globall(v); - if (v == 0) - stderror(ERR_NAME | ERR_NOMATCH); - } - else { - v = gargv = saveblk(v); - trim(v); - } - nwp = (struct whyle *) xcalloc(1, sizeof *nwp); - nwp->w_fe = nwp->w_fe0 = v; - gargv = 0; - btell(&nwp->w_start); - nwp->w_fename = Strsave(cp); - nwp->w_next = whyles; - nwp->w_end.type = F_SEEK; - whyles = nwp; - /* - * Pre-read the loop so as to be more comprehensible to a terminal user. - */ - zlast = TC_FOREACH; - if (intty) - preread(); - doagain(); -} - -/*ARGSUSED*/ -void -dowhile(v, c) - Char **v; - struct command *c; -{ - register int status; - register bool again = whyles != 0 && - SEEKEQ(&whyles->w_start, &lineloc) && - whyles->w_fename == 0; - - USE(c); - v++; - /* - * Implement prereading here also, taking care not to evaluate the - * expression before the loop has been read up from a terminal. - */ - if (intty && !again) - status = !exp0(&v, 1); - else - status = !expr(&v); - if (*v) - stderror(ERR_NAME | ERR_EXPRESSION); - if (!again) { - register struct whyle *nwp = - (struct whyle *) xcalloc(1, sizeof(*nwp)); - - nwp->w_start = lineloc; - nwp->w_end.type = F_SEEK; - nwp->w_end.f_seek = 0; - nwp->w_next = whyles; - whyles = nwp; - zlast = TC_WHILE; - if (intty) { - /* - * The tty preread - */ - preread(); - doagain(); - return; - } - } - if (status) - /* We ain't gonna loop no more, no more! */ - toend(); -} - -static void -preread() -{ - whyles->w_end.type = I_SEEK; - if (setintr) -#ifdef BSDSIGS - (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT)); -#else /* !BSDSIGS */ - (void) sigrelse (SIGINT); -#endif /* BSDSIGS */ - search(TC_BREAK, 0, NULL); /* read the expression in */ - if (setintr) -#ifdef BSDSIGS - (void) sigblock(sigmask(SIGINT)); -#else /* !BSDSIGS */ - (void) sighold(SIGINT); -#endif /* BSDSIGS */ - btell(&whyles->w_end); -} - -/*ARGSUSED*/ -void -doend(v, c) - Char **v; - struct command *c; -{ - USE(v); - USE(c); - if (!whyles) - stderror(ERR_NAME | ERR_NOTWHILE); - btell(&whyles->w_end); - doagain(); -} - -/*ARGSUSED*/ -void -docontin(v, c) - Char **v; - struct command *c; -{ - USE(v); - USE(c); - if (!whyles) - stderror(ERR_NAME | ERR_NOTWHILE); - doagain(); -} - -static void -doagain() -{ - /* Repeating a while is simple */ - if (whyles->w_fename == 0) { - bseek(&whyles->w_start); - return; - } - /* - * The foreach variable list actually has a spurious word ")" at the end of - * the w_fe list. Thus we are at the of the list if one word beyond this - * is 0. - */ - if (!whyles->w_fe[1]) { - dobreak(NULL, NULL); - return; - } - set(whyles->w_fename, quote(Strsave(*whyles->w_fe++)), VAR_READWRITE); - bseek(&whyles->w_start); -} - -void -dorepeat(v, kp) - Char **v; - struct command *kp; -{ - register int i; - -#ifdef BSDSIGS - register sigmask_t omask = 0; - -#endif /* BSDSIGS */ - - i = getn(v[1]); - if (setintr) -#ifdef BSDSIGS - omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); -#else /* !BSDSIGS */ - (void) sighold(SIGINT); -#endif /* BSDSIGS */ - lshift(v, 2); - while (i > 0) { - if (setintr) -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse (SIGINT); -#endif /* BSDSIGS */ - reexecute(kp); - --i; - } - donefds(); - if (setintr) -#ifdef BSDSIGS - (void) sigsetmask(omask); -#else /* !BSDSIGS */ - (void) sigrelse (SIGINT); -#endif /* BSDSIGS */ -} - -/*ARGSUSED*/ -void -doswbrk(v, c) - Char **v; - struct command *c; -{ - USE(v); - USE(c); - search(TC_BRKSW, 0, NULL); -} - -int -srchx(cp) - Char *cp; -{ - struct srch *sp, *sp1, *sp2; - int i; - - /* - * Ignore keywords inside heredocs - */ - if (inheredoc) - return -1; - - /* - * Binary search Sp1 is the beginning of the current search range. Sp2 is - * one past the end. - */ - for (sp1 = srchn, sp2 = srchn + nsrchn; sp1 < sp2;) { - sp = sp1 + ((sp2 - sp1) >> 1); - if ((i = *cp - *sp->s_name) == 0 && - (i = Strcmp(cp, str2short(sp->s_name))) == 0) - return sp->s_value; - if (i < 0) - sp2 = sp; - else - sp1 = sp + 1; - } - return (-1); -} - -static char * -isrchx(n) - register int n; -{ - register struct srch *sp, *sp2; - - for (sp = srchn, sp2 = srchn + nsrchn; sp < sp2; sp++) - if (sp->s_value == n) - return (sp->s_name); - return (""); -} - - -static Char Stype; -static Char *Sgoal; - -static void -search(type, level, goal) - int type; - register int level; - Char *goal; -{ - Char wordbuf[BUFSIZE]; - register Char *aword = wordbuf; - register Char *cp; - - Stype = (Char) type; - Sgoal = goal; - if (type == TC_GOTO) { - struct Ain a; - a.type = F_SEEK; - a.f_seek = 0; - bseek(&a); - } - do { - if (intty && fseekp == feobp && aret == F_SEEK) - printprompt(1, isrchx(type == TC_BREAK ? zlast : type)); - /* xprintf("? "), flush(); */ - aword[0] = 0; - (void) getword(aword); - switch (srchx(aword)) { - - case TC_ELSE: - if (level == 0 && type == TC_IF) - return; - break; - - case TC_IF: - while (getword(aword)) - continue; - if ((type == TC_IF || type == TC_ELSE) && - eq(aword, STRthen)) - level++; - break; - - case TC_ENDIF: - if (type == TC_IF || type == TC_ELSE) - level--; - break; - - case TC_FOREACH: - case TC_WHILE: - if (type == TC_BREAK) - level++; - break; - - case TC_END: - if (type == TC_BREAK) - level--; - break; - - case TC_SWITCH: - if (type == TC_SWITCH || type == TC_BRKSW) - level++; - break; - - case TC_ENDSW: - if (type == TC_SWITCH || type == TC_BRKSW) - level--; - break; - - case TC_LABEL: - if (type == TC_GOTO && getword(aword) && eq(aword, goal)) - level = -1; - break; - - default: - if (type != TC_GOTO && (type != TC_SWITCH || level != 0)) - break; - if (lastchr(aword) != ':') - break; - aword[Strlen(aword) - 1] = 0; - if ((type == TC_GOTO && eq(aword, goal)) || - (type == TC_SWITCH && eq(aword, STRdefault))) - level = -1; - break; - - case TC_CASE: - if (type != TC_SWITCH || level != 0) - break; - (void) getword(aword); - if (lastchr(aword) == ':') - aword[Strlen(aword) - 1] = 0; - cp = strip(Dfix1(aword)); - if (Gmatch(goal, cp)) - level = -1; - xfree((ptr_t) cp); - break; - - case TC_DEFAULT: - if (type == TC_SWITCH && level == 0) - level = -1; - break; - } - (void) getword(NULL); - } while (level >= 0); -} - -static int -getword(wp) - register Char *wp; -{ - int found = 0, first; - int c, d; - - c = readc(1); - d = 0; - do { - while (c == ' ' || c == '\t') - c = readc(1); - if (c == '#') - do - c = readc(1); - while (c >= 0 && c != '\n'); - if (c < 0) - goto past; - if (c == '\n') { - if (wp) - break; - return (0); - } - unreadc(c); - found = 1; - first = 1; - do { - c = readc(1); - if (c == '\\' && (c = readc(1)) == '\n') - c = ' '; - if (c == '\'' || c == '"') { - if (d == 0) - d = c; - else if (d == c) - d = 0; - } - if (c < 0) - goto past; - if (wp) { - *wp++ = (Char) c; - *wp = '\0'; - } - if (!first && !d && c == '(') { - if (wp) { - unreadc(c); - *--wp = '\0'; - return found; - } - else - break; - } - first = 0; - } while ((d || (c != ' ' && c != '\t')) && c != '\n'); - } while (wp == 0); - - unreadc(c); - if (found) - *--wp = '\0'; - - return (found); - -past: - switch (Stype) { - - case TC_IF: - stderror(ERR_NAME | ERR_NOTFOUND, "then/endif"); - break; - - case TC_ELSE: - stderror(ERR_NAME | ERR_NOTFOUND, "endif"); - break; - - case TC_BRKSW: - case TC_SWITCH: - stderror(ERR_NAME | ERR_NOTFOUND, "endsw"); - break; - - case TC_BREAK: - stderror(ERR_NAME | ERR_NOTFOUND, "end"); - break; - - case TC_GOTO: - setname(short2str(Sgoal)); - stderror(ERR_NAME | ERR_NOTFOUND, "label"); - break; - - default: - break; - } - /* NOTREACHED */ - return (0); -} - -static void -toend() -{ - if (whyles->w_end.type == F_SEEK && whyles->w_end.f_seek == 0) { - search(TC_BREAK, 0, NULL); - btell(&whyles->w_end); - whyles->w_end.f_seek--; - } - else { - bseek(&whyles->w_end); - } - wfree(); -} - -void -wfree() -{ - struct Ain o; - struct whyle *nwp; -#ifdef lint - nwp = NULL; /* sun lint is dumb! */ -#endif - -#ifdef FDEBUG - static char foo[] = "IAFE"; -#endif /* FDEBUG */ - - btell(&o); - -#ifdef FDEBUG - xprintf("o->type %c o->a_seek %d o->f_seek %d\n", - foo[o.type + 1], o.a_seek, o.f_seek); -#endif /* FDEBUG */ - - for (; whyles; whyles = nwp) { - register struct whyle *wp = whyles; - nwp = wp->w_next; - -#ifdef FDEBUG - xprintf("start->type %c start->a_seek %d start->f_seek %d\n", - foo[wp->w_start.type+1], - wp->w_start.a_seek, wp->w_start.f_seek); - xprintf("end->type %c end->a_seek %d end->f_seek %d\n", - foo[wp->w_end.type + 1], wp->w_end.a_seek, wp->w_end.f_seek); -#endif /* FDEBUG */ - - /* - * XXX: We free loops that have different seek types. - */ - if (wp->w_end.type != I_SEEK && wp->w_start.type == wp->w_end.type && - wp->w_start.type == o.type) { - if (wp->w_end.type == F_SEEK) { - if (o.f_seek >= wp->w_start.f_seek && - (wp->w_end.f_seek == 0 || o.f_seek < wp->w_end.f_seek)) - break; - } - else { - if (o.a_seek >= wp->w_start.a_seek && - (wp->w_end.a_seek == 0 || o.a_seek < wp->w_end.a_seek)) - break; - } - } - - if (wp->w_fe0) - blkfree(wp->w_fe0); - if (wp->w_fename) - xfree((ptr_t) wp->w_fename); - xfree((ptr_t) wp); - } -} - -/*ARGSUSED*/ -void -doecho(v, c) - Char **v; - struct command *c; -{ - USE(c); - xecho(' ', v); -} - -/*ARGSUSED*/ -void -doglob(v, c) - Char **v; - struct command *c; -{ - USE(c); - xecho(0, v); - flush(); -} - -static void -xecho(sep, v) - int sep; - register Char **v; -{ - register Char *cp; - int nonl = 0; -#ifdef ECHO_STYLE - int echo_style = ECHO_STYLE; -#else /* !ECHO_STYLE */ -# if SYSVREL > 0 - int echo_style = SYSV_ECHO; -# else /* SYSVREL == 0 */ - int echo_style = BSD_ECHO; -# endif /* SYSVREL */ -#endif /* ECHO_STYLE */ - struct varent *vp; - - if ((vp = adrof(STRecho_style)) != NULL && vp->vec != NULL && - vp->vec[0] != NULL) { - if (Strcmp(vp->vec[0], STRbsd) == 0) - echo_style = BSD_ECHO; - else if (Strcmp(vp->vec[0], STRsysv) == 0) - echo_style = SYSV_ECHO; - else if (Strcmp(vp->vec[0], STRboth) == 0) - echo_style = BOTH_ECHO; - else if (Strcmp(vp->vec[0], STRnone) == 0) - echo_style = NONE_ECHO; - } - - if (setintr) -#ifdef BSDSIGS - (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT)); -#else /* !BSDSIGS */ - (void) sigrelse (SIGINT); -#endif /* BSDSIGS */ - v++; - if (*v == 0) - return; - gflag = 0, tglob(v); - if (gflag) { - v = globall(v); - if (v == 0) - stderror(ERR_NAME | ERR_NOMATCH); - } - else { - v = gargv = saveblk(v); - trim(v); - } - - if ((echo_style & BSD_ECHO) != 0 && sep == ' ' && *v && eq(*v, STRmn)) - nonl++, v++; - - while ((cp = *v++) != 0) { - register int c; - - while ((c = *cp++) != 0) { - if ((echo_style & SYSV_ECHO) != 0 && c == '\\') { - switch (c = *cp++) { - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 'c': - nonl = 1; - goto done; - case 'e': -#if 0 /* Windows does not understand \e */ - c = '\e'; -#else - c = '\033'; -#endif - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case '\\': - c = '\\'; - break; - case '0': - c = 0; - if (*cp >= '0' && *cp < '8') - c = c * 8 + *cp++ - '0'; - if (*cp >= '0' && *cp < '8') - c = c * 8 + *cp++ - '0'; - if (*cp >= '0' && *cp < '8') - c = c * 8 + *cp++ - '0'; - break; - case '\0': - c = '\\'; - cp--; - break; - default: - xputchar('\\' | QUOTE); - break; - } - } - xputchar(c | QUOTE); - - } - if (*v) - xputchar(sep | QUOTE); - } -done: - if (sep && nonl == 0) - xputchar('\n'); - else - flush(); - if (setintr) -#ifdef BSDSIGS - (void) sigblock(sigmask(SIGINT)); -#else /* !BSDSIGS */ - (void) sighold(SIGINT); -#endif /* BSDSIGS */ - if (gargv) - blkfree(gargv), gargv = 0; -} - -/* check whether an environment variable should invoke 'set_locale()' */ -static bool -islocale_var(var) - Char *var; -{ - static Char *locale_vars[] = { - STRLANG, STRLC_CTYPE, STRLC_NUMERIC, STRLC_TIME, - STRLC_COLLATE, STRLC_MESSAGES, STRLC_MONETARY, 0 - }; - register Char **v; - - for (v = locale_vars; *v; ++v) - if (eq(var, *v)) - return 1; - return 0; -} - -/*ARGSUSED*/ -void -doprintenv(v, c) - register Char **v; - struct command *c; -{ - Char *e; - extern bool output_raw; - extern bool xlate_cr; - - USE(c); - if (setintr) -#ifdef BSDSIGS - (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT)); -#else /* !BSDSIGS */ - (void) sigrelse (SIGINT); -#endif /* BSDSIGS */ - - v++; - if (*v == 0) { - register Char **ep; - - xlate_cr = 1; - for (ep = STR_environ; *ep; ep++) - xprintf("%S\n", *ep); - xlate_cr = 0; - } - else if ((e = tgetenv(*v)) != NULL) { - output_raw = 1; - xprintf("%S\n", e); - output_raw = 0; - } - else - set(STRstatus, Strsave(STR1), VAR_READWRITE); -} - -/* from "Karl Berry." <karl%mote.umb.edu@relay.cs.net> -- for NeXT things - (and anything else with a modern compiler) */ - -/*ARGSUSED*/ -void -dosetenv(v, c) - register Char **v; - struct command *c; -{ - Char *vp, *lp; - - USE(c); - if (*++v == 0) { - doprintenv(--v, 0); - return; - } - - vp = *v++; - - if ((lp = *v++) == 0) - lp = STRNULL; - - tsetenv(vp, lp = globone(lp, G_APPEND)); - if (eq(vp, STRKPATH)) { - importpath(lp); - dohash(NULL, NULL); - xfree((ptr_t) lp); - return; - } - -#ifdef apollo - if (eq(vp, STRSYSTYPE)) { - dohash(NULL, NULL); - xfree((ptr_t) lp); - return; - } -#endif /* apollo */ - - /* dspkanji/dspmbyte autosetting */ - /* PATCH IDEA FROM Issei.Suzuki VERY THANKS */ -#if defined(DSPMBYTE) - if(eq(vp, STRLANG) && !adrof(CHECK_MBYTEVAR)) { - autoset_dspmbyte(lp); - } -#endif - - if (islocale_var(vp)) { -#ifdef NLS - int k; - -# ifdef SETLOCALEBUG - dont_free = 1; -# endif /* SETLOCALEBUG */ - (void) setlocale(LC_ALL, ""); -# ifdef LC_COLLATE - (void) setlocale(LC_COLLATE, ""); -# endif -# ifdef NLS_CATALOGS -# ifdef LC_MESSAGES - (void) setlocale(LC_MESSAGES, ""); -# endif /* LC_MESSAGES */ - (void) catclose(catd); - nlsinit(); -# endif /* NLS_CATALOGS */ -# ifdef LC_CTYPE - (void) setlocale(LC_CTYPE, ""); /* for iscntrl */ -# endif /* LC_CTYPE */ -# ifdef SETLOCALEBUG - dont_free = 0; -# endif /* SETLOCALEBUG */ -# ifdef STRCOLLBUG - fix_strcoll_bug(); -# endif /* STRCOLLBUG */ - tw_cmd_free(); /* since the collation sequence has changed */ - for (k = 0200; k <= 0377 && !Isprint(k); k++) - continue; - AsciiOnly = k > 0377; -#else /* !NLS */ - AsciiOnly = 0; -#endif /* NLS */ - NLSMapsAreInited = 0; - ed_Init(); - if (MapsAreInited && !NLSMapsAreInited) - ed_InitNLSMaps(); - xfree((ptr_t) lp); - return; - } - - if (eq(vp, STRNOREBIND)) { - NoNLSRebind = 1; - MapsAreInited = 0; - NLSMapsAreInited = 0; - ed_InitMaps(); - xfree((ptr_t) lp); - return; - } -#ifdef WINNT - if (eq(vp, STRtcshlang)) { - nlsinit(); - xfree((ptr_t) lp); - return; - } - if (eq(vp, STRtcshonlystartexes)) { - __nt_only_start_exes = 1; - xfree((ptr_t) lp); - return; - } -#endif /* WINNT */ - if (eq(vp, STRKTERM)) { - char *t; - set(STRterm, quote(lp), VAR_READWRITE); /* lp memory used here */ - t = short2str(lp); - if (noediting && strcmp(t, "unknown") != 0 && strcmp(t,"dumb") != 0) { - editing = 1; - noediting = 0; - set(STRedit, Strsave(STRNULL), VAR_READWRITE); - } - GotTermCaps = 0; - ed_Init(); - return; - } - - if (eq(vp, STRKHOME)) { - /* - * convert to canonical pathname (possibly resolving symlinks) - */ - lp = dcanon(lp, lp); - set(STRhome, quote(lp), VAR_READWRITE); /* cp memory used here */ - - /* fix directory stack for new tilde home */ - dtilde(); - return; - } - - if (eq(vp, STRKSHLVL)) { - /* lp memory used here */ - set(STRshlvl, quote(lp), VAR_READWRITE); - return; - } - - if (eq(vp, STRKUSER)) { - set(STRuser, quote(lp), VAR_READWRITE); /* lp memory used here */ - return; - } - - if (eq(vp, STRKGROUP)) { - set(STRgroup, quote(lp), VAR_READWRITE); /* lp memory used here */ - return; - } - -#ifdef COLOR_LS_F - if (eq(vp, STRLS_COLORS)) { - parseLS_COLORS(lp); - return; - } -#endif /* COLOR_LS_F */ - -#ifdef SIG_WINDOW - /* - * Load/Update $LINES $COLUMNS - */ - if ((eq(lp, STRNULL) && (eq(vp, STRLINES) || eq(vp, STRCOLUMNS))) || - eq(vp, STRTERMCAP)) { - xfree((ptr_t) lp); - check_window_size(1); - return; - } - - /* - * Change the size to the one directed by $LINES and $COLUMNS - */ - if (eq(vp, STRLINES) || eq(vp, STRCOLUMNS)) { -#if 0 - GotTermCaps = 0; -#endif - xfree((ptr_t) lp); - ed_Init(); - return; - } -#endif /* SIG_WINDOW */ - xfree((ptr_t) lp); -} - -/*ARGSUSED*/ -void -dounsetenv(v, c) - register Char **v; - struct command *c; -{ - Char **ep, *p, *n; - int i, maxi; - static Char *name = NULL; - - USE(c); - if (name) - xfree((ptr_t) name); - /* - * Find the longest environment variable - */ - for (maxi = 0, ep = STR_environ; *ep; ep++) { - for (i = 0, p = *ep; *p && *p != '='; p++, i++) - continue; - if (i > maxi) - maxi = i; - } - - name = (Char *) xmalloc((size_t) ((maxi + 1) * sizeof(Char))); - - while (++v && *v) - for (maxi = 1; maxi;) - for (maxi = 0, ep = STR_environ; *ep; ep++) { - for (n = name, p = *ep; *p && *p != '='; *n++ = *p++) - continue; - *n = '\0'; - if (!Gmatch(name, *v)) - continue; - maxi = 1; - - /* Unset the name. This wasn't being done until - * later but most of the stuff following won't - * work (particularly the setlocale() and getenv() - * stuff) as intended until the name is actually - * removed. (sg) - */ - Unsetenv(name); - - if (eq(name, STRNOREBIND)) { - NoNLSRebind = 0; - MapsAreInited = 0; - NLSMapsAreInited = 0; - ed_InitMaps(); - } -#ifdef apollo - else if (eq(name, STRSYSTYPE)) - dohash(NULL, NULL); -#endif /* apollo */ - else if (islocale_var(name)) { -#ifdef NLS - int k; - -# ifdef SETLOCALEBUG - dont_free = 1; -# endif /* SETLOCALEBUG */ - (void) setlocale(LC_ALL, ""); -# ifdef LC_COLLATE - (void) setlocale(LC_COLLATE, ""); -# endif -# ifdef NLS_CATALOGS -# ifdef LC_MESSAGES - (void) setlocale(LC_MESSAGES, ""); -# endif /* LC_MESSAGES */ - (void) catclose(catd); - nlsinit(); -# endif /* NLS_CATALOGS */ -# ifdef LC_CTYPE - (void) setlocale(LC_CTYPE, ""); /* for iscntrl */ -# endif /* LC_CTYPE */ -# ifdef SETLOCALEBUG - dont_free = 0; -# endif /* SETLOCALEBUG */ -# ifdef STRCOLLBUG - fix_strcoll_bug(); -# endif /* STRCOLLBUG */ - tw_cmd_free();/* since the collation sequence has changed */ - for (k = 0200; k <= 0377 && !Isprint(k); k++) - continue; - AsciiOnly = k > 0377; -#else /* !NLS */ - AsciiOnly = getenv("LANG") == NULL && - getenv("LC_CTYPE") == NULL; -#endif /* NLS */ - NLSMapsAreInited = 0; - ed_Init(); - if (MapsAreInited && !NLSMapsAreInited) - ed_InitNLSMaps(); - - } -#ifdef WINNT - else if (eq(name,(STRtcshlang))) { - nls_dll_unload(); - nlsinit(); - } - else if (eq(name,(STRtcshonlystartexes))) { - __nt_only_start_exes = 0; - } -#endif /* WINNT */ -#ifdef COLOR_LS_F - else if (eq(name, STRLS_COLORS)) - parseLS_COLORS(n); -#endif /* COLOR_LS_F */ - /* - * start again cause the environment changes - */ - break; - } - xfree((ptr_t) name); name = NULL; -} - -void -tsetenv(name, val) - Char *name, *val; -{ -#ifdef SETENV_IN_LIB -/* - * XXX: This does not work right, since tcsh cannot track changes to - * the environment this way. (the builtin setenv without arguments does - * not print the right stuff neither does unsetenv). This was for Mach, - * it is not needed anymore. - */ -#undef setenv - char nameBuf[BUFSIZE]; - char *cname = short2str(name); - - if (cname == NULL) - return; - (void) strcpy(nameBuf, cname); - setenv(nameBuf, short2str(val), 1); -#else /* !SETENV_IN_LIB */ - register Char **ep = STR_environ; - register Char *cp, *dp; - Char *blk[2]; - Char **oep = ep; - -#ifdef WINNT - nt_set_env(name,val); -#endif /* WINNT */ - for (; *ep; ep++) { -#ifdef WINNT - for (cp = name, dp = *ep; *cp && Tolower(*cp & TRIM) == Tolower(*dp); - cp++, dp++) -#else - for (cp = name, dp = *ep; *cp && (*cp & TRIM) == *dp; cp++, dp++) -#endif /* WINNT */ - continue; - if (*cp != 0 || *dp != '=') - continue; - cp = Strspl(STRequal, val); - xfree((ptr_t) * ep); - *ep = strip(Strspl(name, cp)); - xfree((ptr_t) cp); - blkfree((Char **) environ); - environ = short2blk(STR_environ); - return; - } - cp = Strspl(name, STRequal); - blk[0] = strip(Strspl(cp, val)); - xfree((ptr_t) cp); - blk[1] = 0; - STR_environ = blkspl(STR_environ, blk); - blkfree((Char **) environ); - environ = short2blk(STR_environ); - xfree((ptr_t) oep); -#endif /* SETENV_IN_LIB */ -} - -void -Unsetenv(name) - Char *name; -{ - register Char **ep = STR_environ; - register Char *cp, *dp; - Char **oep = ep; - -#ifdef WINNT - nt_set_env(name,NULL); -#endif /*WINNT */ - for (; *ep; ep++) { - for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) - continue; - if (*cp != 0 || *dp != '=') - continue; - cp = *ep; - *ep = 0; - STR_environ = blkspl(STR_environ, ep + 1); - blkfree((Char **) environ); - environ = short2blk(STR_environ); - *ep = cp; - xfree((ptr_t) cp); - xfree((ptr_t) oep); - return; - } -} - -/*ARGSUSED*/ -void -doumask(v, c) - register Char **v; - struct command *c; -{ - register Char *cp = v[1]; - register int i; - - USE(c); - if (cp == 0) { - i = (int)umask(0); - (void) umask(i); - xprintf("%o\n", i); - return; - } - i = 0; - while (Isdigit(*cp) && *cp != '8' && *cp != '9') - i = i * 8 + *cp++ - '0'; - if (*cp || i < 0 || i > 0777) - stderror(ERR_NAME | ERR_MASK); - (void) umask(i); -} - -#ifndef HAVENOLIMIT -# ifndef BSDLIMIT - typedef long RLIM_TYPE; -# ifndef RLIM_INFINITY -# if !defined(_MINIX) && !defined(__clipper__) && !defined(_CRAY) - extern RLIM_TYPE ulimit(); -# endif /* ! _MINIX && !__clipper__ */ -# define RLIM_INFINITY 0x003fffff -# define RLIMIT_FSIZE 1 -# endif /* RLIM_INFINITY */ -# ifdef aiws -# define toset(a) (((a) == 3) ? 1004 : (a) + 1) -# define RLIMIT_DATA 3 -# define RLIMIT_STACK 1005 -# else /* aiws */ -# define toset(a) ((a) + 1) -# endif /* aiws */ -# else /* BSDLIMIT */ -# if defined(BSD4_4) && !defined(__386BSD__) - typedef quad_t RLIM_TYPE; -# else -# if defined(SOLARIS2) || (defined(sgi) && SYSVREL > 3) - typedef rlim_t RLIM_TYPE; -# else -# if defined(_SX) - typedef long long RLIM_TYPE; -# else /* _SX */ - typedef unsigned long RLIM_TYPE; -# endif /* _SX */ -# endif /* SOLARIS2 || (sgi && SYSVREL > 3) */ -# endif /* BSD4_4 && !__386BSD__ */ -# endif /* BSDLIMIT */ - -# if (HPUXVERSION > 700) && defined(BSDLIMIT) -/* Yes hpux8.0 has limits but <sys/resource.h> does not make them public */ -/* Yes, we could have defined _KERNEL, and -I/etc/conf/h, but is that better? */ -# ifndef RLIMIT_CPU -# define RLIMIT_CPU 0 -# define RLIMIT_FSIZE 1 -# define RLIMIT_DATA 2 -# define RLIMIT_STACK 3 -# define RLIMIT_CORE 4 -# define RLIMIT_RSS 5 -# define RLIMIT_NOFILE 6 -# endif /* RLIMIT_CPU */ -# ifndef RLIM_INFINITY -# define RLIM_INFINITY 0x7fffffff -# endif /* RLIM_INFINITY */ - /* - * old versions of HP/UX counted limits in 512 bytes - */ -# ifndef SIGRTMIN -# define FILESIZE512 -# endif /* SIGRTMIN */ -# endif /* (HPUXVERSION > 700) && BSDLIMIT */ - -# if SYSVREL > 3 && defined(BSDLIMIT) && !defined(_SX) -/* In order to use rusage, we included "/usr/ucbinclude/sys/resource.h" in */ -/* sh.h. However, some SVR4 limits are defined in <sys/resource.h>. Rather */ -/* than include both and get warnings, we define the extra SVR4 limits here. */ -# ifndef RLIMIT_VMEM -# define RLIMIT_VMEM 6 -# endif -# ifndef RLIMIT_AS -# define RLIMIT_AS RLIMIT_VMEM -# endif -# endif /* SYSVREL > 3 && BSDLIMIT */ - -struct limits limits[] = -{ -# ifdef RLIMIT_CPU - { RLIMIT_CPU, "cputime", 1, "seconds" }, -# endif /* RLIMIT_CPU */ - -# ifdef RLIMIT_FSIZE -# ifndef aiws - { RLIMIT_FSIZE, "filesize", 1024, "kbytes" }, -# else - { RLIMIT_FSIZE, "filesize", 512, "blocks" }, -# endif /* aiws */ -# endif /* RLIMIT_FSIZE */ - -# ifdef RLIMIT_DATA - { RLIMIT_DATA, "datasize", 1024, "kbytes" }, -# endif /* RLIMIT_DATA */ - -# ifdef RLIMIT_STACK -# ifndef aiws - { RLIMIT_STACK, "stacksize", 1024, "kbytes" }, -# else - { RLIMIT_STACK, "stacksize", 1024 * 1024, "kbytes"}, -# endif /* aiws */ -# endif /* RLIMIT_STACK */ - -# ifdef RLIMIT_CORE - { RLIMIT_CORE, "coredumpsize", 1024, "kbytes" }, -# endif /* RLIMIT_CORE */ - -# ifdef RLIMIT_RSS - { RLIMIT_RSS, "memoryuse", 1024, "kbytes" }, -# endif /* RLIMIT_RSS */ - -# ifdef RLIMIT_UMEM - { RLIMIT_UMEM, "memoryuse", 1024, "kbytes" }, -# endif /* RLIMIT_UMEM */ - -# ifdef RLIMIT_VMEM - { RLIMIT_VMEM, "vmemoryuse", 1024, "kbytes" }, -# endif /* RLIMIT_VMEM */ - -# ifdef RLIMIT_NOFILE - { RLIMIT_NOFILE, "descriptors", 1, "" }, -# endif /* RLIMIT_NOFILE */ - -# ifdef RLIMIT_CONCUR - { RLIMIT_CONCUR, "concurrency", 1, "thread(s)" }, -# endif /* RLIMIT_CONCUR */ - -# ifdef RLIMIT_MEMLOCK - { RLIMIT_MEMLOCK, "memorylocked", 1024, "kbytes" }, -# endif /* RLIMIT_MEMLOCK */ - -# ifdef RLIMIT_NPROC - { RLIMIT_NPROC, "maxproc", 1, "" }, -# endif /* RLIMIT_NPROC */ - -# ifdef RLIMIT_OFILE - { RLIMIT_OFILE, "openfiles", 1, "" }, -# endif /* RLIMIT_OFILE */ - - { -1, NULL, 0, NULL } -}; - -static struct limits *findlim __P((Char *)); -static RLIM_TYPE getval __P((struct limits *, Char **)); -static void limtail __P((Char *, char*)); -static void plim __P((struct limits *, int)); -static int setlim __P((struct limits *, int, RLIM_TYPE)); - -#ifdef convex -static RLIM_TYPE -restrict_limit(value) - double value; -{ - /* - * is f too large to cope with? return the maximum or minimum int - */ - if (value > (double) INT_MAX) - return (RLIM_TYPE) INT_MAX; - else if (value < (double) INT_MIN) - return (RLIM_TYPE) INT_MIN; - else - return (RLIM_TYPE) value; -} -#else /* !convex */ -# define restrict_limit(x) ((RLIM_TYPE) (x)) -#endif /* convex */ - - -static struct limits * -findlim(cp) - Char *cp; -{ - register struct limits *lp, *res; - - res = (struct limits *) NULL; - for (lp = limits; lp->limconst >= 0; lp++) - if (prefix(cp, str2short(lp->limname))) { - if (res) - stderror(ERR_NAME | ERR_AMBIG); - res = lp; - } - if (res) - return (res); - stderror(ERR_NAME | ERR_LIMIT); - /* NOTREACHED */ - return (0); -} - -/*ARGSUSED*/ -void -dolimit(v, c) - register Char **v; - struct command *c; -{ - register struct limits *lp; - register RLIM_TYPE limit; - int hard = 0; - - USE(c); - v++; - if (*v && eq(*v, STRmh)) { - hard = 1; - v++; - } - if (*v == 0) { - for (lp = limits; lp->limconst >= 0; lp++) - plim(lp, hard); - return; - } - lp = findlim(v[0]); - if (v[1] == 0) { - plim(lp, hard); - return; - } - limit = getval(lp, v + 1); - if (setlim(lp, hard, limit) < 0) - stderror(ERR_SILENT); -} - -static RLIM_TYPE -getval(lp, v) - register struct limits *lp; - Char **v; -{ - register float f; -#ifndef atof /* This can be a macro on linux */ - extern double atof __P((const char *)); -#endif /* atof */ - Char *cp = *v++; - - f = atof(short2str(cp)); - -# ifdef convex - /* - * is f too large to cope with. limit f to minint, maxint - X-6768 by - * strike - */ - if ((f < (double) INT_MIN) || (f > (double) INT_MAX)) { - stderror(ERR_NAME | ERR_TOOLARGE); - } -# endif /* convex */ - - while (Isdigit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') - cp++; - if (*cp == 0) { - if (*v == 0) - return f == 0.0 ? (RLIM_TYPE) 0 : restrict_limit((f + 0.5) * lp->limdiv); - cp = *v; - } - switch (*cp) { -# ifdef RLIMIT_CPU - case ':': - if (lp->limconst != RLIMIT_CPU) - goto badscal; - return f == 0.0 ? (RLIM_TYPE) 0 : restrict_limit((f * 60.0 + atof(short2str(cp + 1)))); - case 'h': - if (lp->limconst != RLIMIT_CPU) - goto badscal; - limtail(cp, "hours"); - f *= 3600.0; - break; - case 'm': - if (lp->limconst == RLIMIT_CPU) { - limtail(cp, "minutes"); - f *= 60.0; - break; - } - *cp = 'm'; - limtail(cp, "megabytes"); - f *= 1024.0 * 1024.0; - break; - case 's': - if (lp->limconst != RLIMIT_CPU) - goto badscal; - limtail(cp, "seconds"); - break; -# endif /* RLIMIT_CPU */ - case 'M': -# ifdef RLIMIT_CPU - if (lp->limconst == RLIMIT_CPU) - goto badscal; -# endif /* RLIMIT_CPU */ - *cp = 'm'; - limtail(cp, "megabytes"); - f *= 1024.0 * 1024.0; - break; - case 'k': -# ifdef RLIMIT_CPU - if (lp->limconst == RLIMIT_CPU) - goto badscal; -# endif /* RLIMIT_CPU */ - limtail(cp, "kbytes"); - f *= 1024.0; - break; - case 'b': -# ifdef RLIMIT_CPU - if (lp->limconst == RLIMIT_CPU) - goto badscal; -# endif /* RLIMIT_CPU */ - limtail(cp, "blocks"); - f *= 512.0; - break; - case 'u': - limtail(cp, "unlimited"); - return ((RLIM_TYPE) RLIM_INFINITY); - default: -# ifdef RLIMIT_CPU -badscal: -# endif /* RLIMIT_CPU */ - stderror(ERR_NAME | ERR_SCALEF); - } -# ifdef convex - return f == 0.0 ? (RLIM_TYPE) 0 : restrict_limit((f + 0.5)); -# else - f += 0.5; - if (f > (float) RLIM_INFINITY) - return ((RLIM_TYPE) RLIM_INFINITY); - else - return ((RLIM_TYPE) f); -# endif /* convex */ -} - -static void -limtail(cp, str) - Char *cp; - char *str; -{ - while (*cp && *cp == *str) - cp++, str++; - if (*cp) - stderror(ERR_BADSCALE, str); -} - - -/*ARGSUSED*/ -static void -plim(lp, hard) - register struct limits *lp; - int hard; -{ -# ifdef BSDLIMIT - struct rlimit rlim; -# endif /* BSDLIMIT */ - RLIM_TYPE limit; - int div = lp->limdiv; - - xprintf("%s \t", lp->limname); - -# ifndef BSDLIMIT - limit = ulimit(lp->limconst, 0); -# ifdef aiws - if (lp->limconst == RLIMIT_DATA) - limit -= 0x20000000; -# endif /* aiws */ -# else /* BSDLIMIT */ - (void) getrlimit(lp->limconst, &rlim); - limit = hard ? rlim.rlim_max : rlim.rlim_cur; -# endif /* BSDLIMIT */ - -# if !defined(BSDLIMIT) || defined(FILESIZE512) - /* - * Christos: filesize comes in 512 blocks. we divide by 2 to get 1024 - * blocks. Note we cannot pre-multiply cause we might overflow (A/UX) - */ - if (lp->limconst == RLIMIT_FSIZE) { - if (limit >= (RLIM_INFINITY / 512)) - limit = RLIM_INFINITY; - else - div = (div == 1024 ? 2 : 1); - } -# endif /* !BSDLIMIT || FILESIZE512 */ - - if (limit == RLIM_INFINITY) - xprintf("unlimited"); - else -# ifdef RLIMIT_CPU - if (lp->limconst == RLIMIT_CPU) - psecs((long) limit); - else -# endif /* RLIMIT_CPU */ - xprintf("%ld %s", (long) (limit / div), lp->limscale); - xputchar('\n'); -} - -/*ARGSUSED*/ -void -dounlimit(v, c) - register Char **v; - struct command *c; -{ - register struct limits *lp; - int lerr = 0; - int hard = 0; - int force = 0; - - USE(c); - while (*++v && **v == '-') { - Char *vp = *v; - while (*++vp) - switch (*vp) { - case 'f': - force = 1; - break; - case 'h': - hard = 1; - break; - default: - stderror(ERR_ULIMUS); - break; - } - } - - if (*v == 0) { - for (lp = limits; lp->limconst >= 0; lp++) - if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0) - lerr++; - if (!force && lerr) - stderror(ERR_SILENT); - return; - } - while (*v) { - lp = findlim(*v++); - if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0 && !force) - stderror(ERR_SILENT); - } -} - -static int -setlim(lp, hard, limit) - register struct limits *lp; - int hard; - RLIM_TYPE limit; -{ -# ifdef BSDLIMIT - struct rlimit rlim; - - (void) getrlimit(lp->limconst, &rlim); - -# ifdef FILESIZE512 - /* Even though hpux has setrlimit(), it expects fsize in 512 byte blocks */ - if (limit != RLIM_INFINITY && lp->limconst == RLIMIT_FSIZE) - limit /= 512; -# endif /* FILESIZE512 */ - if (hard) - rlim.rlim_max = limit; - else if (limit == RLIM_INFINITY && euid != 0) - rlim.rlim_cur = rlim.rlim_max; - else - rlim.rlim_cur = limit; - - if (setrlimit(lp->limconst, &rlim) < 0) { -# else /* BSDLIMIT */ - if (limit != RLIM_INFINITY && lp->limconst == RLIMIT_FSIZE) - limit /= 512; -# ifdef aiws - if (lp->limconst == RLIMIT_DATA) - limit += 0x20000000; -# endif /* aiws */ - if (ulimit(toset(lp->limconst), limit) < 0) { -# endif /* BSDLIMIT */ - xprintf(CGETS(15, 1, "%s: %s: Can't %s%s limit\n"), bname, lp->limname, - limit == RLIM_INFINITY ? CGETS(15, 2, "remove") : - CGETS(15, 3, "set"), - hard ? CGETS(14, 4, " hard") : ""); - return (-1); - } - return (0); -} - -#endif /* !HAVENOLIMIT */ - -/*ARGSUSED*/ -void -dosuspend(v, c) - Char **v; - struct command *c; -{ -#ifdef BSDJOBS - int ctpgrp; - - signalfun_t old; -#endif /* BSDJOBS */ - - USE(c); - USE(v); - - if (loginsh) - stderror(ERR_SUSPLOG); - untty(); - -#ifdef BSDJOBS - old = signal(SIGTSTP, SIG_DFL); - (void) kill(0, SIGTSTP); - /* the shell stops here */ - (void) signal(SIGTSTP, old); -#else /* !BSDJOBS */ - stderror(ERR_JOBCONTROL); -#endif /* BSDJOBS */ - -#ifdef BSDJOBS - if (tpgrp != -1) { -retry: - ctpgrp = tcgetpgrp(FSHTTY); - if (ctpgrp != opgrp) { - old = signal(SIGTTIN, SIG_DFL); - (void) kill(0, SIGTTIN); - (void) signal(SIGTTIN, old); - goto retry; - } - (void) setpgid(0, shpgrp); - (void) tcsetpgrp(FSHTTY, shpgrp); - } -#endif /* BSDJOBS */ - (void) setdisc(FSHTTY); -} - -/* This is the dreaded EVAL built-in. - * If you don't fiddle with file descriptors, and reset didfds, - * this command will either ignore redirection inside or outside - * its arguments, e.g. eval "date >x" vs. eval "date" >x - * The stuff here seems to work, but I did it by trial and error rather - * than really knowing what was going on. If tpgrp is zero, we are - * probably a background eval, e.g. "eval date &", and we want to - * make sure that any processes we start stay in our pgrp. - * This is also the case for "time eval date" -- stay in same pgrp. - * Otherwise, under stty tostop, processes will stop in the wrong - * pgrp, with no way for the shell to get them going again. -IAN! - */ - -static Char **gv = NULL, **gav = NULL; - -/*ARGSUSED*/ -void -doeval(v, c) - Char **v; - struct command *c; -{ - Char **oevalvec; - Char *oevalp; - int odidfds; -#ifndef CLOSE_ON_EXEC - int odidcch; -#endif /* CLOSE_ON_EXEC */ - jmp_buf_t osetexit; - int my_reenter; - Char **savegv; - int saveIN, saveOUT, saveDIAG; - int oSHIN, oSHOUT, oSHDIAG; - - USE(c); - oevalvec = evalvec; - oevalp = evalp; - odidfds = didfds; -#ifndef CLOSE_ON_EXEC - odidcch = didcch; -#endif /* CLOSE_ON_EXEC */ - oSHIN = SHIN; - oSHOUT = SHOUT; - oSHDIAG = SHDIAG; - - savegv = gv; - gav = v; - - gav++; - if (*gav == 0) - return; - gflag = 0, tglob(gav); - if (gflag) { - gv = gav = globall(gav); - gargv = 0; - if (gav == 0) - stderror(ERR_NOMATCH); - gav = copyblk(gav); - } - else { - gv = NULL; - gav = copyblk(gav); - trim(gav); - } - - saveIN = dcopy(SHIN, -1); - saveOUT = dcopy(SHOUT, -1); - saveDIAG = dcopy(SHDIAG, -1); - - getexit(osetexit); - - /* PWP: setjmp/longjmp bugfix for optimizing compilers */ -#ifdef cray - my_reenter = 1; /* assume non-zero return val */ - if (setexit() == 0) { - my_reenter = 0; /* Oh well, we were wrong */ -#else /* !cray */ - if ((my_reenter = setexit()) == 0) { -#endif /* cray */ - evalvec = gav; - evalp = 0; - SHIN = dcopy(0, -1); - SHOUT = dcopy(1, -1); - SHDIAG = dcopy(2, -1); -#ifndef CLOSE_ON_EXEC - didcch = 0; -#endif /* CLOSE_ON_EXEC */ - didfds = 0; - process(0); - } - - evalvec = oevalvec; - evalp = oevalp; - doneinp = 0; -#ifndef CLOSE_ON_EXEC - didcch = odidcch; -#endif /* CLOSE_ON_EXEC */ - didfds = odidfds; - (void) close(SHIN); - (void) close(SHOUT); - (void) close(SHDIAG); - SHIN = dmove(saveIN, oSHIN); - SHOUT = dmove(saveOUT, oSHOUT); - SHDIAG = dmove(saveDIAG, oSHDIAG); - - if (gv) - blkfree(gv); - - gv = savegv; - resexit(osetexit); - if (my_reenter) - stderror(ERR_SILENT); -} - -/*************************************************************************/ -/* print list of builtin commands */ - -/*ARGSUSED*/ -void -dobuiltins(v, c) -Char **v; -struct command *c; -{ - /* would use print_by_column() in tw.parse.c but that assumes - * we have an array of Char * to pass.. (sg) - */ - extern int Tty_raw_mode; - extern int TermH; /* from the editor routines */ - extern int lbuffed; /* from sh.print.c */ - - register struct biltins *b; - register int row, col, columns, rows; - unsigned int w, maxwidth; - - USE(c); - USE(v); - lbuffed = 0; /* turn off line buffering */ - - /* find widest string */ - for (maxwidth = 0, b = bfunc; b < &bfunc[nbfunc]; ++b) - maxwidth = max(maxwidth, strlen(b->bname)); - ++maxwidth; /* for space */ - - columns = (TermH + 1) / maxwidth; /* PWP: terminal size change */ - if (!columns) - columns = 1; - rows = (nbfunc + (columns - 1)) / columns; - - for (b = bfunc, row = 0; row < rows; row++) { - for (col = 0; col < columns; col++) { - if (b < &bfunc[nbfunc]) { - w = strlen(b->bname); - xprintf("%s", b->bname); - if (col < (columns - 1)) /* Not last column? */ - for (; w < maxwidth; w++) - xputchar(' '); - ++b; - } - } - if (row < (rows - 1)) { - if (Tty_raw_mode) - xputchar('\r'); - xputchar('\n'); - } - } -#ifdef WINNT - nt_print_builtins(maxwidth); -#else - if (Tty_raw_mode) - xputchar('\r'); - xputchar('\n'); -#endif /* WINNT */ - - lbuffed = 1; /* turn back on line buffering */ - flush(); -} - -void -nlsinit() -{ -#ifdef NLS_CATALOGS - catd = catopen("tcsh", MCLoadBySet); -#endif -#ifdef WINNT - nls_dll_init(); -#endif /* WINNT */ - errinit(); /* init the errorlist in correct locale */ - mesginit(); /* init the messages for signals */ - dateinit(); /* init the messages for dates */ - editinit(); /* init the editor messages */ - terminit(); /* init the termcap messages */ -} |