From 088f2cdc6274ddce9e65245341b5ed3059305a5c Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:23:11 -0700 Subject: [PATCH] sh: Expand aliases after assignments and redirections. Obtained-from: FreeBSD 222165 --- bin/sh/eval.c | 14 ++++---------- bin/sh/parser.c | 24 +++++++++++++++++++++++- bin/sh/parser.h | 3 ++- bin/sh/sh.1 | 8 ++++---- tools/regression/bin/sh/parser/alias4.0 | 5 +++++ tools/regression/bin/sh/parser/alias5.0 | 5 +++++ 6 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 tools/regression/bin/sh/parser/alias4.0 create mode 100644 tools/regression/bin/sh/parser/alias5.0 diff --git a/bin/sh/eval.c b/bin/sh/eval.c index f8f7d981b6..7f9ae8c083 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)eval.c 8.9 (Berkeley) 6/8/95 - * $FreeBSD: src/bin/sh/eval.c,v 1.104 2011/05/15 17:00:43 jilles Exp $ + * $FreeBSD: src/bin/sh/eval.c,v 1.105 2011/05/21 22:03:06 jilles Exp $ */ #include @@ -717,15 +717,9 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) oexitstatus = exitstatus; exitstatus = 0; for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { - char *p = argp->narg.text; - if (varflag && is_name(*p)) { - do { - p++; - } while (is_in_name(*p)); - if (*p == '=') { - expandarg(argp, &varlist, EXP_VARTILDE); - continue; - } + if (varflag && isassignment(argp->narg.text)) { + expandarg(argp, &varlist, EXP_VARTILDE); + continue; } expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); varflag = 0; diff --git a/bin/sh/parser.c b/bin/sh/parser.c index f5ad6362b6..86823338f8 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)parser.c 8.7 (Berkeley) 5/16/95 - * $FreeBSD: src/bin/sh/parser.c,v 1.111 2011/05/20 16:03:36 jilles Exp $ + * $FreeBSD: src/bin/sh/parser.c,v 1.112 2011/05/21 22:03:06 jilles Exp $ */ #include @@ -618,6 +618,7 @@ simplecmd(union node **rpp, union node *redir) union node **orig_rpp = rpp; union node *n = NULL; int special; + int savecheckkwd; /* If we don't have any redirections already, then we must reset */ /* rpp to be the address of the local redir variable. */ @@ -633,7 +634,10 @@ simplecmd(union node **rpp, union node *redir) */ orig_rpp = rpp; + savecheckkwd = CHKALIAS; + for (;;) { + checkkwd = savecheckkwd; if (readtoken() == TWORD) { n = (union node *)stalloc(sizeof (struct narg)); n->type = NARG; @@ -641,6 +645,8 @@ simplecmd(union node **rpp, union node *redir) n->narg.backquote = backquotelist; *app = n; app = &n->narg.next; + if (savecheckkwd != 0 && !isassignment(wordtext)) + savecheckkwd = 0; } else if (lasttoken == TREDIR) { *rpp = n = redirnode; rpp = &n->nfile.next; @@ -1858,6 +1864,22 @@ goodname(const char *name) } +int +isassignment(const char *p) +{ + if (!is_name(*p)) + return 0; + p++; + for (;;) { + if (*p == '=') + return 1; + else if (!is_in_name(*p)) + return 0; + p++; + } +} + + /* * Called when an unexpected token is read during the parse. The argument * is the token that is expected, or -1 if more than one type of token can diff --git a/bin/sh/parser.h b/bin/sh/parser.h index 1b7a729abd..202e9784b8 100644 --- a/bin/sh/parser.h +++ b/bin/sh/parser.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)parser.h 8.3 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/parser.h,v 1.16 2011/05/06 20:45:50 jilles Exp $ + * $FreeBSD: src/bin/sh/parser.h,v 1.17 2011/05/21 22:03:06 jilles Exp $ */ /* control characters in argument strings */ @@ -84,4 +84,5 @@ extern const char *const parsekwd[]; union node *parsecmd(int); void fixredir(union node *, const char *, int); int goodname(const char *); +int isassignment(const char *); const char *getprompt(void *); diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 027a94d385..d3fbe815b8 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 -.\" $FreeBSD: src/bin/sh/sh.1,v 1.164 2011/05/20 22:55:18 jilles Exp $ +.\" $FreeBSD: src/bin/sh/sh.1,v 1.165 2011/05/21 22:03:06 jilles Exp $ .\" -.Dd July 4, 2011 +.Dd August 21, 2011 .Dt SH 1 .Os .Sh NAME @@ -517,8 +517,8 @@ The following are keywords: An alias is a name and corresponding value set using the .Ic alias built-in command. -Whenever a keyword may occur (see above), -and after checking for keywords, the shell +Wherever the command word of a simple command may occur, +and after checking for keywords if a keyword may occur, the shell checks the word to see if it matches an alias. If it does, it replaces it in the input stream with its value. For example, if there is an alias called diff --git a/tools/regression/bin/sh/parser/alias4.0 b/tools/regression/bin/sh/parser/alias4.0 new file mode 100644 index 0000000000..b2023be5e5 --- /dev/null +++ b/tools/regression/bin/sh/parser/alias4.0 @@ -0,0 +1,5 @@ +# $FreeBSD: src/tools/regression/bin/sh/parser/alias4.0,v 1.1 2011/05/21 22:03:06 jilles Exp $ + +alias alias0=exit +eval 'x=1 alias0 0' +exit 1 diff --git a/tools/regression/bin/sh/parser/alias5.0 b/tools/regression/bin/sh/parser/alias5.0 new file mode 100644 index 0000000000..b3c6c5a0e9 --- /dev/null +++ b/tools/regression/bin/sh/parser/alias5.0 @@ -0,0 +1,5 @@ +# $FreeBSD: src/tools/regression/bin/sh/parser/alias5.0,v 1.1 2011/05/21 22:03:06 jilles Exp $ + +alias alias0=exit +eval '