diff options
author | Bryan Drewery <bryan@shatow.net> | 2019-02-12 22:20:15 +0300 |
---|---|---|
committer | Bryan Drewery <bryan@shatow.net> | 2019-02-12 22:20:15 +0300 |
commit | 070fc33bed05c2e55aaceab9d5bd28f65b346f40 (patch) | |
tree | a30677a2aa69fdd68a32c535452b50c7b19f12e6 /external | |
parent | 6df43071f25cdfab2210083837634136575b9c53 (diff) |
Update sh from head r343981
Diffstat (limited to 'external')
-rw-r--r-- | external/sh/arith_yacc.c | 4 | ||||
-rw-r--r-- | external/sh/arith_yacc.h | 3 | ||||
-rw-r--r-- | external/sh/arith_yylex.c | 32 | ||||
-rw-r--r-- | external/sh/expand.c | 7 | ||||
-rw-r--r-- | external/sh/histedit.c | 10 | ||||
-rw-r--r-- | external/sh/input.c | 10 | ||||
-rw-r--r-- | external/sh/parser.c | 85 | ||||
-rw-r--r-- | external/sh/shell.h | 4 | ||||
-rw-r--r-- | external/sh/var.c | 6 |
9 files changed, 135 insertions, 26 deletions
diff --git a/external/sh/arith_yacc.c b/external/sh/arith_yacc.c index 20e1e43e..8ff1f63c 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 270246 2014-08-20 20:15:43Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/arith_yacc.c 343981 2019-02-10 22:23:05Z jilles $"); #include <limits.h> #include <errno.h> @@ -104,7 +104,7 @@ static arith_t arith_lookupvarint(char *varname) if (str == NULL || *str == '\0') str = "0"; errno = 0; - result = strtoarith_t(str, &p, 0); + result = strtoarith_t(str, &p); if (errno != 0 || *p != '\0') yyerror("variable conversion error"); return result; diff --git a/external/sh/arith_yacc.h b/external/sh/arith_yacc.h index d386886a..9b9364d5 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 279503 2015-03-01 21:46:55Z jilles $ + * $FreeBSD: head/bin/sh/arith_yacc.h 343981 2019-02-10 22:23:05Z jilles $ */ #define ARITH_ASS 1 @@ -90,4 +90,5 @@ union yystype { extern union yystype yylval; +arith_t strtoarith_t(const char *restrict nptr, char **restrict endptr); int yylex(void); diff --git a/external/sh/arith_yylex.c b/external/sh/arith_yylex.c index 99368523..e48af6bd 100644 --- a/external/sh/arith_yylex.c +++ b/external/sh/arith_yylex.c @@ -33,8 +33,10 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/bin/sh/arith_yylex.c 279503 2015-03-01 21:46:55Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/arith_yylex.c 343981 2019-02-10 22:23:05Z jilles $"); +#include <ctype.h> +#include <errno.h> #include <inttypes.h> #include <stdlib.h> #include <string.h> @@ -50,6 +52,32 @@ __FBSDID("$FreeBSD: head/bin/sh/arith_yylex.c 279503 2015-03-01 21:46:55Z jilles #error Arithmetic tokens are out of order. #endif +arith_t +strtoarith_t(const char *restrict nptr, char **restrict endptr) +{ + arith_t val; + + while (isspace((unsigned char)*nptr)) + nptr++; + switch (*nptr) { + case '-': + return strtoimax(nptr, endptr, 0); + case '0': + return (arith_t)strtoumax(nptr, endptr, 0); + default: + val = (arith_t)strtoumax(nptr, endptr, 0); + if (val >= 0) + return val; + else if (val == ARITH_MIN) { + errno = ERANGE; + return ARITH_MIN; + } else { + errno = ERANGE; + return ARITH_MAX; + } + } +} + int yylex(void) { @@ -78,7 +106,7 @@ yylex(void) case '7': case '8': case '9': - yylval.val = strtoarith_t(buf, &end, 0); + yylval.val = strtoarith_t(buf, &end); arith_buf = end; return ARITH_NUM; case 'A': diff --git a/external/sh/expand.c b/external/sh/expand.c index 117fd2ff..112125dd 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 338473 2018-09-05 19:16:09Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/expand.c 341164 2018-11-28 20:03:53Z jilles $"); #include <sys/types.h> #include <sys/time.h> @@ -623,10 +623,11 @@ static const char * subevalvar_misc(const char *p, struct nodelist **restrict argbackq, const char *var, int subtype, int startloc, int varflags) { + const char *end; char *startp; int amount; - p = argstr(p, argbackq, EXP_TILDE, NULL); + end = argstr(p, argbackq, EXP_TILDE, NULL); STACKSTRNUL(expdest); startp = stackblock() + startloc; @@ -635,7 +636,7 @@ subevalvar_misc(const char *p, struct nodelist **restrict argbackq, setvar(var, startp, 0); amount = startp - expdest; STADJUST(amount, expdest); - return p; + return end; case VSQUESTION: if (*p != CTLENDVAR) { diff --git a/external/sh/histedit.c b/external/sh/histedit.c index f01cabd5..81a7996b 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 319635 2017-06-06 21:08:05Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/histedit.c 343215 2019-01-20 14:25:25Z jilles $"); #include <sys/param.h> #include <limits.h> @@ -67,7 +67,7 @@ __FBSDID("$FreeBSD: head/bin/sh/histedit.c 319635 2017-06-06 21:08:05Z jilles $" History *hist; /* history cookie */ EditLine *el; /* editline cookie */ int displayhist; -static FILE *el_in, *el_out, *el_err; +static FILE *el_in, *el_out; static char *fc_replace(const char *, char *, char *); static int not_fcnumber(const char *); @@ -106,18 +106,16 @@ histedit(void) INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); - if (el_err == NULL) - el_err = fdopen(1, "w"); if (el_out == NULL) el_out = fdopen(2, "w"); - if (el_in == NULL || el_err == NULL || el_out == NULL) + if (el_in == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) setenv("TERM", term, 1); else unsetenv("TERM"); - el = el_init(arg0, el_in, el_out, el_err); + el = el_init(arg0, el_in, el_out, el_out); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); diff --git a/external/sh/input.c b/external/sh/input.c index d5b66bfa..df430a6e 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 314436 2017-02-28 23:42:47Z imp $"); +__FBSDID("$FreeBSD: head/bin/sh/input.c 341097 2018-11-27 21:49:59Z jilles $"); #include <stdio.h> /* defines BUFSIZ */ #include <fcntl.h> @@ -359,12 +359,16 @@ popstring(void) void setinputfile(const char *fname, int push) { + int e; int fd; int fd2; INTOFF; - if ((fd = open(fname, O_RDONLY | O_CLOEXEC)) < 0) - error("cannot open %s: %s", fname, strerror(errno)); + if ((fd = open(fname, O_RDONLY | O_CLOEXEC)) < 0) { + e = errno; + errorwithstatus(e == ENOENT || e == ENOTDIR ? 127 : 126, + "cannot open %s: %s", fname, strerror(e)); + } if (fd < 10) { fd2 = fcntl(fd, F_DUPFD_CLOEXEC, 10); close(fd); diff --git a/external/sh/parser.c b/external/sh/parser.c index 9da2ea6d..2c5cdd89 100644 --- a/external/sh/parser.c +++ b/external/sh/parser.c @@ -38,8 +38,10 @@ 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 334008 2018-05-21 21:52:48Z jilles $"); +__FBSDID("$FreeBSD: head/bin/sh/parser.c 343399 2019-01-24 11:59:46Z trasz $"); +#include <sys/param.h> +#include <pwd.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> @@ -130,6 +132,7 @@ static void synexpect(int) __dead2; static void synerror(const char *) __dead2; static void setprompt(int); static int pgetc_linecont(void); +static void getusername(char *, size_t); static void * @@ -1969,6 +1972,53 @@ pgetc_linecont(void) return (c); } + +static struct passwd * +getpwlogin(void) +{ + const char *login; + + login = getlogin(); + if (login == NULL) + return (NULL); + + return (getpwnam(login)); +} + + +static void +getusername(char *name, size_t namelen) +{ + static char cached_name[MAXLOGNAME]; + struct passwd *pw; + uid_t euid; + + if (cached_name[0] == '\0') { + euid = geteuid(); + + /* + * Handle the case when there is more than one + * login with the same UID, or when the login + * returned by getlogin(2) does no longer match + * the current UID. + */ + pw = getpwlogin(); + if (pw == NULL || pw->pw_uid != euid) + pw = getpwuid(euid); + + if (pw != NULL) { + strlcpy(cached_name, pw->pw_name, + sizeof(cached_name)); + } else { + snprintf(cached_name, sizeof(cached_name), + "%u", euid); + } + } + + strlcpy(name, cached_name, namelen); +} + + /* * called by editline -- any expansions to the prompt * should be added here. @@ -1978,7 +2028,9 @@ getprompt(void *unused __unused) { static char ps[PROMPTLEN]; const char *fmt; + const char *home; const char *pwd; + size_t homelen; int i, trim; static char internal_error[] = "??"; @@ -2025,6 +2077,17 @@ getprompt(void *unused __unused) break; /* + * User name. + */ + case 'u': + ps[i] = '\0'; + getusername(&ps[i], PROMPTLEN - i); + /* Skip to end of username. */ + while (ps[i + 1] != '\0') + i++; + break; + + /* * Working directory. * * \W specifies just the final component, @@ -2039,8 +2102,24 @@ getprompt(void *unused __unused) *pwd == '/' && pwd[1] != '\0') strlcpy(&ps[i], strrchr(pwd, '/') + 1, PROMPTLEN - i); - else - strlcpy(&ps[i], pwd, PROMPTLEN - i); + else { + home = lookupvar("HOME"); + if (home != NULL) + homelen = strlen(home); + if (home != NULL && + strcmp(home, "/") != 0 && + strncmp(pwd, home, homelen) == 0 && + (pwd[homelen] == '/' || + pwd[homelen] == '\0')) { + strlcpy(&ps[i], "~", + PROMPTLEN - i); + strlcpy(&ps[i + 1], + pwd + homelen, + PROMPTLEN - i - 1); + } else { + strlcpy(&ps[i], pwd, PROMPTLEN - i); + } + } /* Skip to end of path. */ while (ps[i + 1] != '\0') i++; diff --git a/external/sh/shell.h b/external/sh/shell.h index 1c7a7662..8574a4b0 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 326025 2017-11-20 19:49:47Z pfg $ + * $FreeBSD: head/bin/sh/shell.h 343981 2019-02-10 22:23:05Z jilles $ */ #ifndef SHELL_H_ @@ -59,8 +59,6 @@ */ typedef intmax_t arith_t; #define ARITH_FORMAT_STR "%" PRIdMAX -#define atoarith_t(arg) strtoimax(arg, NULL, 0) -#define strtoarith_t(nptr, endptr, base) strtoimax(nptr, endptr, base) #define ARITH_MIN INTMAX_MIN #define ARITH_MAX INTMAX_MAX diff --git a/external/sh/var.c b/external/sh/var.c index feeea03c..b2d5595f 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 329221 2018-02-13 16:48:57Z bdrewery $"); +__FBSDID("$FreeBSD: head/bin/sh/var.c 342740 2019-01-03 20:22:35Z jilles $"); #include <unistd.h> #include <stdlib.h> @@ -558,13 +558,13 @@ environment(void) nenv = 0; for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) - if (vp->flags & VEXPORT) + if ((vp->flags & (VEXPORT|VUNSET)) == VEXPORT) nenv++; } ep = env = stalloc((nenv + 1) * sizeof *env); for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) - if (vp->flags & VEXPORT) + if ((vp->flags & (VEXPORT|VUNSET)) == VEXPORT) *ep++ = vp->text; } *ep = NULL; |