diff options
author | Bryan Drewery <bryan@shatow.net> | 2016-03-23 22:08:52 +0300 |
---|---|---|
committer | Bryan Drewery <bryan@shatow.net> | 2016-03-23 22:08:52 +0300 |
commit | 52516207ac8685a7f6073536b63954eb37311ec4 (patch) | |
tree | 1f8d7af3dfed1f54540627a6ef74bcea78d22313 /external | |
parent | d0c3d0061d191c0cea08ffbfa221dbae96796fe3 (diff) |
Update sh from head @ r296813
Diffstat (limited to 'external')
-rw-r--r-- | external/sh/alias.c | 8 | ||||
-rw-r--r-- | external/sh/cd.c | 50 | ||||
-rw-r--r-- | external/sh/eval.c | 6 | ||||
-rw-r--r-- | external/sh/exec.c | 7 | ||||
-rw-r--r-- | external/sh/expand.c | 59 | ||||
-rw-r--r-- | external/sh/histedit.c | 4 | ||||
-rw-r--r-- | external/sh/input.c | 57 | ||||
-rw-r--r-- | external/sh/jobs.c | 38 | ||||
-rw-r--r-- | external/sh/miscbltin.c | 7 | ||||
-rw-r--r-- | external/sh/options.c | 68 | ||||
-rw-r--r-- | external/sh/options.h | 98 | ||||
-rw-r--r-- | external/sh/parser.c | 6 | ||||
-rw-r--r-- | external/sh/redir.c | 31 | ||||
-rw-r--r-- | external/sh/test.c | 166 | ||||
-rw-r--r-- | external/sh/var.c | 20 |
15 files changed, 345 insertions, 280 deletions
diff --git a/external/sh/alias.c b/external/sh/alias.c index 1f2442b1..4eb6f9e5 100644 --- a/external/sh/alias.c +++ b/external/sh/alias.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/alias.c 284779 2015-06-24 20:51:48Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/alias.c 295868 2016-02-21 20:58:24Z jilles $"); #include <stdlib.h> #include "shell.h" @@ -144,9 +144,11 @@ rmaliases(void) struct alias * lookupalias(const char *name, int check) { - struct alias *ap = *hashalias(name); + struct alias *ap; - for (; ap; ap = ap->next) { + if (aliases == 0) + return (NULL); + for (ap = *hashalias(name); ap; ap = ap->next) { if (equal(name, ap->name)) { if (check && (ap->flag & ALIASINUSE)) return (NULL); diff --git a/external/sh/cd.c b/external/sh/cd.c index 596d782b..67a80bd7 100644 --- a/external/sh/cd.c +++ b/external/sh/cd.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/cd.c 278820 2015-02-15 21:47:43Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/cd.c 294667 2016-01-24 17:01:34Z jilles $"); #include <sys/types.h> #include <sys/stat.h> @@ -68,15 +68,13 @@ __FBSDID("$FreeBSD: head/bin/sh/cd.c 278820 2015-02-15 21:47:43Z jilles $"); static int cdlogical(char *); static int cdphysical(char *); static int docd(char *, int, int); -static char *getcomponent(void); +static char *getcomponent(char **); static char *findcwd(char *); static void updatepwd(char *); static char *getpwd(void); static char *getpwd2(void); static char *curdir = NULL; /* current working directory */ -static char *prevdir; /* previous working directory */ -static char *cdcomppath; int cdcmd(int argc __unused, char **argv __unused) @@ -112,11 +110,10 @@ cdcmd(int argc __unused, char **argv __unused) if (*dest == '\0') dest = "."; if (dest[0] == '-' && dest[1] == '\0') { - dest = prevdir ? prevdir : curdir; - if (dest) - print = 1; - else - dest = "."; + dest = bltinlookup("OLDPWD", 1); + if (dest == NULL) + error("OLDPWD not set"); + print = 1; } if (dest[0] == '/' || (dest[0] == '.' && (dest[1] == '/' || dest[1] == '\0')) || @@ -179,6 +176,7 @@ cdlogical(char *dest) char *p; char *q; char *component; + char *path; struct stat statb; int first; int badstat; @@ -189,14 +187,14 @@ cdlogical(char *dest) * next time we get the value of the current directory. */ badstat = 0; - cdcomppath = stsavestr(dest); + path = stsavestr(dest); STARTSTACKSTR(p); if (*dest == '/') { STPUTC('/', p); - cdcomppath++; + path++; } first = 1; - while ((q = getcomponent()) != NULL) { + while ((q = getcomponent(&path)) != NULL) { if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) continue; if (! first) @@ -245,25 +243,25 @@ cdphysical(char *dest) } /* - * Get the next component of the path name pointed to by cdcomppath. - * This routine overwrites the string pointed to by cdcomppath. + * Get the next component of the path name pointed to by *path. + * This routine overwrites *path and the string pointed to by it. */ static char * -getcomponent(void) +getcomponent(char **path) { char *p; char *start; - if ((p = cdcomppath) == NULL) + if ((p = *path) == NULL) return NULL; - start = cdcomppath; + start = *path; while (*p != '/' && *p != '\0') p++; if (*p == '\0') { - cdcomppath = NULL; + *path = NULL; } else { *p++ = '\0'; - cdcomppath = p; + *path = p; } return start; } @@ -274,6 +272,7 @@ findcwd(char *dir) { char *new; char *p; + char *path; /* * If our argument is NULL, we don't know the current directory @@ -282,14 +281,14 @@ findcwd(char *dir) */ if (dir == NULL || curdir == NULL) return getpwd2(); - cdcomppath = stsavestr(dir); + path = stsavestr(dir); STARTSTACKSTR(new); if (*dir != '/') { STPUTS(curdir, new); if (STTOPC(new) == '/') STUNPUTC(new); } - while ((p = getcomponent()) != NULL) { + while ((p = getcomponent(&path)) != NULL) { if (equal(p, "..")) { while (new > stackblock() && (STUNPUTC(new), *new) != '/'); } else if (*p != '\0' && ! equal(p, ".")) { @@ -311,14 +310,15 @@ findcwd(char *dir) static void updatepwd(char *dir) { + char *prevdir; + hashcd(); /* update command hash table */ - if (prevdir) - ckfree(prevdir); + setvar("PWD", dir, VEXPORT); + setvar("OLDPWD", curdir, VEXPORT); prevdir = curdir; curdir = dir ? savestr(dir) : NULL; - setvar("PWD", curdir, VEXPORT); - setvar("OLDPWD", prevdir, VEXPORT); + ckfree(prevdir); } int diff --git a/external/sh/eval.c b/external/sh/eval.c index 8413c0cc..4184c06d 100644 --- a/external/sh/eval.c +++ b/external/sh/eval.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/eval.c 293359 2016-01-07 20:48:24Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/eval.c 293635 2016-01-10 16:31:28Z jilles $"); #include <paths.h> #include <signal.h> @@ -1039,12 +1039,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) reffunc(cmdentry.u.func); savehandler = handler; if (setjmp(jmploc.loc)) { - freeparam(&shellparam); - shellparam = saveparam; popredir(); unreffunc(cmdentry.u.func); poplocalvars(); localvars = savelocalvars; + freeparam(&shellparam); + shellparam = saveparam; funcnest--; handler = savehandler; longjmp(handler->loc, 1); diff --git a/external/sh/exec.c b/external/sh/exec.c index e3a1868f..c4b4e2ab 100644 --- a/external/sh/exec.c +++ b/external/sh/exec.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/exec.c 293118 2016-01-03 21:30:22Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/exec.c 296813 2016-03-13 22:54:14Z jilles $"); #include <sys/types.h> #include <sys/stat.h> @@ -332,6 +332,7 @@ find_command(const char *name, struct cmdentry *entry, int act, if (strchr(name, '/') != NULL) { entry->cmdtype = CMDNORMAL; entry->u.index = 0; + entry->special = 0; return; } @@ -408,6 +409,7 @@ find_command(const char *name, struct cmdentry *entry, int act, cmdp = &loc_cmd; cmdp->cmdtype = CMDNORMAL; cmdp->param.index = idx; + cmdp->special = 0; INTON; goto success; } @@ -420,6 +422,7 @@ find_command(const char *name, struct cmdentry *entry, int act, } entry->cmdtype = CMDUNKNOWN; entry->u.index = 0; + entry->special = 0; return; success: @@ -588,6 +591,7 @@ addcmdentry(const char *name, struct cmdentry *entry) } cmdp->cmdtype = entry->cmdtype; cmdp->param = entry->u; + cmdp->special = entry->special; INTON; } @@ -604,6 +608,7 @@ defun(const char *name, union node *func) INTOFF; entry.cmdtype = CMDFUNCTION; entry.u.func = copyfunc(func); + entry.special = 0; addcmdentry(name, &entry); INTON; } diff --git a/external/sh/expand.c b/external/sh/expand.c index 4fee21ce..03d7a34e 100644 --- a/external/sh/expand.c +++ b/external/sh/expand.c @@ -40,7 +40,7 @@ static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/expand.c 293002 2015-12-31 20:15:57Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/expand.c 296429 2016-03-06 17:24:02Z jilles $"); #include <sys/types.h> #include <sys/time.h> @@ -91,13 +91,13 @@ struct worddest { static char *expdest; /* output of current string */ static struct nodelist *argbackq; /* list of back quote expressions */ -static char *argstr(char *, int, struct worddest *); -static char *exptilde(char *, int); -static char *expari(char *, int, struct worddest *); +static const char *argstr(const char *, int, struct worddest *); +static const char *exptilde(const char *, int); +static const char *expari(const char *, int, struct worddest *); static void expbackq(union node *, int, int, struct worddest *); -static void subevalvar_trim(char *, int, int, int); -static int subevalvar_misc(char *, const char *, int, int, int); -static char *evalvar(char *, int, struct worddest *); +static void subevalvar_trim(const char *, int, int, int); +static int subevalvar_misc(const char *, const char *, int, int, int); +static const char *evalvar(const char *, int, struct worddest *); static int varisset(const char *, int); static void strtodest(const char *, int, int, int, struct worddest *); static void reprocess(int, int, int, int, struct worddest *); @@ -262,8 +262,8 @@ expandarg(union node *arg, struct arglist *arglist, int flag) * * If EXP_SPLIT is set, dst receives any complete words produced. */ -static char * -argstr(char *p, int flag, struct worddest *dst) +static const char * +argstr(const char *p, int flag, struct worddest *dst) { char c; int quotes = flag & (EXP_GLOB | EXP_CASE); /* do CTLESC */ @@ -352,12 +352,15 @@ argstr(char *p, int flag, struct worddest *dst) * Perform tilde expansion, placing the result in the stack string and * returning the next position in the input string to process. */ -static char * -exptilde(char *p, int flag) +static const char * +exptilde(const char *p, int flag) { - char c, *startp = p; + char c; + const char *startp = p; + const char *user; struct passwd *pw; char *home; + int len; for (;;) { c = *p; @@ -377,14 +380,17 @@ exptilde(char *p, int flag) case '\0': case '/': case CTLENDVAR: - *p = '\0'; - if (*(startp+1) == '\0') { + len = p - startp - 1; + STPUTBIN(startp + 1, len, expdest); + STACKSTRNUL(expdest); + user = expdest - len; + if (*user == '\0') { home = lookupvar("HOME"); } else { - pw = getpwnam(startp+1); + pw = getpwnam(user); home = pw != NULL ? pw->pw_dir : NULL; } - *p = c; + STADJUST(-len, expdest); if (home == NULL || *home == '\0') return (startp); strtodest(home, flag, VSNORMAL, 1, NULL); @@ -398,8 +404,8 @@ exptilde(char *p, int flag) /* * Expand arithmetic expression. */ -static char * -expari(char *p, int flag, struct worddest *dst) +static const char * +expari(const char *p, int flag, struct worddest *dst) { char *q, *start; arith_t result; @@ -457,7 +463,6 @@ expbackq(union node *cmd, int quoted, int flag, struct worddest *dst) argbackq = saveargbackq; p = in.buf; - lastc = '\0'; nnl = 0; if (!quoted && flag & EXP_SPLIT) ifs = ifsset() ? ifsval() : " \t\n"; @@ -532,7 +537,7 @@ recordleft(const char *str, const char *loc, char *startp) } static void -subevalvar_trim(char *p, int strloc, int subtype, int startloc) +subevalvar_trim(const char *p, int strloc, int subtype, int startloc) { char *startp; char *loc = NULL; @@ -606,7 +611,7 @@ subevalvar_trim(char *p, int strloc, int subtype, int startloc) static int -subevalvar_misc(char *p, const char *var, int subtype, int startloc, +subevalvar_misc(const char *p, const char *var, int subtype, int startloc, int varflags) { char *startp; @@ -645,12 +650,12 @@ subevalvar_misc(char *p, const char *var, int subtype, int startloc, * input string. */ -static char * -evalvar(char *p, int flag, struct worddest *dst) +static const char * +evalvar(const char *p, int flag, struct worddest *dst) { int subtype; int varflags; - char *var; + const char *var; const char *val; int patloc; int c; @@ -951,8 +956,8 @@ varvalue(const char *name, int quoted, int subtype, int flag, case '-': p = buf; for (i = 0 ; i < NSHORTOPTS ; i++) { - if (optlist[i].val) - *p++ = optlist[i].letter; + if (optval[i]) + *p++ = optletter[i]; } *p = '\0'; strtodest(buf, flag, subtype, quoted, dst); @@ -1282,7 +1287,7 @@ patmatch(const char *pattern, const char *string) if (wc == 0) goto backtrack; } else - wc = (unsigned char)*q++; + q++; break; case '*': c = *p; diff --git a/external/sh/histedit.c b/external/sh/histedit.c index dad46722..e2017b0e 100644 --- a/external/sh/histedit.c +++ b/external/sh/histedit.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/histedit.c 279508 2015-03-01 22:32:23Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/histedit.c 296429 2016-03-06 17:24:02Z jilles $"); #include <sys/param.h> #include <limits.h> @@ -359,7 +359,7 @@ histcmd(int argc, char **argv __unused) * cursor, set it back to the current * entry. */ - retval = history(hist, &he, + history(hist, &he, H_NEXT_EVENT, oldhistnum); } } else diff --git a/external/sh/input.c b/external/sh/input.c index aeb3590e..2a4dc18d 100644 --- a/external/sh/input.c +++ b/external/sh/input.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/input.c 271593 2014-09-14 16:46:30Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/input.c 295937 2016-02-23 22:44:01Z jilles $"); #include <stdio.h> /* defines BUFSIZ */ #include <fcntl.h> @@ -195,8 +195,7 @@ retry: int preadbuffer(void) { - char *p, *q; - int more; + char *p, *q, *r, *end; char savec; while (parsefile->strpush) { @@ -213,8 +212,6 @@ preadbuffer(void) } if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) return PEOF; - flushout(&output); - flushout(&errout); again: if (parselleft <= 0) { @@ -224,34 +221,32 @@ again: } } - q = p = parsefile->buf + (parsenextc - parsefile->buf); - - /* delete nul characters */ - for (more = 1; more;) { - switch (*p) { - case '\0': - p++; /* Skip nul */ - goto check; - - case '\n': - parsenleft = q - parsenextc; - more = 0; /* Stop processing here */ - break; - - default: - break; - } - - *q++ = *p++; -check: - if (--parselleft <= 0) { - parsenleft = q - parsenextc - 1; - if (parsenleft < 0) - goto again; - *q = '\0'; - more = 0; + p = parsefile->buf + (parsenextc - parsefile->buf); + end = p + parselleft; + *end = '\0'; + q = strchrnul(p, '\n'); + if (q != end && *q == '\0') { + /* delete nul characters */ + for (r = q; q != end; q++) { + if (*q != '\0') + *r++ = *q; } + parselleft -= end - r; + if (parselleft == 0) + goto again; + end = p + parselleft; + *end = '\0'; + q = strchrnul(p, '\n'); + } + if (q == end) { + parsenleft = parselleft; + parselleft = 0; + } else /* *q == '\n' */ { + q++; + parsenleft = q - parsenextc; + parselleft -= parsenleft; } + parsenleft--; savec = *q; *q = '\0'; diff --git a/external/sh/jobs.c b/external/sh/jobs.c index 1a130fc8..28baa0c7 100644 --- a/external/sh/jobs.c +++ b/external/sh/jobs.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/jobs.c 281982 2015-04-25 13:34:25Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/jobs.c 296326 2016-03-02 21:24:46Z jilles $"); #include <sys/ioctl.h> #include <sys/param.h> @@ -322,8 +322,8 @@ static void showjob(struct job *jp, int mode) { char s[64]; - char statestr[64]; - const char *sigstr; + char statebuf[16]; + const char *statestr, *coredump; struct procstat *ps; struct job *j; int col, curr, i, jobno, prev, procno; @@ -339,9 +339,10 @@ showjob(struct job *jp, int mode) prev = j - jobtab + 1; } #endif + coredump = ""; ps = jp->ps + jp->nprocs - 1; if (jp->state == 0) { - strcpy(statestr, "Running"); + statestr = "Running"; #if JOBS } else if (jp->state == JOBSTOPPED) { while (!WIFSTOPPED(ps->status) && ps > jp->ps) @@ -350,27 +351,25 @@ showjob(struct job *jp, int mode) i = WSTOPSIG(ps->status); else i = -1; - sigstr = strsignal(i); - if (sigstr != NULL) - strcpy(statestr, sigstr); - else - strcpy(statestr, "Suspended"); + statestr = strsignal(i); + if (statestr == NULL) + statestr = "Suspended"; #endif } else if (WIFEXITED(ps->status)) { if (WEXITSTATUS(ps->status) == 0) - strcpy(statestr, "Done"); - else - fmtstr(statestr, 64, "Done(%d)", + statestr = "Done"; + else { + fmtstr(statebuf, sizeof(statebuf), "Done(%d)", WEXITSTATUS(ps->status)); + statestr = statebuf; + } } else { i = WTERMSIG(ps->status); - sigstr = strsignal(i); - if (sigstr != NULL) - strcpy(statestr, sigstr); - else - strcpy(statestr, "Unknown signal"); + statestr = strsignal(i); + if (statestr == NULL) + statestr = "Unknown signal"; if (WCOREDUMP(ps->status)) - strcat(statestr, " (core dumped)"); + coredump = " (core dumped)"; } for (ps = jp->ps ; procno > 0 ; ps++, procno--) { /* for each process */ @@ -399,7 +398,8 @@ showjob(struct job *jp, int mode) } if (ps == jp->ps) { out1str(statestr); - col += strlen(statestr); + out1str(coredump); + col += strlen(statestr) + strlen(coredump); } do { out1c(' '); diff --git a/external/sh/miscbltin.c b/external/sh/miscbltin.c index f9042a85..d7ec6a2f 100644 --- a/external/sh/miscbltin.c +++ b/external/sh/miscbltin.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/miscbltin.c 287308 2015-08-30 17:24:22Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/miscbltin.c 296723 2016-03-12 14:54:34Z kib $"); /* * Miscellaneous builtins. @@ -414,6 +414,9 @@ static const struct limits limits[] = { #ifdef RLIMIT_KQUEUES { "kqueues", (char *)0, RLIMIT_KQUEUES, 1, 'k' }, #endif +#ifdef RLIMIT_UMTXP + { "umtxp", (char *)0, RLIMIT_UMTXP, 1, 'o' }, +#endif { (char *) 0, (char *)0, 0, 0, '\0' } }; @@ -449,7 +452,7 @@ ulimitcmd(int argc __unused, char **argv __unused) struct rlimit limit; what = 'f'; - while ((optc = nextopt("HSatfdsmcnuvlbpwk")) != '\0') + while ((optc = nextopt("HSatfdsmcnuvlbpwko")) != '\0') switch (optc) { case 'H': how = HARD; diff --git a/external/sh/options.c b/external/sh/options.c index 6b239152..25056b20 100644 --- a/external/sh/options.c +++ b/external/sh/options.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/options.c 287296 2015-08-29 19:41:47Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/options.c 296577 2016-03-09 21:00:57Z jilles $"); #include <signal.h> #include <unistd.h> @@ -74,6 +74,7 @@ static void options(int); static void minus_o(char *, int); static void setoption(int, int); static void setoptionbyindex(int, int); +static void setparam(int, char **); static int getopts(char *, char *, char **, char ***, char **); @@ -91,7 +92,7 @@ procargs(int argc, char **argv) if (argc > 0) argptr++; for (i = 0; i < NOPTS; i++) - optlist[i].val = 2; + optval[i] = 2; privileged = (getuid() != geteuid() || getgid() != getegid()); options(1); if (*argptr == NULL && minusc == NULL) @@ -104,8 +105,8 @@ procargs(int argc, char **argv) if (mflag == 2) mflag = iflag; for (i = 0; i < NOPTS; i++) - if (optlist[i].val == 2) - optlist[i].val = 0; + if (optval[i] == 2) + optval[i] = 0; arg0 = argv[0]; if (sflag == 0 && minusc == NULL) { scriptname = *argptr++; @@ -224,7 +225,7 @@ end_options1: end_options2: if (!cmdline) { if (*argptr == NULL) - setparam(argptr); + setparam(0, argptr); return; } @@ -250,26 +251,29 @@ static void minus_o(char *name, int val) { int i; + const unsigned char *on; + size_t len; if (name == NULL) { if (val) { /* "Pretty" output. */ out1str("Current option settings\n"); - for (i = 0; i < NOPTS; i++) - out1fmt("%-16s%s\n", optlist[i].name, - optlist[i].val ? "on" : "off"); + for (i = 0, on = optname; i < NOPTS; i++, on += *on + 1) + out1fmt("%-16.*s%s\n", *on, on + 1, + optval[i] ? "on" : "off"); } else { /* Output suitable for re-input to shell. */ - for (i = 0; i < NOPTS; i++) - out1fmt("%s %co %s%s", + for (i = 0, on = optname; i < NOPTS; i++, on += *on + 1) + out1fmt("%s %co %.*s%s", i % 6 == 0 ? "set" : "", - optlist[i].val ? '-' : '+', - optlist[i].name, + optval[i] ? '-' : '+', + *on, on + 1, i % 6 == 5 || i == NOPTS - 1 ? "\n" : ""); } } else { - for (i = 0; i < NOPTS; i++) - if (equal(name, optlist[i].name)) { + len = strlen(name); + for (i = 0, on = optname; i < NOPTS; i++, on += *on + 1) + if (*on == len && memcmp(on + 1, name, len) == 0) { setoptionbyindex(i, val); return; } @@ -281,18 +285,18 @@ minus_o(char *name, int val) static void setoptionbyindex(int idx, int val) { - if (optlist[idx].letter == 'p' && !val && privileged) { + if (&optval[idx] == &privileged && !val && privileged) { if (setgid(getgid()) == -1) error("setgid"); if (setuid(getuid()) == -1) error("setuid"); } - optlist[idx].val = val; + optval[idx] = val; if (val) { /* #%$ hack for ksh semantics */ - if (optlist[idx].letter == 'V') + if (&optval[idx] == &Vflag) Eflag = 0; - else if (optlist[idx].letter == 'E') + else if (&optval[idx] == &Eflag) Vflag = 0; } } @@ -303,7 +307,7 @@ setoption(int flag, int val) int i; for (i = 0; i < NSHORTOPTS; i++) - if (optlist[i].letter == flag) { + if (optletter[i] == flag) { setoptionbyindex(i, val); return; } @@ -315,22 +319,20 @@ setoption(int flag, int val) * Set the shell parameters. */ -void -setparam(char **argv) +static void +setparam(int argc, char **argv) { char **newparam; char **ap; - int nparam; - for (nparam = 0 ; argv[nparam] ; nparam++); - ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); + ap = newparam = ckmalloc((argc + 1) * sizeof *ap); while (*argv) { *ap++ = savestr(*argv++); } *ap = NULL; freeparam(&shellparam); shellparam.malloc = 1; - shellparam.nparam = nparam; + shellparam.nparam = argc; shellparam.p = newparam; shellparam.optp = NULL; shellparam.reset = 1; @@ -368,8 +370,7 @@ freeparam(struct shparam *param) int shiftcmd(int argc, char **argv) { - int n; - char **ap1, **ap2; + int i, n; n = 1; if (argc > 1) @@ -378,12 +379,11 @@ shiftcmd(int argc, char **argv) return 1; INTOFF; shellparam.nparam -= n; - for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { - if (shellparam.malloc) - ckfree(*ap1); - } - ap2 = shellparam.p; - while ((*ap2++ = *ap1++) != NULL); + if (shellparam.malloc) + for (i = 0; i < n; i++) + ckfree(shellparam.p[i]); + memmove(shellparam.p, shellparam.p + n, + (shellparam.nparam + 1) * sizeof(shellparam.p[0])); shellparam.reset = 1; INTON; return 0; @@ -404,7 +404,7 @@ setcmd(int argc, char **argv) options(0); optschanged(); if (*argptr != NULL) { - setparam(argptr); + setparam(argc - (argptr - argv), argptr); } INTON; return 0; diff --git a/external/sh/options.h b/external/sh/options.h index 851cf75c..8910df9a 100644 --- a/external/sh/options.h +++ b/external/sh/options.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)options.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/options.h 287296 2015-08-29 19:41:47Z jilles $ + * $FreeBSD: head/bin/sh/options.h 294348 2016-01-19 22:41:26Z jilles $ */ struct shparam { @@ -45,60 +45,57 @@ struct shparam { -#define eflag optlist[0].val -#define fflag optlist[1].val -#define Iflag optlist[2].val -#define iflag optlist[3].val -#define mflag optlist[4].val -#define nflag optlist[5].val -#define sflag optlist[6].val -#define xflag optlist[7].val -#define vflag optlist[8].val -#define Vflag optlist[9].val -#define Eflag optlist[10].val -#define Cflag optlist[11].val -#define aflag optlist[12].val -#define bflag optlist[13].val -#define uflag optlist[14].val -#define privileged optlist[15].val -#define Tflag optlist[16].val -#define Pflag optlist[17].val -#define hflag optlist[18].val -#define nologflag optlist[19].val +#define eflag optval[0] +#define fflag optval[1] +#define Iflag optval[2] +#define iflag optval[3] +#define mflag optval[4] +#define nflag optval[5] +#define sflag optval[6] +#define xflag optval[7] +#define vflag optval[8] +#define Vflag optval[9] +#define Eflag optval[10] +#define Cflag optval[11] +#define aflag optval[12] +#define bflag optval[13] +#define uflag optval[14] +#define privileged optval[15] +#define Tflag optval[16] +#define Pflag optval[17] +#define hflag optval[18] +#define nologflag optval[19] #define NSHORTOPTS 19 #define NOPTS 20 -struct optent { - const char *name; - const char letter; - char val; -}; - -extern struct optent optlist[NOPTS]; +extern char optval[NOPTS]; +extern const char optletter[NSHORTOPTS]; #ifdef DEFINE_OPTIONS -struct optent optlist[NOPTS] = { - { "errexit", 'e', 0 }, - { "noglob", 'f', 0 }, - { "ignoreeof", 'I', 0 }, - { "interactive",'i', 0 }, - { "monitor", 'm', 0 }, - { "noexec", 'n', 0 }, - { "stdin", 's', 0 }, - { "xtrace", 'x', 0 }, - { "verbose", 'v', 0 }, - { "vi", 'V', 0 }, - { "emacs", 'E', 0 }, - { "noclobber", 'C', 0 }, - { "allexport", 'a', 0 }, - { "notify", 'b', 0 }, - { "nounset", 'u', 0 }, - { "privileged", 'p', 0 }, - { "trapsasync", 'T', 0 }, - { "physical", 'P', 0 }, - { "trackall", 'h', 0 }, - { "nolog", '\0', 0 }, -}; +char optval[NOPTS]; +const char optletter[NSHORTOPTS] = "efIimnsxvVECabupTPh"; +static const unsigned char optname[] = + "\007errexit" + "\006noglob" + "\011ignoreeof" + "\013interactive" + "\007monitor" + "\006noexec" + "\005stdin" + "\006xtrace" + "\007verbose" + "\002vi" + "\005emacs" + "\011noclobber" + "\011allexport" + "\006notify" + "\007nounset" + "\012privileged" + "\012trapsasync" + "\010physical" + "\010trackall" + "\005nolog" +; #endif @@ -111,7 +108,6 @@ extern char *nextopt_optptr; /* used by nextopt */ void procargs(int, char **); void optschanged(void); -void setparam(char **); void freeparam(struct shparam *); int nextopt(const char *); void getoptsreset(const char *); diff --git a/external/sh/parser.c b/external/sh/parser.c index ecfcb1fe..81079b40 100644 --- a/external/sh/parser.c +++ b/external/sh/parser.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/parser.c 288430 2015-09-30 21:32:29Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/parser.c 296327 2016-03-02 22:52:54Z jilles $"); #include <stdlib.h> #include <unistd.h> @@ -1671,7 +1671,7 @@ varname: c = pgetc_linecont(); } while (is_digit(c)); } else { - STPUTC(c, out); + USTPUTC(c, out); c = pgetc_linecont(); } } else if (is_special(c)) { @@ -1930,6 +1930,8 @@ static void setprompt(int which) { whichprompt = which; + if (which == 0) + return; #ifndef NO_HISTORY if (!el) diff --git a/external/sh/redir.c b/external/sh/redir.c index 0c3653e5..d0b4535b 100644 --- a/external/sh/redir.c +++ b/external/sh/redir.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/redir.c 272575 2014-10-05 21:51:36Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/redir.c 295085 2016-01-30 21:21:25Z jilles $"); #include <sys/types.h> #include <sys/stat.h> @@ -70,6 +70,7 @@ struct redirtab { struct redirtab *next; int renamed[10]; int fd0_redirected; + unsigned int empty_redirs; }; @@ -82,6 +83,9 @@ static struct redirtab *redirlist; */ static int fd0_redirected = 0; +/* Number of redirtabs that have not been allocated. */ +static unsigned int empty_redirs = 0; + static void openredirect(union node *, char[10 ]); static int openhere(union node *); @@ -115,12 +119,17 @@ redirect(union node *redir, int flags) memory[i] = 0; memory[1] = flags & REDIR_BACKQ; if (flags & REDIR_PUSH) { - sv = ckmalloc(sizeof (struct redirtab)); - for (i = 0 ; i < 10 ; i++) - sv->renamed[i] = EMPTY; - sv->fd0_redirected = fd0_redirected; - sv->next = redirlist; - redirlist = sv; + empty_redirs++; + if (redir != NULL) { + sv = ckmalloc(sizeof (struct redirtab)); + for (i = 0 ; i < 10 ; i++) + sv->renamed[i] = EMPTY; + sv->fd0_redirected = fd0_redirected; + sv->empty_redirs = empty_redirs - 1; + sv->next = redirlist; + redirlist = sv; + empty_redirs = 0; + } } for (n = redir ; n ; n = n->nfile.next) { fd = n->nfile.fd; @@ -303,6 +312,12 @@ popredir(void) struct redirtab *rp = redirlist; int i; + INTOFF; + if (empty_redirs > 0) { + empty_redirs--; + INTON; + return; + } for (i = 0 ; i < 10 ; i++) { if (rp->renamed[i] != EMPTY) { if (rp->renamed[i] >= 0) { @@ -313,8 +328,8 @@ popredir(void) } } } - INTOFF; fd0_redirected = rp->fd0_redirected; + empty_redirs = rp->empty_redirs; redirlist = rp->next; ckfree(rp); INTON; diff --git a/external/sh/test.c b/external/sh/test.c index c92bb088..05d0631f 100644 --- a/external/sh/test.c +++ b/external/sh/test.c @@ -15,7 +15,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/test/test.c 259017 2013-12-05 22:53:32Z jilles $"); +__FBSDID("$FreeBSD: head/bin/test/test.c 295082 2016-01-30 19:59:58Z jilles $"); #include <sys/types.h> #include <sys/stat.h> @@ -120,51 +120,53 @@ enum token { #define TOKEN_TYPE(token) ((token) & 0xff00) -static struct t_op { - char op_text[4]; +static const struct t_op { + char op_text[2]; short op_num; -} const ops [] = { - {"-r", FILRD}, - {"-w", FILWR}, - {"-x", FILEX}, - {"-e", FILEXIST}, - {"-f", FILREG}, - {"-d", FILDIR}, - {"-c", FILCDEV}, - {"-b", FILBDEV}, - {"-p", FILFIFO}, - {"-u", FILSUID}, - {"-g", FILSGID}, - {"-k", FILSTCK}, - {"-s", FILGZ}, - {"-t", FILTT}, - {"-z", STREZ}, - {"-n", STRNZ}, - {"-h", FILSYM}, /* for backwards compat */ - {"-O", FILUID}, - {"-G", FILGID}, - {"-L", FILSYM}, - {"-S", FILSOCK}, +} ops1[] = { {"=", STREQ}, - {"==", STREQ}, - {"!=", STRNE}, {"<", STRLT}, {">", STRGT}, - {"-eq", INTEQ}, - {"-ne", INTNE}, - {"-ge", INTGE}, - {"-gt", INTGT}, - {"-le", INTLE}, - {"-lt", INTLT}, - {"-nt", FILNT}, - {"-ot", FILOT}, - {"-ef", FILEQ}, {"!", UNOT}, - {"-a", BAND}, - {"-o", BOR}, {"(", LPAREN}, {")", RPAREN}, - {"", 0} +}, opsm1[] = { + {"r", FILRD}, + {"w", FILWR}, + {"x", FILEX}, + {"e", FILEXIST}, + {"f", FILREG}, + {"d", FILDIR}, + {"c", FILCDEV}, + {"b", FILBDEV}, + {"p", FILFIFO}, + {"u", FILSUID}, + {"g", FILSGID}, + {"k", FILSTCK}, + {"s", FILGZ}, + {"t", FILTT}, + {"z", STREZ}, + {"n", STRNZ}, + {"h", FILSYM}, /* for backwards compat */ + {"O", FILUID}, + {"G", FILGID}, + {"L", FILSYM}, + {"S", FILSOCK}, + {"a", BAND}, + {"o", BOR}, +}, ops2[] = { + {"==", STREQ}, + {"!=", STRNE}, +}, opsm2[] = { + {"eq", INTEQ}, + {"ne", INTNE}, + {"ge", INTGE}, + {"gt", INTGT}, + {"le", INTLE}, + {"lt", INTLT}, + {"nt", FILNT}, + {"ot", FILOT}, + {"ef", FILEQ}, }; static int nargc; @@ -416,35 +418,71 @@ filstat(char *nm, enum token mode) } } -static enum token -t_lex(char *s) +static int +find_op_1char(const struct t_op *op, const struct t_op *end, const char *s) { - struct t_op const *op = ops; + char c; - if (s == 0) { - return EOI; + c = s[0]; + while (op != end) { + if (c == *op->op_text) + return op->op_num; + op++; } - while (*op->op_text) { - if (strcmp(s, op->op_text) == 0) { - if (((TOKEN_TYPE(op->op_num) == UNOP || - TOKEN_TYPE(op->op_num) == BUNOP) - && isunopoperand()) || - (op->op_num == LPAREN && islparenoperand()) || - (op->op_num == RPAREN && isrparenoperand())) - break; + return OPERAND; +} + +static int +find_op_2char(const struct t_op *op, const struct t_op *end, const char *s) +{ + while (op != end) { + if (s[0] == op->op_text[0] && s[1] == op->op_text[1]) return op->op_num; - } op++; } return OPERAND; } static int +find_op(const char *s) +{ + if (s[0] == '\0') + return OPERAND; + else if (s[1] == '\0') + return find_op_1char(ops1, (&ops1)[1], s); + else if (s[2] == '\0') + return s[0] == '-' ? find_op_1char(opsm1, (&opsm1)[1], s + 1) : + find_op_2char(ops2, (&ops2)[1], s); + else if (s[3] == '\0') + return s[0] == '-' ? find_op_2char(opsm2, (&opsm2)[1], s + 1) : + OPERAND; + else + return OPERAND; +} + +static enum token +t_lex(char *s) +{ + int num; + + if (s == 0) { + return EOI; + } + num = find_op(s); + if (((TOKEN_TYPE(num) == UNOP || TOKEN_TYPE(num) == BUNOP) + && isunopoperand()) || + (num == LPAREN && islparenoperand()) || + (num == RPAREN && isrparenoperand())) + return OPERAND; + return num; +} + +static int isunopoperand(void) { - struct t_op const *op = ops; char *s; char *t; + int num; if (nargc == 1) return 1; @@ -452,20 +490,16 @@ isunopoperand(void) if (nargc == 2) return parenlevel == 1 && strcmp(s, ")") == 0; t = *(t_wp + 2); - while (*op->op_text) { - if (strcmp(s, op->op_text) == 0) - return TOKEN_TYPE(op->op_num) == BINOP && - (parenlevel == 0 || t[0] != ')' || t[1] != '\0'); - op++; - } - return 0; + num = find_op(s); + return TOKEN_TYPE(num) == BINOP && + (parenlevel == 0 || t[0] != ')' || t[1] != '\0'); } static int islparenoperand(void) { - struct t_op const *op = ops; char *s; + int num; if (nargc == 1) return 1; @@ -474,12 +508,8 @@ islparenoperand(void) return parenlevel == 1 && strcmp(s, ")") == 0; if (nargc != 3) return 0; - while (*op->op_text) { - if (strcmp(s, op->op_text) == 0) - return TOKEN_TYPE(op->op_num) == BINOP; - op++; - } - return 0; + num = find_op(s); + return TOKEN_TYPE(num) == BINOP; } static int diff --git a/external/sh/var.c b/external/sh/var.c index a204926c..1a34c72a 100644 --- a/external/sh/var.c +++ b/external/sh/var.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/var.c 292360 2015-12-16 20:33:47Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/var.c 294593 2016-01-22 20:10:08Z jilles $"); #include <unistd.h> #include <stdlib.h> @@ -754,8 +754,8 @@ mklocal(char *name) INTOFF; lvp = ckmalloc(sizeof (struct localvar)); if (name[0] == '-' && name[1] == '\0') { - lvp->text = ckmalloc(sizeof optlist); - memcpy(lvp->text, optlist, sizeof optlist); + lvp->text = ckmalloc(sizeof optval); + memcpy(lvp->text, optval, sizeof optval); vp = NULL; } else { vp = find_var(name, &vpp, NULL); @@ -791,22 +791,34 @@ poplocalvars(void) { struct localvar *lvp; struct var *vp; + int islocalevar; INTOFF; while ((lvp = localvars) != NULL) { localvars = lvp->next; vp = lvp->vp; if (vp == NULL) { /* $- saved */ - memcpy(optlist, lvp->text, sizeof optlist); + memcpy(optval, lvp->text, sizeof optval); ckfree(lvp->text); optschanged(); } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { + vp->flags &= ~VREADONLY; (void)unsetvar(vp->text); } else { + islocalevar = (vp->flags | lvp->flags) & VEXPORT && + localevar(lvp->text); if ((vp->flags & VTEXTFIXED) == 0) ckfree(vp->text); vp->flags = lvp->flags; vp->text = lvp->text; + if (vp->func) + (*vp->func)(vp->text + vp->name_len + 1); + if (islocalevar) { + change_env(vp->text, vp->flags & VEXPORT && + (vp->flags & VUNSET) == 0); + setlocale(LC_ALL, ""); + updatecharset(); + } } ckfree(lvp); } |