From 010baf5e2af59a633e796569c7600627ac5f6287 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Mon, 4 Jul 2011 17:32:26 -1000 Subject: [PATCH 01/16] sh: Minor optimization to output from ulimit/export/readonly. Obtained-from: FreeBSD SVN rev 221975 --- bin/sh/miscbltin.c | 6 +++--- bin/sh/var.c | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index ebb66a4d0a..ae34d9fef3 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)miscbltin.c 8.4 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/miscbltin.c,v 1.44 2010/11/23 22:17:39 jilles Exp $ + * $FreeBSD: src/bin/sh/miscbltin.c,v 1.45 2011/05/15 22:09:27 jilles Exp $ */ /* @@ -464,7 +464,7 @@ ulimitcmd(int argc __unused, char **argv __unused) "(-%c) ", l->option); out1fmt("%-18s %18s ", l->name, optbuf); if (val == RLIM_INFINITY) - out1fmt("unlimited\n"); + out1str("unlimited\n"); else { val /= l->factor; @@ -490,7 +490,7 @@ ulimitcmd(int argc __unused, char **argv __unused) val = limit.rlim_max; if (val == RLIM_INFINITY) - out1fmt("unlimited\n"); + out1str("unlimited\n"); else { val /= l->factor; diff --git a/bin/sh/var.c b/bin/sh/var.c index c9b93a3445..16552a39f6 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)var.c 8.3 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/var.c,v 1.59 2011/05/08 17:40:10 jilles Exp $ + * $FreeBSD: src/bin/sh/var.c,v 1.60 2011/05/15 22:09:27 jilles Exp $ */ #include @@ -678,14 +678,13 @@ exportcmd(int argc, char **argv) out1str(cmdname); out1c(' '); } - p = strchr(vp->text, '='); if (values && !(vp->flags & VUNSET)) { - p++; - outbin(vp->text, p - vp->text, - out1); - out1qstr(p); + outbin(vp->text, + vp->name_len + 1, out1); + out1qstr(vp->text + + vp->name_len + 1); } else - outbin(vp->text, p - vp->text, + outbin(vp->text, vp->name_len, out1); out1c('\n'); } -- 2.41.0 From b50bb77759a611b50deb3e3ef5bc45c0186bc553 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Mon, 4 Jul 2011 17:35:34 -1000 Subject: [PATCH 02/16] sh: Allow terminating a heredoc with a terminator at EOF w/o newline. Obtained-from: FreeBSD SVN rev 222134 --- bin/sh/parser.c | 10 +++++---- tools/regression/bin/sh/parser/heredoc11.0 | 26 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 tools/regression/bin/sh/parser/heredoc11.0 diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 6f37eb8aef..f5ad6362b6 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.110 2011/05/08 17:40:10 jilles Exp $ + * $FreeBSD: src/bin/sh/parser.c,v 1.111 2011/05/20 16:03:36 jilles Exp $ */ #include @@ -1512,10 +1512,12 @@ checkend: { p = line; for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); - if (*p == '\n' && *q == '\0') { + if ((*p == '\0' || *p == '\n') && *q == '\0') { c = PEOF; - plinno++; - needprompt = doprompt; + if (*p == '\n') { + plinno++; + needprompt = doprompt; + } } else { pushstring(line, strlen(line), NULL); } diff --git a/tools/regression/bin/sh/parser/heredoc11.0 b/tools/regression/bin/sh/parser/heredoc11.0 new file mode 100644 index 0000000000..0b254cfcad --- /dev/null +++ b/tools/regression/bin/sh/parser/heredoc11.0 @@ -0,0 +1,26 @@ +# $FreeBSD: src/tools/regression/bin/sh/parser/heredoc11.0,v 1.1 2011/05/20 16:03:36 jilles Exp $ + +failures='' + +check() { + if eval "[ $* ]"; then + : + else + echo "Failed: $*" + failures=x$failures + fi +} + +check '`cat < Date: Mon, 4 Jul 2011 17:40:08 -1000 Subject: [PATCH 03/16] sh: Implement the cd -e flag proposed for the next POSIX issue. This reflects failure to determine the pathname of the new directory in the exit status (1). Normally, cd returns successfully if it did chdir() and the call was successful. In POSIX, -e only has meaning with -P; because our -L is not entirely compliant and may fall back to -P mode, -e has some effect with -L as well. Obtained-from: FreeBSD SVN rev 222154 --- bin/sh/cd.c | 27 ++++++++++++------ bin/sh/sh.1 | 15 ++++++++-- tools/regression/bin/sh/builtins/cd3.0 | 21 ++++++++++++++ tools/regression/bin/sh/builtins/cd4.0 | 38 ++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 tools/regression/bin/sh/builtins/cd3.0 create mode 100644 tools/regression/bin/sh/builtins/cd4.0 diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 82e4f66905..128bd9af10 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)cd.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/cd.c,v 1.45 2010/12/21 20:47:06 jilles Exp $ + * $FreeBSD: src/bin/sh/cd.c,v 1.46 2011/05/20 22:55:18 jilles Exp $ */ #include @@ -83,12 +83,16 @@ cdcmd(int argc, char **argv) const char *path; char *p; struct stat statb; - int ch, phys, print = 0; + int ch, phys, print = 0, getcwderr = 0; + int rc; optreset = 1; optind = 1; opterr = 0; /* initialize getopt */ phys = Pflag; - while ((ch = getopt(argc, argv, "LP")) != -1) { + while ((ch = getopt(argc, argv, "eLP")) != -1) { switch (ch) { + case 'e': + getcwderr = 1; + break; case 'L': phys = 0; break; @@ -130,8 +134,9 @@ cdcmd(int argc, char **argv) else print = strcmp(p, dest); } - if (docd(p, print, phys) >= 0) - return 0; + rc = docd(p, print, phys); + if (rc >= 0) + return getcwderr ? rc : 0; } } error("can't cd to %s", dest); @@ -147,17 +152,18 @@ cdcmd(int argc, char **argv) static int docd(char *dest, int print, int phys) { + int rc; TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, phys)); /* If logical cd fails, fall back to physical. */ - if ((phys || cdlogical(dest) < 0) && cdphysical(dest) < 0) + if ((phys || (rc = cdlogical(dest)) < 0) && (rc = cdphysical(dest)) < 0) return (-1); if (print && iflag && curdir) out1fmt("%s\n", curdir); - return 0; + return (rc); } static int @@ -215,6 +221,7 @@ static int cdphysical(char *dest) { char *p; + int rc = 0; INTOFF; if (chdir(dest) < 0) { @@ -222,11 +229,13 @@ cdphysical(char *dest) return (-1); } p = findcwd(NULL); - if (p == NULL) + if (p == NULL) { warning("warning: failed to get name of current directory"); + rc = 1; + } updatepwd(p); INTON; - return (0); + return (rc); } /* diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 3cea1cc39e..027a94d385 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.163 2011/05/08 17:40:10 jilles Exp $ +.\" $FreeBSD: src/bin/sh/sh.1,v 1.164 2011/05/20 22:55:18 jilles Exp $ .\" -.Dd July 2, 2011 +.Dd July 4, 2011 .Dt SH 1 .Os .Sh NAME @@ -1744,7 +1744,7 @@ Execute the specified built-in command, .Ar cmd . This is useful when the user wishes to override a shell function with the same name as a built-in command. -.It Ic cd Oo Fl L | P Oc Op Ar directory +.It Ic cd Oo Fl L | P Oc Oo Fl e Oc Op Ar directory Switch to the specified .Ar directory , or to the directory specified in the @@ -1793,6 +1793,15 @@ option is specified, .Pa .. is handled logically. This is the default. +.Pp +The +.Fl e +option causes +.Ic cd +to return exit status 1 if the full pathname of the new directory +cannot be determined reliably or at all. +Normally this is not considered an error, +although a warning is printed. .It Ic chdir A synonym for the .Ic cd diff --git a/tools/regression/bin/sh/builtins/cd3.0 b/tools/regression/bin/sh/builtins/cd3.0 new file mode 100644 index 0000000000..f697d23c58 --- /dev/null +++ b/tools/regression/bin/sh/builtins/cd3.0 @@ -0,0 +1,21 @@ +# $FreeBSD: src/tools/regression/bin/sh/builtins/cd3.0,v 1.1 2011/05/20 22:55:18 jilles Exp $ + +# If fully successful, cd -Pe must be like cd -P. + +set -e + +cd "${TMPDIR:-/tmp}" +cd -Pe / +[ "$PWD" = / ] +[ "$(pwd)" = / ] +cd "${TMPDIR:-/tmp}" +cd -eP / +[ "$PWD" = / ] +[ "$(pwd)" = / ] + +set +e + +# If cd -Pe cannot chdir, the exit status must be greater than 1. + +v=$( (cd -Pe /var/empty/nonexistent) 2>&1 >/dev/null) +[ $? -gt 1 ] && [ -n "$v" ] diff --git a/tools/regression/bin/sh/builtins/cd4.0 b/tools/regression/bin/sh/builtins/cd4.0 new file mode 100644 index 0000000000..ea071e381b --- /dev/null +++ b/tools/regression/bin/sh/builtins/cd4.0 @@ -0,0 +1,38 @@ +# $FreeBSD: src/tools/regression/bin/sh/builtins/cd4.0,v 1.1 2011/05/20 22:55:18 jilles Exp $ + +# This test assumes that whatever mechanism cd -P uses to determine the +# pathname to the current directory if it is longer than PATH_MAX requires +# read permission on all parent directories. It also works if this +# requirement always applies. + +set -e +L=$(getconf PATH_MAX / 2>/dev/null) || L=4096 +[ "$L" -lt 100000 ] 2>/dev/null || L=4096 +L=$((L+100)) +T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX) +trap 'chmod u+r ${T}; rm -rf ${T}' 0 +cd -Pe $T +D=$(pwd) +chmod u-r "$D" +if [ -r "$D" ]; then + # Running as root, cannot test. + exit 0 +fi +set +e +while [ ${#D} -lt $L ]; do + mkdir veryverylongdirectoryname || exit + cd -Pe veryverylongdirectoryname 2>/dev/null + r=$? + [ $r -gt 1 ] && exit $r + if [ $r -eq 1 ]; then + # Verify that the directory was changed correctly. + cd -Pe .. || exit + [ "$(pwd)" = "$D" ] || exit + # Verify that omitting -e results in success. + cd -P veryverylongdirectoryname 2>/dev/null || exit + exit 0 + fi + D=$D/veryverylongdirectoryname +done +echo "cd -Pe never returned 1" +exit 0 -- 2.41.0 From 088f2cdc6274ddce9e65245341b5ed3059305a5c Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:23:11 -0700 Subject: [PATCH 04/16] 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 ' Date: Sun, 21 Aug 2011 12:27:39 -0700 Subject: [PATCH 05/16] sh: Fix bss-based buffer overflow in . builtin. If the length of a directory in PATH together with the given filename exceeded FILENAME_MAX (which may happen even for pathnames that work), a static buffer was overflown. The static buffer is unnecessary, we can use the stalloc() stack. Obtained-from: FreeBSD 222173 --- bin/sh/main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/sh/main.c b/bin/sh/main.c index 2ed869a875..6629078903 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -35,7 +35,7 @@ * * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved. * @(#)main.c 8.6 (Berkeley) 5/28/95 - * $FreeBSD: src/bin/sh/main.c,v 1.47 2011/05/08 17:40:10 jilles Exp $ + * $FreeBSD: src/bin/sh/main.c,v 1.48 2011/05/22 12:12:28 jilles Exp $ */ #include @@ -275,7 +275,6 @@ readcmdfile(const char *name) static const char * find_dot_file(const char *basename) { - static char localname[FILENAME_MAX+1]; char *fullname; const char *path = pathval(); struct stat statb; @@ -285,10 +284,14 @@ find_dot_file(const char *basename) return basename; while ((fullname = padvance(&path, basename)) != NULL) { - strcpy(localname, fullname); + if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { + /* + * Don't bother freeing here, since it will + * be freed by the caller. + */ + return fullname; + } stunalloc(fullname); - if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) - return localname; } return basename; } -- 2.41.0 From ea8c7d7190d90b39af88a5d41ffab85b05513e56 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:31:07 -0700 Subject: [PATCH 06/16] sh: Fix typo in comment. Obtained-from: FreeBSD 222178 --- bin/sh/mkinit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/sh/mkinit.c b/bin/sh/mkinit.c index 3ae47dedf9..708a3be7fe 100644 --- a/bin/sh/mkinit.c +++ b/bin/sh/mkinit.c @@ -35,7 +35,7 @@ * * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved. * @(#)mkinit.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/mkinit.c,v 1.21 2011/02/04 22:47:55 jilles Exp $ + * $FreeBSD: src/bin/sh/mkinit.c,v 1.22 2011/05/22 14:03:46 uqs Exp $ */ /* @@ -69,7 +69,7 @@ /* - * A text structure is basicly just a string that grows as more characters + * A text structure is basically just a string that grows as more characters * are added onto the end of it. It is implemented as a linked list of * blocks of characters. The routines addstr and addchar append a string * or a single character, respectively, to a text structure. Writetext -- 2.41.0 From d3f265f8380e38bd8bbf1ad635eb0fbb39a836af Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:32:57 -0700 Subject: [PATCH 07/16] sh: Remove obsolete token type TENDBQUOTE. Obtained-from: FreeBSD 222182 --- bin/sh/mktokens | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/sh/mktokens b/bin/sh/mktokens index 746f3ec090..a5c4471a6b 100644 --- a/bin/sh/mktokens +++ b/bin/sh/mktokens @@ -36,7 +36,7 @@ # SUCH DAMAGE. # # @(#)mktokens 8.1 (Berkeley) 5/31/93 -# $FreeBSD: src/bin/sh/mktokens,v 1.10 2005/01/10 08:39:25 imp Exp $ +# $FreeBSD: src/bin/sh/mktokens,v 1.11 2011/05/22 15:24:56 jilles Exp $ # The following is a list of tokens. The second column is nonzero if the # token marks the end of a list. The third column is the name to print in @@ -54,7 +54,6 @@ TPIPE 0 "|" TLP 0 "(" TRP 1 ")" TENDCASE 1 ";;" -TENDBQUOTE 1 "`" TREDIR 0 redirection TWORD 0 word TIF 0 "if" -- 2.41.0 From 72cbf40102386293122f5cbf79eb8ef44b4098e0 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:34:40 -0700 Subject: [PATCH 08/16] sh: Show errno messages in cd. Obtained-from: FreeBSD 222292 --- bin/sh/cd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 128bd9af10..fdbeff1dc0 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)cd.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/cd.c,v 1.46 2011/05/20 22:55:18 jilles Exp $ + * $FreeBSD: src/bin/sh/cd.c,v 1.47 2011/05/25 21:38:16 jilles Exp $ */ #include @@ -85,6 +85,7 @@ cdcmd(int argc, char **argv) struct stat statb; int ch, phys, print = 0, getcwderr = 0; int rc; + int errno1 = ENOENT; optreset = 1; optind = 1; opterr = 0; /* initialize getopt */ phys = Pflag; @@ -137,9 +138,11 @@ cdcmd(int argc, char **argv) rc = docd(p, print, phys); if (rc >= 0) return getcwderr ? rc : 0; + if (errno != ENOENT) + errno1 = errno; } } - error("can't cd to %s", dest); + error("%s: %s", dest, strerror(errno1)); /*NOTREACHED*/ return 0; } -- 2.41.0 From 5b14c76dd79484f6131bc857929bd01f68ca8736 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:39:23 -0700 Subject: [PATCH 09/16] sh: Fix unquoted $@/$* if IFS=''. If IFS is null, unquoted $@/$* should still expand to separate words. This differs from quoted $@ (which does not depend on IFS) in that pathname generation is performed and empty words are removed. Obtained-from: FreeBSD 222361 --- bin/sh/expand.c | 9 ++++-- tools/regression/bin/sh/expansion/ifs4.0 | 39 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tools/regression/bin/sh/expansion/ifs4.0 diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 6f355b8a4f..fae5a3d889 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)expand.c 8.5 (Berkeley) 5/15/95 - * $FreeBSD: src/bin/sh/expand.c,v 1.85 2011/05/08 11:32:20 jilles Exp $ + * $FreeBSD: src/bin/sh/expand.c,v 1.86 2011/05/27 15:56:13 jilles Exp $ */ #include @@ -760,7 +760,8 @@ again: /* jump here after setting a variable with ${var=text} */ break; record: recordregion(startloc, expdest - stackblock(), - varflags & VSQUOTE); + varflags & VSQUOTE || (ifsset() && ifsval()[0] == '\0' && + (*var == '@' || *var == '*'))); break; case VSPLUS: @@ -946,7 +947,9 @@ numvar: sep = ' '; for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { strtodest(p, flag, subtype, quoted); - if (*ap && sep) + if (!*ap) + break; + if (sep || (flag & EXP_FULL && !quoted && **ap != '\0')) STPUTC(sep, expdest); } break; diff --git a/tools/regression/bin/sh/expansion/ifs4.0 b/tools/regression/bin/sh/expansion/ifs4.0 new file mode 100644 index 0000000000..f29cfead03 --- /dev/null +++ b/tools/regression/bin/sh/expansion/ifs4.0 @@ -0,0 +1,39 @@ +# $FreeBSD: src/tools/regression/bin/sh/expansion/ifs4.0,v 1.1 2011/05/27 15:56:13 jilles Exp $ + +c=: e= s=' ' +failures='' +ok='' + +check_result() { + if [ "x$2" = "x$3" ]; then + ok=x$ok + else + failures=x$failures + echo "For $1, expected $3 actual $2" + fi +} + +IFS=' +' +set -- a b '' c +set -- $@ +check_result 'set -- $@' "($#)($1)($2)($3)($4)" "(3)(a)(b)(c)()" + +IFS='' +set -- a b '' c +set -- $@ +check_result 'set -- $@' "($#)($1)($2)($3)($4)" "(3)(a)(b)(c)()" + +set -- a b '' c +set -- $* +check_result 'set -- $*' "($#)($1)($2)($3)($4)" "(3)(a)(b)(c)()" + +set -- a b '' c +set -- "$@" +check_result 'set -- "$@"' "($#)($1)($2)($3)($4)" "(4)(a)(b)()(c)" + +set -- a b '' c +set -- "$*" +check_result 'set -- "$*"' "($#)($1)($2)($3)($4)" "(1)(abc)()()()" + +test "x$failures" = x -- 2.41.0 From 88ce2c2d5734269b65120fc42a10d07068a5b3a1 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:41:55 -0700 Subject: [PATCH 10/16] sh: Various updates to the TOUR document. Obtained-From: FreeBSD 222362 --- bin/sh/TOUR | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/bin/sh/TOUR b/bin/sh/TOUR index a6114f1350..b97491f2cd 100644 --- a/bin/sh/TOUR +++ b/bin/sh/TOUR @@ -1,5 +1,5 @@ # @(#)TOUR 8.1 (Berkeley) 5/31/93 -# $FreeBSD: src/bin/sh/TOUR,v 1.8 2011/02/04 22:47:55 jilles Exp $ +# $FreeBSD: src/bin/sh/TOUR,v 1.9 2011/05/27 16:00:37 jilles Exp $ NOTE -- This is the original TOUR paper distributed with ash and does not represent the current state of the shell. It is provided anyway @@ -27,10 +27,8 @@ programs is: mkbuiltins builtins builtins.h builtins.c mkinit *.c init.c mknodes nodetypes nodes.h nodes.c - mksignames - signames.h signames.c mksyntax - syntax.h syntax.c mktokens - token.h - bltin/mkexpr unary_op binary_op operators.h operators.c There are undoubtedly too many of these. Mkinit searches all the C source files for entries looking like: @@ -64,14 +62,6 @@ tion: Preprocessor #define statements are copied to init.c without any special action to request this. -INDENTATION: The ash source is indented in multiples of six -spaces. The only study that I have heard of on the subject con- -cluded that the optimal amount to indent is in the range of four -to six spaces. I use six spaces since it is not too big a jump -from the widely used eight spaces. If you really hate six space -indentation, use the adjind (source included) program to change -it to something else. - EXCEPTIONS: Code for dealing with exceptions appears in exceptions.c. The C language doesn't include exception handling, so I implement it using setjmp and longjmp. The global variable @@ -115,7 +105,7 @@ repeatedly parses and executes commands. OPTIONS.C: This file contains the option processing code. It is called from main to parse the shell arguments when the shell is -invoked, and it also contains the set builtin. The -i and -j op- +invoked, and it also contains the set builtin. The -i and -m op- tions (the latter turns on job control) require changes in signal handling. The routines setjobctl (in jobs.c) and setinteractive (in trap.c) are called to handle changes to these options. @@ -123,10 +113,11 @@ handling. The routines setjobctl (in jobs.c) and setinteractive PARSING: The parser code is all in parser.c. A recursive des- cent parser is used. Syntax tables (generated by mksyntax) are used to classify characters during lexical analysis. There are -three tables: one for normal use, one for use when inside single -quotes, and one for use when inside double quotes. The tables -are machine dependent because they are indexed by character vari- -ables and the range of a char varies from machine to machine. +four tables: one for normal use, one for use when inside single +quotes and dollar single quotes, one for use when inside double +quotes and one for use in arithmetic. The tables are machine +dependent because they are indexed by character variables and +the range of a char varies from machine to machine. PARSE OUTPUT: The output of the parser consists of a tree of nodes. The various types of nodes are defined in the file node- @@ -242,12 +233,7 @@ The routine shellexec is the interface to the exec system call. EXPAND.C: Arguments are processed in three passes. The first (performed by the routine argstr) performs variable and command substitution. The second (ifsbreakup) performs word splitting -and the third (expandmeta) performs file name generation. If the -"/u" directory is simulated, then when "/u/username" is replaced -by the user's home directory, the flag "didudir" is set. This -tells the cd command that it should print out the directory name, -just as it would if the "/u" directory were implemented using -symbolic links. +and the third (expandmeta) performs file name generation. VAR.C: Variables are stored in a hash table. Probably we should switch to extensible hashing. The variable name is stored in the @@ -292,14 +278,7 @@ when the program is linked into ash. This #define should appear before bltin.h is included; bltin.h will #undef main if the pro- gram is to be compiled stand-alone. -CD.C: This file defines the cd and pwd builtins. The pwd com- -mand runs /bin/pwd the first time it is invoked (unless the user -has already done a cd to an absolute pathname), but then -remembers the current directory and updates it when the cd com- -mand is run, so subsequent pwd commands run very fast. The main -complication in the cd command is in the docd command, which -resolves symbolic links into actual names and informs the user -where the user ended up if he crossed a symbolic link. +CD.C: This file defines the cd and pwd builtins. SIGNALS: Trap.c implements the trap command. The routine set- signal figures out what action should be taken when a signal is -- 2.41.0 From db98aac00aa4b78e8811da43a1a6366f4feff158 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:46:44 -0700 Subject: [PATCH 11/16] sh: Correct criterion for using CDPATH in cd. CDPATH should be ignored not only for pathnames starting with '/' but also for pathnames whose first component is '.' or '..'. Obtained-from: FreeBSD 222381 --- bin/sh/cd.c | 7 +++++-- tools/regression/bin/sh/builtins/cd6.0 | 10 ++++++++++ tools/regression/bin/sh/builtins/cd7.0 | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tools/regression/bin/sh/builtins/cd6.0 create mode 100644 tools/regression/bin/sh/builtins/cd7.0 diff --git a/bin/sh/cd.c b/bin/sh/cd.c index fdbeff1dc0..8396df67f4 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)cd.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/cd.c,v 1.47 2011/05/25 21:38:16 jilles Exp $ + * $FreeBSD: src/bin/sh/cd.c,v 1.48 2011/05/27 20:01:46 jilles Exp $ */ #include @@ -122,7 +122,10 @@ cdcmd(int argc, char **argv) else dest = "."; } - if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL) + if (dest[0] == '/' || + (dest[0] == '.' && (dest[1] == '/' || dest[1] == '\0')) || + (dest[0] == '.' && dest[1] == '.' && (dest[2] == '/' || dest[2] == '\0')) || + (path = bltinlookup("CDPATH", 1)) == NULL) path = nullstr; while ((p = padvance(&path, dest)) != NULL) { if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { diff --git a/tools/regression/bin/sh/builtins/cd6.0 b/tools/regression/bin/sh/builtins/cd6.0 new file mode 100644 index 0000000000..664f11de87 --- /dev/null +++ b/tools/regression/bin/sh/builtins/cd6.0 @@ -0,0 +1,10 @@ +# $FreeBSD: src/tools/regression/bin/sh/builtins/cd6.0,v 1.1 2011/05/27 20:01:46 jilles Exp $ + +set -e +cd -P /bin +d=$PWD +CDPATH=/: +cd -P . +[ "$d" = "$PWD" ] +cd -P ./ +[ "$d" = "$PWD" ] diff --git a/tools/regression/bin/sh/builtins/cd7.0 b/tools/regression/bin/sh/builtins/cd7.0 new file mode 100644 index 0000000000..0a9c9d813a --- /dev/null +++ b/tools/regression/bin/sh/builtins/cd7.0 @@ -0,0 +1,15 @@ +# $FreeBSD: src/tools/regression/bin/sh/builtins/cd7.0,v 1.1 2011/05/27 20:01:46 jilles Exp $ + +set -e +cd /usr/bin +[ "$PWD" = /usr/bin ] +CDPATH=/: +cd . +[ "$PWD" = /usr/bin ] +cd ./ +[ "$PWD" = /usr/bin ] +cd .. +[ "$PWD" = /usr ] +cd /usr/bin +cd ../ +[ "$PWD" = /usr ] -- 2.41.0 From 2b2de9a92edd0a872c6c6f6c3de3662ef89ed3c7 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:50:34 -0700 Subject: [PATCH 12/16] sh: Remove the "exp" builtin. The "exp" builtin is undocumented, non-standard and not very useful. Obtained-from: FreeBSD 222386 --- bin/sh/arith.h | 2 +- bin/sh/arith_yacc.c | 4 ++-- bin/sh/builtins.def | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/sh/arith.h b/bin/sh/arith.h index 82b797f2b3..c65357a790 100644 --- a/bin/sh/arith.h +++ b/bin/sh/arith.h @@ -40,4 +40,4 @@ arith_t arith(const char *); void arith_lex_reset(void); -int expcmd(int, char **); +int letcmd(int, char **); diff --git a/bin/sh/arith_yacc.c b/bin/sh/arith_yacc.c index 1dd364cc49..cb81136f55 100644 --- a/bin/sh/arith_yacc.c +++ b/bin/sh/arith_yacc.c @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/bin/sh/arith_yacc.c,v 1.4 2011/05/04 22:12:22 jilles Exp $ + * $FreeBSD: src/bin/sh/arith_yacc.c,v 1.5 2011/05/27 20:53:07 jilles Exp $ */ #include @@ -356,7 +356,7 @@ arith(const char *s) * The exp(1) builtin. */ int -expcmd(int argc, char **argv) +letcmd(int argc, char **argv) { const char *p; char *concat; diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def index f13d255a13..190b4f7b9d 100644 --- a/bin/sh/builtins.def +++ b/bin/sh/builtins.def @@ -36,7 +36,7 @@ # SUCH DAMAGE. # # @(#)builtins.def 8.4 (Berkeley) 5/4/95 -# $FreeBSD: src/bin/sh/builtins.def,v 1.21 2010/12/21 22:47:34 jilles Exp $ +# $FreeBSD: src/bin/sh/builtins.def,v 1.22 2011/05/27 20:53:07 jilles Exp $ # # This file lists all the builtin commands. The first column is the name @@ -64,7 +64,7 @@ echocmd echo evalcmd -s eval execcmd -s exec exitcmd -s exit -expcmd exp let +letcmd let exportcmd -s export -s readonly falsecmd false fgcmd -j fg -- 2.41.0 From 276d61f564ac22244a1359aa22c319a27b105adc Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:52:25 -0700 Subject: [PATCH 13/16] sh: Honor -n while processing -c string. Obtained-from: FreeBSD 222676 --- bin/sh/eval.c | 4 ++-- tools/regression/bin/sh/execution/set-n4.0 | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 tools/regression/bin/sh/execution/set-n4.0 diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 7f9ae8c083..1de8c311d0 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.105 2011/05/21 22:03:06 jilles Exp $ + * $FreeBSD: src/bin/sh/eval.c,v 1.106 2011/06/04 11:28:42 jilles Exp $ */ #include @@ -166,7 +166,7 @@ evalstring(char *s, int flags) setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { - if (n != NULL) { + if (n != NULL && !nflag) { if (flags_exit && preadateof()) evaltree(n, flags | EV_EXIT); else diff --git a/tools/regression/bin/sh/execution/set-n4.0 b/tools/regression/bin/sh/execution/set-n4.0 new file mode 100644 index 0000000000..29bf3df2a4 --- /dev/null +++ b/tools/regression/bin/sh/execution/set-n4.0 @@ -0,0 +1,3 @@ +# $FreeBSD: src/tools/regression/bin/sh/execution/set-n4.0,v 1.1 2011/06/04 11:28:42 jilles Exp $ + +$SH -nc 'echo bad' -- 2.41.0 From f893ef221c0def4584d3c6814725f04a003f242c Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 12:58:01 -0700 Subject: [PATCH 14/16] sh: Reduce more needless differences between error messages. Obtained-from: FreeBSD 222684 --- bin/sh/alias.c | 4 ++-- bin/sh/input.c | 4 ++-- bin/sh/jobs.c | 6 +++--- bin/sh/main.c | 4 ++-- tools/regression/bin/sh/builtins/alias.1.stderr | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bin/sh/alias.c b/bin/sh/alias.c index 9fd05376c4..d4b222f9dc 100644 --- a/bin/sh/alias.c +++ b/bin/sh/alias.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)alias.c 8.3 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/alias.c,v 1.30 2011/02/04 22:47:55 jilles Exp $ + * $FreeBSD: src/bin/sh/alias.c,v 1.31 2011/06/04 15:05:52 jilles Exp $ */ #include @@ -237,7 +237,7 @@ aliascmd(int argc, char **argv) while ((n = *++argv) != NULL) { if ((v = strchr(n+1, '=')) == NULL) /* n+1: funny ksh stuff */ if ((ap = lookupalias(n, 0)) == NULL) { - warning("%s not found", n); + warning("%s: not found", n); ret = 1; } else printalias(ap); diff --git a/bin/sh/input.c b/bin/sh/input.c index 656bc1f4af..2c3908d887 100644 --- a/bin/sh/input.c +++ b/bin/sh/input.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)input.c 8.3 (Berkeley) 6/9/95 - * $FreeBSD: src/bin/sh/input.c,v 1.29 2009/12/27 18:04:05 jilles Exp $ + * $FreeBSD: src/bin/sh/input.c,v 1.33 2011/06/04 15:05:52 jilles Exp $ */ #include /* defines BUFSIZ */ @@ -401,7 +401,7 @@ setinputfile(const char *fname, int push) INTOFF; if ((fd = open(fname, O_RDONLY)) < 0) - error("Can't open %s: %s", fname, strerror(errno)); + error("cannot open %s: %s", fname, strerror(errno)); if (fd < 10) { fd2 = fcntl(fd, F_DUPFD, 10); close(fd); diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index b679bac91c..ae3bd03896 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)jobs.c 8.5 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/jobs.c,v 1.92 2011/02/04 22:47:55 jilles Exp $ + * $FreeBSD: src/bin/sh/jobs.c,v 1.93 2011/06/04 15:05:52 jilles Exp $ */ #include @@ -819,7 +819,7 @@ forkshell(struct job *jp, union node *n, int mode) ! fd0_redirected_p ()) { close(0); if (open(_PATH_DEVNULL, O_RDONLY) != 0) - error("Can't open %s: %s", + error("cannot open %s: %s", _PATH_DEVNULL, strerror(errno)); } } @@ -831,7 +831,7 @@ forkshell(struct job *jp, union node *n, int mode) ! fd0_redirected_p ()) { close(0); if (open(_PATH_DEVNULL, O_RDONLY) != 0) - error("Can't open %s: %s", + error("cannot open %s: %s", _PATH_DEVNULL, strerror(errno)); } } diff --git a/bin/sh/main.c b/bin/sh/main.c index 6629078903..327335d441 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -35,7 +35,7 @@ * * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved. * @(#)main.c 8.6 (Berkeley) 5/28/95 - * $FreeBSD: src/bin/sh/main.c,v 1.48 2011/05/22 12:12:28 jilles Exp $ + * $FreeBSD: src/bin/sh/main.c,v 1.49 2011/06/04 15:05:52 jilles Exp $ */ #include @@ -258,7 +258,7 @@ readcmdfile(const char *name) if ((fd = open(name, O_RDONLY)) >= 0) setinputfd(fd, 1); else - error("Can't open %s: %s", name, strerror(errno)); + error("cannot open %s: %s", name, strerror(errno)); INTON; cmdloop(0); popfile(); diff --git a/tools/regression/bin/sh/builtins/alias.1.stderr b/tools/regression/bin/sh/builtins/alias.1.stderr index 5ea01d55bf..c9f4011bea 100644 --- a/tools/regression/bin/sh/builtins/alias.1.stderr +++ b/tools/regression/bin/sh/builtins/alias.1.stderr @@ -1 +1 @@ -alias: foo not found +alias: foo: not found -- 2.41.0 From 84021a35cdfe43b836c506f2d8f23d527b78b957 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 13:05:22 -0700 Subject: [PATCH 15/16] sh: Improve error message if the script cannot be opened. Avoid ": cannot open : ...". Obtained-from: FreeBSD 222699 --- bin/sh/options.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/sh/options.c b/bin/sh/options.c index e720284ffb..65006f5311 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)options.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/options.c,v 1.35 2011/04/25 10:14:29 jilles Exp $ + * $FreeBSD: src/bin/sh/options.c,v 1.36 2011/06/04 22:19:00 jilles Exp $ */ #include @@ -82,6 +82,7 @@ void procargs(int argc, char **argv) { int i; + char *scriptname; argptr = argv; if (argc > 0) @@ -106,8 +107,9 @@ procargs(int argc, char **argv) optlist[i].val = 0; arg0 = argv[0]; if (sflag == 0 && minusc == NULL) { - commandname = arg0 = *argptr++; - setinputfile(commandname, 0); + scriptname = *argptr++; + setinputfile(scriptname, 0); + commandname = arg0 = scriptname; } /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ if (argptr && minusc && *argptr) -- 2.41.0 From 87838cc9ea8a6c1c9a2cc20b78bfbc97026c3c04 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 21 Aug 2011 13:10:39 -0700 Subject: [PATCH 16/16] sh: Fix $? in heredocs on simple commands. Obtained-from: FreeBSD 222716 --- bin/sh/eval.c | 5 +++-- tools/regression/bin/sh/expansion/heredoc2.0 | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tools/regression/bin/sh/expansion/heredoc2.0 diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 1de8c311d0..567a040d00 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.106 2011/06/04 11:28:42 jilles Exp $ + * $FreeBSD: src/bin/sh/eval.c,v 1.107 2011/06/05 14:13:15 jilles Exp $ */ #include @@ -410,6 +410,7 @@ evalsubshell(union node *n, int flags) struct job *jp; int backgnd = (n->type == NBACKGND); + oexitstatus = exitstatus; expredir(n->nredir.redirect); if ((!backgnd && flags & EV_EXIT && !have_traps()) || forkshell(jp = makejob(n, 1), n, backgnd) == 0) { @@ -437,6 +438,7 @@ evalredir(union node *n, int flags) struct jmploc *savehandler; volatile int in_redirect = 1; + oexitstatus = exitstatus; expredir(n->nredir.redirect); savehandler = handler; if (setjmp(jmploc.loc)) { @@ -479,7 +481,6 @@ expredir(union node *n) for (redir = n ; redir ; redir = redir->nfile.next) { struct arglist fn; fn.lastp = &fn.list; - oexitstatus = exitstatus; switch (redir->type) { case NFROM: case NTO: diff --git a/tools/regression/bin/sh/expansion/heredoc2.0 b/tools/regression/bin/sh/expansion/heredoc2.0 new file mode 100644 index 0000000000..2d86d5ea40 --- /dev/null +++ b/tools/regression/bin/sh/expansion/heredoc2.0 @@ -0,0 +1,15 @@ +# $FreeBSD: src/tools/regression/bin/sh/expansion/heredoc2.0,v 1.1 2011/06/05 14:13:15 jilles Exp $ + +f() { return $1; } + +[ `f 42; cat <