diff options
author | Bryan Drewery <bryan@shatow.net> | 2021-10-27 18:45:44 +0300 |
---|---|---|
committer | Bryan Drewery <bryan@shatow.net> | 2021-11-18 16:13:45 +0300 |
commit | 3f177434d4f5ff6c4aeeecb0206628ab66fb00a0 (patch) | |
tree | 68c0eeb70f3d0bdf3eb3e3fb75b75dfb6548e3b4 | |
parent | ae641ed4ff326fb338aff781506e4b06ead65bfc (diff) |
Update sh from git main 72f750dc7c732
57 files changed, 337 insertions, 109 deletions
diff --git a/external/patches/sh/builtin-intoff-leak.patch b/external/patches/sh/builtin-intoff-leak.patch index b2f315e5..3462eaa8 100644 --- a/external/patches/sh/builtin-intoff-leak.patch +++ b/external/patches/sh/builtin-intoff-leak.patch @@ -4,7 +4,7 @@ index 362fd798d..49fa3ebf6 100644 +++ external/sh/eval.c @@ -38,6 +38,7 @@ static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; #include <sys/cdefs.h> - __FBSDID("$FreeBSD: head/bin/sh/eval.c 340284 2018-11-09 14:58:24Z jilles $"); + __FBSDID("$FreeBSD$"); +#include <assert.h> #include <paths.h> @@ -20,7 +20,7 @@ index 362fd798d..49fa3ebf6 100644 /* First expand the arguments. */ TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags)); -@@ -1104,8 +1108,19 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) +@@ -1104,8 +1108,18 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) argptr = argv + 1; nextopt_optptr = NULL; /* initialize nextopt */ builtin_flags = flags; @@ -31,8 +31,7 @@ index 362fd798d..49fa3ebf6 100644 flushall(); +#ifndef NDEBUG + if (suppressint > savesuppressint && -+ cmdentry.u.index != DOTCMD && -+ cmdentry.u.index != CRITICAL_STARTCMD) { ++ cmdentry.u.index != DOTCMD) { + error("leaked INTOFF/INTON %d != %ld", + savesuppressint, suppressint); + } diff --git a/external/patches/sh/builtin-read-timeout-setvar.patch b/external/patches/sh/builtin-read-timeout-setvar.patch deleted file mode 100644 index bfa4a817..00000000 --- a/external/patches/sh/builtin-read-timeout-setvar.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git external/sh/miscbltin.c external/sh/miscbltin.c -index bd4164811..d52433047 100644 ---- external/sh/miscbltin.c -+++ external/sh/miscbltin.c -@@ -231,6 +231,8 @@ readcmd(int argc __unused, char **argv __unused) - * If there's nothing ready, return an error. - */ - if (status <= 0) { -+ while (*ap != NULL) -+ setvar(*ap++, "", 0); - sig = pendingsig; - return (128 + (sig != 0 ? sig : SIGALRM)); - } diff --git a/external/sh/alias.c b/external/sh/alias.c index a8fe82c9..bbcf5fbe 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 317039 2017-04-16 22:10:02Z jilles $"); +__FBSDID("$FreeBSD$"); #include <stdlib.h> #include "shell.h" diff --git a/external/sh/alias.h b/external/sh/alias.h index e08a9e8c..92de705b 100644 --- a/external/sh/alias.h +++ b/external/sh/alias.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)alias.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/alias.h 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ #define ALIASINUSE 1 diff --git a/external/sh/arith.h b/external/sh/arith.h index 9c2ef394..569d0c58 100644 --- a/external/sh/arith.h +++ b/external/sh/arith.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * @(#)arith.h 1.1 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/arith.h 315511 2017-03-18 20:41:07Z jilles $ + * $FreeBSD$ */ #include "shell.h" diff --git a/external/sh/arith_yacc.c b/external/sh/arith_yacc.c index 8ff1f63c..a08163bd 100644 --- a/external/sh/arith_yacc.c +++ b/external/sh/arith_yacc.c @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/arith_yacc.c 343981 2019-02-10 22:23:05Z jilles $"); +__FBSDID("$FreeBSD$"); #include <limits.h> #include <errno.h> diff --git a/external/sh/arith_yacc.h b/external/sh/arith_yacc.h index 9b9364d5..7fdd99b7 100644 --- a/external/sh/arith_yacc.h +++ b/external/sh/arith_yacc.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/bin/sh/arith_yacc.h 343981 2019-02-10 22:23:05Z jilles $ + * $FreeBSD$ */ #define ARITH_ASS 1 diff --git a/external/sh/arith_yylex.c b/external/sh/arith_yylex.c index e48af6bd..9f320dbc 100644 --- a/external/sh/arith_yylex.c +++ b/external/sh/arith_yylex.c @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/arith_yylex.c 343981 2019-02-10 22:23:05Z jilles $"); +__FBSDID("$FreeBSD$"); #include <ctype.h> #include <errno.h> diff --git a/external/sh/bltin/bltin.h b/external/sh/bltin/bltin.h index b8c20875..81498958 100644 --- a/external/sh/bltin/bltin.h +++ b/external/sh/bltin/bltin.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)bltin.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/bltin/bltin.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ /* diff --git a/external/sh/bltin/echo.c b/external/sh/bltin/echo.c index 1bb64c6d..e8046c76 100644 --- a/external/sh/bltin/echo.c +++ b/external/sh/bltin/echo.c @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/bltin/echo.c 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); /* * Echo command. diff --git a/external/sh/builtins.def b/external/sh/builtins.def index b493f436..f38af0f2 100644 --- a/external/sh/builtins.def +++ b/external/sh/builtins.def @@ -32,7 +32,7 @@ # SUCH DAMAGE. # # @(#)builtins.def 8.4 (Berkeley) 5/4/95 -# $FreeBSD: head/bin/sh/builtins.def 360210 2020-04-22 21:45:43Z jilles $ +# $FreeBSD$ # # This file lists all the builtin commands. The first column is the name diff --git a/external/sh/cd.c b/external/sh/cd.c index 83ff140c..66eee00b 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 356251 2020-01-01 12:06:37Z jilles $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/stat.h> diff --git a/external/sh/cd.h b/external/sh/cd.h index 0745d97a..a82d6370 100644 --- a/external/sh/cd.h +++ b/external/sh/cd.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/bin/sh/cd.h 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ void pwd_init(int); diff --git a/external/sh/error.c b/external/sh/error.c index efa4cb4d..ade63b71 100644 --- a/external/sh/error.c +++ b/external/sh/error.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/error.c 340284 2018-11-09 14:58:24Z jilles $"); +__FBSDID("$FreeBSD$"); /* * Errors and exceptions. @@ -74,7 +74,7 @@ void verrorwithstatus(int, const char *, va_list) __printf0like(2, 0) __dead2; * just do a longjmp to the exception handler. The type of exception is * stored in the global variable "exception". * - * Interrupts are disabled; they should be reenabled when the exception is + * Interrupts are disabled; they should be re-enabled when the exception is * caught. */ diff --git a/external/sh/error.h b/external/sh/error.h index d6a4368b..3a79dec8 100644 --- a/external/sh/error.h +++ b/external/sh/error.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)error.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/error.h 340284 2018-11-09 14:58:24Z jilles $ + * $FreeBSD$ */ /* diff --git a/external/sh/eval.c b/external/sh/eval.c index 179381b7..44364aed 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 340284 2018-11-09 14:58:24Z jilles $"); +__FBSDID("$FreeBSD$"); #include <assert.h> #include <paths.h> @@ -904,7 +904,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) * the hash table isn't filled with items * from the temporary setting. * - * It would be better to forbit using and + * It would be better to forbid using and * updating the table while this command * runs, by the command finding mechanism * is heavily integrated with hash handling, diff --git a/external/sh/eval.h b/external/sh/eval.h index 18b39f95..d8a12eb7 100644 --- a/external/sh/eval.h +++ b/external/sh/eval.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)eval.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/eval.h 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ extern char *commandname; /* currently executing command */ diff --git a/external/sh/exec.c b/external/sh/exec.c index 9dc9f2ae..43095a25 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 365037 2020-09-01 13:19:15Z jilles $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/stat.h> @@ -418,7 +418,7 @@ find_command(const char *name, struct cmdentry *entry, int act, if (!S_ISREG(statb.st_mode)) continue; if (opt) { /* this is a %func directory */ - readcmdfile(fullname); + readcmdfile(fullname, -1 /* verify */); if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) error("%s not defined in %s", name, fullname); stunalloc(fullname); diff --git a/external/sh/exec.h b/external/sh/exec.h index 79899edb..03e7e6ab 100644 --- a/external/sh/exec.h +++ b/external/sh/exec.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)exec.h 8.3 (Berkeley) 6/8/95 - * $FreeBSD: head/bin/sh/exec.h 339822 2018-10-27 20:17:57Z jilles $ + * $FreeBSD$ */ /* values of cmdtype */ diff --git a/external/sh/expand.c b/external/sh/expand.c index 112125dd..922bf5c3 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 341164 2018-11-28 20:03:53Z jilles $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/time.h> diff --git a/external/sh/expand.h b/external/sh/expand.h index e959174e..a60ea295 100644 --- a/external/sh/expand.h +++ b/external/sh/expand.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)expand.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/expand.h 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ struct arglist { diff --git a/external/sh/histedit.c b/external/sh/histedit.c index 6c99e7ad..3c113333 100644 --- a/external/sh/histedit.c +++ b/external/sh/histedit.c @@ -36,9 +36,13 @@ 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 360139 2020-04-21 00:37:55Z bdrewery $"); +__FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/stat.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> #include <limits.h> #include <paths.h> #include <stdio.h> @@ -67,11 +71,75 @@ __FBSDID("$FreeBSD: head/bin/sh/histedit.c 360139 2020-04-21 00:37:55Z bdrewery History *hist; /* history cookie */ EditLine *el; /* editline cookie */ int displayhist; +static int savehist; static FILE *el_in, *el_out; static char *fc_replace(const char *, char *, char *); static int not_fcnumber(const char *); static int str_to_event(const char *, int); +static int comparator(const void *, const void *, void *); +static char **sh_matches(const char *, int, int); +static unsigned char sh_complete(EditLine *, int); + +static const char * +get_histfile(void) +{ + const char *histfile; + + /* don't try to save if the history size is 0 */ + if (hist == NULL || histsizeval() == 0) + return (NULL); + histfile = expandstr("${HISTFILE-${HOME-}/.sh_history}"); + + if (histfile[0] == '\0') + return (NULL); + return (histfile); +} + +void +histsave(void) +{ + HistEvent he; + char *histtmpname = NULL; + const char *histfile; + int fd; + FILE *f; + + if (!savehist || (histfile = get_histfile()) == NULL) + return; + INTOFF; + asprintf(&histtmpname, "%s.XXXXXXXXXX", histfile); + if (histtmpname == NULL) { + INTON; + return; + } + fd = mkstemp(histtmpname); + if (fd == -1 || (f = fdopen(fd, "w")) == NULL) { + free(histtmpname); + INTON; + return; + } + if (history(hist, &he, H_SAVE_FP, f) < 1 || + rename(histtmpname, histfile) == -1) + unlink(histtmpname); + fclose(f); + free(histtmpname); + INTON; + +} + +void +histload(void) +{ + const char *histfile; + HistEvent he; + + if ((histfile = get_histfile()) == NULL) + return; + errno = 0; + if (history(hist, &he, H_LOAD, histfile) != -1 || errno == ENOENT) + savehist = 1; +} /* * Set history and editing status. Called whenever the status may @@ -122,7 +190,7 @@ histedit(void) el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", - _el_fn_complete); + sh_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); @@ -137,8 +205,9 @@ bad: if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); - else if (Eflag) + else if (Eflag) { el_set(el, EL_EDITOR, "emacs"); + } el_set(el, EL_BIND, "^I", "sh-complete", NULL); el_source(el, NULL); } @@ -378,7 +447,7 @@ histcmd(int argc, char **argv __unused) editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); sprintf(editcmd, "%s %s", editor, editfile); evalstring(editcmd, 0); /* XXX - should use no JC command */ - readcmdfile(editfile); /* XXX - should read back - quick tst */ + readcmdfile(editfile, 0 /* verify */); /* XXX - should read back - quick tst */ unlink(editfile); } @@ -494,11 +563,151 @@ bindcmd(int argc, char **argv) fclose(out); + if (argc > 1 && argv[1][0] == '-' && + memchr("ve", argv[1][1], 2) != NULL) { + Vflag = argv[1][1] == 'v'; + Eflag = !Vflag; + histedit(); + } + INTON; return ret; } +/* + * Comparator function for qsort(). The use of curpos here is to skip + * characters that we already know to compare equal (common prefix). + */ +static int +comparator(const void *a, const void *b, void *thunk) +{ + size_t curpos = (intptr_t)thunk; + return (strcmp(*(char *const *)a + curpos, + *(char *const *)b + curpos)); +} + +/* + * This function is passed to libedit's fn_complete2(). The library will + * use it instead of its standard function that finds matching files in + * current directory. If we're at the start of the line, we want to look + * for available commands from all paths in $PATH. + */ +static char +**sh_matches(const char *text, int start, int end) +{ + char *free_path = NULL, *path; + const char *dirname; + char **matches = NULL; + size_t i = 0, size = 16, uniq; + size_t curpos = end - start, lcstring = -1; + + if (start > 0 || memchr("/.~", text[0], 3) != NULL) + return (NULL); + if ((free_path = path = strdup(pathval())) == NULL) + goto out; + if ((matches = malloc(size * sizeof(matches[0]))) == NULL) + goto out; + while ((dirname = strsep(&path, ":")) != NULL) { + struct dirent *entry; + DIR *dir; + int dfd; + + dir = opendir(dirname[0] == '\0' ? "." : dirname); + if (dir == NULL) + continue; + if ((dfd = dirfd(dir)) == -1) { + closedir(dir); + continue; + } + while ((entry = readdir(dir)) != NULL) { + struct stat statb; + char **rmatches; + + if (strncmp(entry->d_name, text, curpos) != 0) + continue; + if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) { + if (fstatat(dfd, entry->d_name, &statb, 0) == -1) + continue; + if (!S_ISREG(statb.st_mode)) + continue; + } else if (entry->d_type != DT_REG) + continue; + matches[++i] = strdup(entry->d_name); + if (i < size - 1) + continue; + size *= 2; + rmatches = reallocarray(matches, size, sizeof(matches[0])); + if (rmatches == NULL) { + closedir(dir); + goto out; + } + matches = rmatches; + } + closedir(dir); + } +out: + free(free_path); + if (i == 0) { + free(matches); + return (NULL); + } + uniq = 1; + if (i > 1) { + qsort_s(matches + 1, i, sizeof(matches[0]), comparator, + (void *)(intptr_t)curpos); + for (size_t k = 2; k <= i; k++) { + const char *l = matches[uniq] + curpos; + const char *r = matches[k] + curpos; + size_t common = 0; + + while (*l != '\0' && *r != '\0' && *l == *r) + (void)l++, r++, common++; + if (common < lcstring) + lcstring = common; + if (*l == *r) + free(matches[k]); + else + matches[++uniq] = matches[k]; + } + } + matches[uniq + 1] = NULL; + /* + * matches[0] is special: it's not a real matching file name but a common + * prefix for all matching names. It can't be null, unlike any other + * element of the array. When strings matches[0] and matches[1] compare + * equal and matches[2] is null that means to libedit that there is only + * a single match. It will then replace user input with possibly escaped + * string in matches[0] which is the reason to copy the full name of the + * only match. + */ + if (uniq == 1) + matches[0] = strdup(matches[1]); + else if (lcstring != (size_t)-1) + matches[0] = strndup(matches[1], curpos + lcstring); + else + matches[0] = strdup(text); + if (matches[0] == NULL) { + for (size_t k = 1; k <= uniq; k++) + free(matches[k]); + free(matches); + return (NULL); + } + return (matches); +} + +/* + * This is passed to el_set(el, EL_ADDFN, ...) so that it's possible to + * bind a key (tab by default) to execute the function. + */ +unsigned char +sh_complete(EditLine *sel, int ch __unused) +{ + return (unsigned char)fn_complete2(sel, NULL, sh_matches, + L" \t\n\"\\'`@$><=;|&{(", NULL, NULL, (size_t)100, + NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH); +} + #else #include "error.h" diff --git a/external/sh/input.c b/external/sh/input.c index db9e26e0..39332875 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 359398 2020-03-28 17:02:32Z kevans $"); +__FBSDID("$FreeBSD$"); #include <stdio.h> /* defines BUFSIZ */ #include <fcntl.h> @@ -352,17 +352,25 @@ popstring(void) /* * Set the input to take input from a file. If push is set, push the * old input onto the stack first. + * About verify: + * -1: Obey verifyflag + * 0: Do not verify + * 1: Do verify */ void -setinputfile(const char *fname, int push) +setinputfile(const char *fname, int push, int verify) { int e; int fd; int fd2; + int oflags = O_RDONLY | O_CLOEXEC; + + if (verify == 1 || (verify == -1 && verifyflag)) + oflags |= O_VERIFY; INTOFF; - if ((fd = open(fname, O_RDONLY | O_CLOEXEC)) < 0) { + if ((fd = open(fname, oflags)) < 0) { e = errno; errorwithstatus(e == ENOENT || e == ENOTDIR ? 127 : 126, "cannot open %s: %s", fname, strerror(e)); diff --git a/external/sh/input.h b/external/sh/input.h index 5a47e4b1..edb622b6 100644 --- a/external/sh/input.h +++ b/external/sh/input.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)input.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/input.h 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ /* PEOF (the end of file marker) is defined in syntax.h */ @@ -53,7 +53,7 @@ int preadbuffer(void); int preadateof(void); void pungetc(void); void pushstring(const char *, int, struct alias *); -void setinputfile(const char *, int); +void setinputfile(const char *, int, int); void setinputfd(int, int); void setinputstring(const char *, int); void popfile(void); diff --git a/external/sh/jobs.c b/external/sh/jobs.c index 291f3a5c..c0ba7d75 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 361112 2020-05-16 16:29:23Z jilles $"); +__FBSDID("$FreeBSD$"); #include <sys/ioctl.h> #include <sys/param.h> @@ -928,7 +928,12 @@ forkshell(struct job *jp, union node *n, int mode) pgrp = jp->ps[0].pid; if (setpgid(0, pgrp) == 0 && mode == FORK_FG && ttyfd >= 0) { - /*** this causes superfluous TIOCSPGRPS ***/ + /* + * Each process in a pipeline must have the tty + * pgrp set before running its code. + * Only for pipelines of three or more processes + * could this be reduced to two calls. + */ if (tcsetpgrp(ttyfd, pgrp) < 0) error("tcsetpgrp failed, errno=%d", errno); } diff --git a/external/sh/jobs.h b/external/sh/jobs.h index f6d90a8b..d0caf063 100644 --- a/external/sh/jobs.h +++ b/external/sh/jobs.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * @(#)jobs.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/jobs.h 327475 2018-01-01 22:31:52Z jilles $ + * $FreeBSD$ */ /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ diff --git a/external/sh/kill.c b/external/sh/kill.c index dbf345de..201ab9aa 100644 --- a/external/sh/kill.c +++ b/external/sh/kill.c @@ -45,7 +45,7 @@ static char sccsid[] = "@(#)kill.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #endif #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/kill/kill.c 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); #include <ctype.h> #include <err.h> diff --git a/external/sh/mail.c b/external/sh/mail.c index bbf5e404..194f6544 100644 --- a/external/sh/mail.c +++ b/external/sh/mail.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/mail.c 336303 2018-07-15 09:14:30Z jilles $"); +__FBSDID("$FreeBSD$"); /* * Routines to check for mail. (Perhaps make part of main.c?) diff --git a/external/sh/mail.h b/external/sh/mail.h index 509f11c5..0bb56520 100644 --- a/external/sh/mail.h +++ b/external/sh/mail.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)mail.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/mail.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ void chkmail(int); diff --git a/external/sh/main.c b/external/sh/main.c index 9270b6bb..bc874408 100644 --- a/external/sh/main.c +++ b/external/sh/main.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/28/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/main.c 364919 2020-08-28 15:35:45Z jilles $"); +__FBSDID("$FreeBSD$"); #include <stdio.h> #include <signal.h> @@ -75,6 +75,9 @@ __FBSDID("$FreeBSD: head/bin/sh/main.c 364919 2020-08-28 15:35:45Z jilles $"); #include "cd.h" #include "redir.h" #include "builtins.h" +#ifndef NO_HISTORY +#include "myhistedit.h" +#endif int rootpid; int rootshell; @@ -157,6 +160,10 @@ state2: read_profile(shinit); } } +#ifndef NO_HISTORY + if (iflag) + histload(); +#endif state3: state = 4; popstackmark(&smark2); @@ -246,12 +253,16 @@ read_profile(const char *name) { int fd; const char *expandedname; + int oflags = O_RDONLY | O_CLOEXEC; + + if (verifyflag) + oflags |= O_VERIFY; expandedname = expandstr(name); if (expandedname == NULL) return; INTOFF; - if ((fd = open(expandedname, O_RDONLY | O_CLOEXEC)) >= 0) + if ((fd = open(expandedname, oflags)) >= 0) setinputfd(fd, 1); INTON; if (fd < 0) @@ -267,9 +278,9 @@ read_profile(const char *name) */ void -readcmdfile(const char *name) +readcmdfile(const char *name, int verify) { - setinputfile(name, 1); + setinputfile(name, 1, verify); cmdloop(0); popfile(); } @@ -324,7 +335,7 @@ dotcmd(int argc, char **argv) filename = argc > 2 && strcmp(argv[1], "--") == 0 ? argv[2] : argv[1]; fullname = find_dot_file(filename); - setinputfile(fullname, 1); + setinputfile(fullname, 1, -1 /* verify */); commandname = fullname; cmdloop(0); popfile(); diff --git a/external/sh/main.h b/external/sh/main.h index ed160cd3..d12c7ab7 100644 --- a/external/sh/main.h +++ b/external/sh/main.h @@ -32,11 +32,11 @@ * SUCH DAMAGE. * * @(#)main.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/main.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ extern int rootpid; /* pid of main shell */ extern int rootshell; /* true if we aren't a child of the main shell */ extern struct jmploc main_handler; /* top level exception handler */ -void readcmdfile(const char *); +void readcmdfile(const char *, int); diff --git a/external/sh/memalloc.c b/external/sh/memalloc.c index 0f49e587..7ea31af0 100644 --- a/external/sh/memalloc.c +++ b/external/sh/memalloc.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/memalloc.c 360452 2020-04-28 20:34:27Z jilles $"); +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include "shell.h" @@ -227,7 +227,10 @@ popstackmark(struct stackmark *mark) } stacknxt = mark->stacknxt; stacknleft = mark->stacknleft; - sstrend = stacknxt + stacknleft; + if (stacknleft != 0) + sstrend = stacknxt + stacknleft; + else + sstrend = stacknxt; INTON; } diff --git a/external/sh/memalloc.h b/external/sh/memalloc.h index 180abfd4..6cb7bd81 100644 --- a/external/sh/memalloc.h +++ b/external/sh/memalloc.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)memalloc.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/memalloc.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ #include <string.h> diff --git a/external/sh/miscbltin.c b/external/sh/miscbltin.c index d5243304..79d7dc09 100644 --- a/external/sh/miscbltin.c +++ b/external/sh/miscbltin.c @@ -38,7 +38,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 361384 2020-05-22 14:46:23Z jilles $"); +__FBSDID("$FreeBSD$"); /* * Miscellaneous builtins. diff --git a/external/sh/mkbuiltins b/external/sh/mkbuiltins index 4d257ce0..a04a796e 100755 --- a/external/sh/mkbuiltins +++ b/external/sh/mkbuiltins @@ -32,7 +32,7 @@ # SUCH DAMAGE. # # @(#)mkbuiltins 8.2 (Berkeley) 5/4/95 -# $FreeBSD: head/bin/sh/mkbuiltins 360210 2020-04-22 21:45:43Z jilles $ +# $FreeBSD$ temp=`mktemp -t ka` srcdir=$1 diff --git a/external/sh/myhistedit.h b/external/sh/myhistedit.h index 3dbad7e4..1f513f0a 100644 --- a/external/sh/myhistedit.h +++ b/external/sh/myhistedit.h @@ -29,7 +29,7 @@ * SUCH DAMAGE. * * @(#)myhistedit.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/myhistedit.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ #include <histedit.h> @@ -38,7 +38,10 @@ extern History *hist; extern EditLine *el; extern int displayhist; +#include <filecomplete.h> + void histedit(void); void sethistsize(const char *); void setterm(const char *); - +void histload(void); +void histsave(void); diff --git a/external/sh/mystring.c b/external/sh/mystring.c index 7e17e23f..716f0034 100644 --- a/external/sh/mystring.c +++ b/external/sh/mystring.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/mystring.c 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); /* * String functions. diff --git a/external/sh/mystring.h b/external/sh/mystring.h index 31d7891f..ff4384d2 100644 --- a/external/sh/mystring.h +++ b/external/sh/mystring.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)mystring.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/mystring.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ #include <string.h> diff --git a/external/sh/nodes.c b/external/sh/nodes.c index 34741c4f..b574b9b3 100644 --- a/external/sh/nodes.c +++ b/external/sh/nodes.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/nodes.c.pat 314436 2017-02-28 23:42:47Z imp $ + * $FreeBSD$ */ #include <sys/param.h> diff --git a/external/sh/options.c b/external/sh/options.c index 0628e73a..97171d32 100644 --- a/external/sh/options.c +++ b/external/sh/options.c @@ -38,7 +38,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 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); #include <signal.h> #include <unistd.h> @@ -112,7 +112,7 @@ procargs(int argc, char **argv) arg0 = argv[0]; if (sflag == 0 && minusc == NULL) { scriptname = *argptr++; - setinputfile(scriptname, 0); + setinputfile(scriptname, 0, -1 /* verify */); commandname = arg0 = scriptname; } /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ diff --git a/external/sh/options.h b/external/sh/options.h index ac772290..7c9c4513 100644 --- a/external/sh/options.h +++ b/external/sh/options.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)options.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/options.h 344502 2019-02-24 21:05:13Z jilles $ + * $FreeBSD$ */ struct shparam { @@ -68,9 +68,10 @@ struct shparam { #define hflag optval[18] #define nologflag optval[19] #define pipefailflag optval[20] +#define verifyflag optval[21] #define NSHORTOPTS 19 -#define NOPTS 21 +#define NOPTS 22 extern char optval[NOPTS]; extern const char optletter[NSHORTOPTS]; @@ -99,6 +100,7 @@ static const unsigned char optname[] = "\010trackall" "\005nolog" "\010pipefail" + "\006verify" ; #endif diff --git a/external/sh/output.c b/external/sh/output.c index 6f9fb45f..c01ddd5a 100644 --- a/external/sh/output.c +++ b/external/sh/output.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/output.c 344306 2019-02-19 21:27:30Z jilles $"); +__FBSDID("$FreeBSD$"); /* * Shell output routines. We use our own output routines because: diff --git a/external/sh/output.h b/external/sh/output.h index 83cb8acb..62f006d3 100644 --- a/external/sh/output.h +++ b/external/sh/output.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)output.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/output.h 344306 2019-02-19 21:27:30Z jilles $ + * $FreeBSD$ */ #ifndef OUTPUT_INCL diff --git a/external/sh/parser.c b/external/sh/parser.c index 2c5cdd89..e7579880 100644 --- a/external/sh/parser.c +++ b/external/sh/parser.c @@ -38,7 +38,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 343399 2019-01-24 11:59:46Z trasz $"); +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <pwd.h> @@ -480,9 +480,9 @@ command(void) n1 = (union node *)stalloc(sizeof (struct nfor)); n1->type = NFOR; n1->nfor.var = wordtext; - while (readtoken() == TNL) - ; - if (lasttoken == TWORD && ! quoteflag && equal(wordtext, "in")) { + checkkwd = CHKNL; + if (readtoken() == TWORD && !quoteflag && + equal(wordtext, "in")) { app = ≈ while (readtoken() == TWORD) { n2 = makename(); @@ -491,7 +491,9 @@ command(void) } *app = NULL; n1->nfor.args = ap; - if (lasttoken != TNL && lasttoken != TSEMI) + if (lasttoken == TNL) + tokpushback++; + else if (lasttoken != TSEMI) synexpect(-1); } else { static char argvars[5] = { @@ -507,7 +509,7 @@ command(void) * Newline or semicolon here is optional (but note * that the original Bourne shell only allowed NL). */ - if (lasttoken != TNL && lasttoken != TSEMI) + if (lasttoken != TSEMI) tokpushback++; } checkkwd = CHKNL | CHKKWD | CHKALIAS; @@ -526,8 +528,8 @@ command(void) n1->type = NCASE; consumetoken(TWORD); n1->ncase.expr = makename(); - while (readtoken() == TNL); - if (lasttoken != TWORD || ! equal(wordtext, "in")) + checkkwd = CHKNL; + if (readtoken() != TWORD || ! equal(wordtext, "in")) synerror("expecting \"in\""); cpp = &n1->ncase.cases; checkkwd = CHKNL | CHKKWD, readtoken(); diff --git a/external/sh/parser.h b/external/sh/parser.h index 210726bd..aee8244e 100644 --- a/external/sh/parser.h +++ b/external/sh/parser.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)parser.h 8.3 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/parser.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ /* control characters in argument strings */ diff --git a/external/sh/printf.c b/external/sh/printf.c index 266668ec..94667f38 100644 --- a/external/sh/printf.c +++ b/external/sh/printf.c @@ -49,7 +49,7 @@ static char const copyright[] = static char const sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93"; #endif static const char rcsid[] = - "$FreeBSD: head/usr.bin/printf/printf.c 337618 2018-08-11 11:13:34Z jilles $"; + "$FreeBSD$"; #endif /* not lint */ #include <sys/types.h> diff --git a/external/sh/redir.c b/external/sh/redir.c index 8f415a6c..e820fd2c 100644 --- a/external/sh/redir.c +++ b/external/sh/redir.c @@ -38,7 +38,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 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/stat.h> diff --git a/external/sh/redir.h b/external/sh/redir.h index 74d17b13..08c52359 100644 --- a/external/sh/redir.h +++ b/external/sh/redir.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)redir.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/redir.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ /* flags passed to redirect */ diff --git a/external/sh/shell.h b/external/sh/shell.h index 8574a4b0..536efe6c 100644 --- a/external/sh/shell.h +++ b/external/sh/shell.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)shell.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/shell.h 343981 2019-02-10 22:23:05Z jilles $ + * $FreeBSD$ */ #ifndef SHELL_H_ @@ -55,7 +55,7 @@ /* #define DEBUG 1 */ /* - * Type of used arithmetics. SUSv3 requires us to have at least signed long. + * Type of used arithmetic. SUSv3 requires us to have at least signed long. */ typedef intmax_t arith_t; #define ARITH_FORMAT_STR "%" PRIdMAX diff --git a/external/sh/show.c b/external/sh/show.c index 9b55708c..01035d76 100644 --- a/external/sh/show.c +++ b/external/sh/show.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/show.c 326025 2017-11-20 19:49:47Z pfg $"); +__FBSDID("$FreeBSD$"); #include <fcntl.h> #include <stdio.h> @@ -73,7 +73,7 @@ static void shtree(union node *n, int ind, char *pfx, FILE *fp) { struct nodelist *lp; - char *s; + const char *s; if (n == NULL) return; @@ -125,7 +125,7 @@ shcmd(union node *cmd, FILE *fp) { union node *np; int first; - char *s; + const char *s; int dftfd; first = 1; @@ -274,8 +274,7 @@ indent(int amount, char *pfx, FILE *fp) */ -FILE *tracefile; - +static FILE *tracefile; #if DEBUG >= 2 int debug = 1; #else diff --git a/external/sh/show.h b/external/sh/show.h index fc5ef76a..790a62e2 100644 --- a/external/sh/show.h +++ b/external/sh/show.h @@ -29,7 +29,7 @@ * SUCH DAMAGE. * * @(#)show.h 1.1 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/show.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ void showtree(union node *); @@ -39,4 +39,6 @@ void trargs(char **); void trputc(int); void trputs(const char *); void opentrace(void); + +extern int debug; #endif diff --git a/external/sh/test.c b/external/sh/test.c index 518846a6..60696388 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 298232 2016-04-19 00:38:07Z araujo $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/stat.h> @@ -24,9 +24,7 @@ __FBSDID("$FreeBSD: head/bin/test/test.c 298232 2016-04-19 00:38:07Z araujo $"); #include <err.h> #include <errno.h> #include <inttypes.h> -#include <limits.h> #include <stdarg.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> diff --git a/external/sh/trap.c b/external/sh/trap.c index f82b7c68..a3f1f216 100644 --- a/external/sh/trap.c +++ b/external/sh/trap.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; #endif #endif /* not lint */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/trap.c 364919 2020-08-28 15:35:45Z jilles $"); +__FBSDID("$FreeBSD$"); #include <signal.h> #include <unistd.h> @@ -274,12 +274,8 @@ setsignal(int signo) break; case SIGQUIT: #ifdef DEBUG - { - extern int debug; - if (debug) break; - } #endif action = S_CATCH; break; @@ -540,6 +536,9 @@ exitshell_savedstatus(void) #if JOBS setjobctl(0); #endif +#ifndef NO_HISTORY + histsave(); +#endif } if (sig != 0 && sig != SIGSTOP && sig != SIGTSTP && sig != SIGTTIN && sig != SIGTTOU) { diff --git a/external/sh/trap.h b/external/sh/trap.h index 515491e4..fdc4b7a9 100644 --- a/external/sh/trap.h +++ b/external/sh/trap.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)trap.h 8.3 (Berkeley) 6/5/95 - * $FreeBSD: head/bin/sh/trap.h 364919 2020-08-28 15:35:45Z jilles $ + * $FreeBSD$ */ extern volatile sig_atomic_t pendingsig; diff --git a/external/sh/var.c b/external/sh/var.c index b2d5595f..07582891 100644 --- a/external/sh/var.c +++ b/external/sh/var.c @@ -38,7 +38,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 342740 2019-01-03 20:22:35Z jilles $"); +__FBSDID("$FreeBSD$"); #include <unistd.h> #include <stdlib.h> diff --git a/external/sh/var.h b/external/sh/var.h index c9b5a990..eaf4f427 100644 --- a/external/sh/var.h +++ b/external/sh/var.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)var.h 8.2 (Berkeley) 5/4/95 - * $FreeBSD: head/bin/sh/var.h 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD$ */ /* diff --git a/external/update_sh.sh b/external/update_sh.sh index 51568696..c168cd61 100644 --- a/external/update_sh.sh +++ b/external/update_sh.sh @@ -61,4 +61,5 @@ find "${DESTDIR}" -name '*.c' -o -name '*.h' -o -name '*.def' -o -name 'mk*' } | sed -e '$ ! s,$, \\,' \ > external/sh/Makefile.sources git add -f external/sh/Makefile.sources -find external/patches/sh -type f -exec git am {} + +find external/patches/sh -type f -name '*.patch' -exec \ + git apply -v --index --directory=external {} + |