Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Make it be that an empty command is treated as a regu...



details:   https://anonhg.NetBSD.org/src/rev/3ecfe07fb534
branches:  trunk
changeset: 446186:3ecfe07fb534
user:      kre <kre%NetBSD.org@localhost>
date:      Mon Nov 26 13:47:39 2018 +0000

description:
Make it be that an empty command is treated as a regular builtin
for the purposes of any redirects it might have -- ie: as posix
requires, make the redirects appear to have been executed in a subshell
environment, so if one fails, aside from a diagnositc msg, all the
running script sees is a command that failed ($? != 0), rather
that having the shell exit which used to happen (the empty command was
being treated as a special builtin).

Continue to treat the empty command as special for the purposes of
var assigns it might contain (those are not executed in a sub-shell
and persist) - an error there (eg: assigning to a readonly var) will
continue to cause the shell (non-interactive shell) to exit.

This makes the NetBSD shell behave like all other (reasonably modern)
shells - fix method (not the implementation, details differ) taken from
FreeBSD who fixed this back in early 2010.    Problem pointed out
in (non-list) mail by Martijn Dekker.

diffstat:

 bin/sh/eval.c |  29 +++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 6 deletions(-)

diffs (75 lines):

diff -r 7481496336f4 -r 3ecfe07fb534 bin/sh/eval.c
--- a/bin/sh/eval.c     Mon Nov 26 11:53:58 2018 +0000
+++ b/bin/sh/eval.c     Mon Nov 26 13:47:39 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.163 2018/11/23 23:37:22 kre Exp $   */
+/*     $NetBSD: eval.c,v 1.164 2018/11/26 13:47:39 kre Exp $   */
 
 /*-
  * Copyright (c) 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)eval.c     8.9 (Berkeley) 6/8/95";
 #else
-__RCSID("$NetBSD: eval.c,v 1.163 2018/11/23 23:37:22 kre Exp $");
+__RCSID("$NetBSD: eval.c,v 1.164 2018/11/26 13:47:39 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -873,6 +873,7 @@
        volatile int temp_path;
        const int savefuncline = funclinebase;
        const int savefuncabs = funclineabs;
+       volatile int cmd_flags = 0;
 
        vforked = 0;
        /* First expand the arguments. */
@@ -979,11 +980,16 @@
 
        /* Now locate the command. */
        if (argc == 0) {
-               cmdentry.cmdtype = CMDSPLBLTIN;
+               /*
+                * the empty command begins as a normal builtin, and
+                * remains that way while redirects are processed, then
+                * will become special before we get to doing the
+                * var assigns.
+                */
+               cmdentry.cmdtype = CMDBUILTIN;
                cmdentry.u.bltin = bltincmd;
        } else {
                static const char PATH[] = "PATH=";
-               int cmd_flags = 0;
 
                /*
                 * Modify the command lookup path, if a PATH= assignment
@@ -1224,9 +1230,11 @@
                        exitshell(exitstatus);
                break;
 
+       case CMDSPLBLTIN:
+               VTRACE(DBG_EVAL, ("special "));
        case CMDBUILTIN:
-       case CMDSPLBLTIN:
-               VXTRACE(DBG_EVAL, ("builtin command%s:  ",vforked?" VF":""), trargs(argv));
+               VXTRACE(DBG_EVAL, ("builtin command [%d]%s:  ", argc,
+                   vforked ? " VF" : ""), trargs(argv));
                mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;
                if (flags == EV_BACKCMD) {
                        memout.nleft = 0;
@@ -1254,6 +1262,15 @@
                        }
                        redirect(cmd->ncmd.redirect, mode);
 
+                       /*
+                        * the empty command is regarded as a normal
+                        * builtin for the purposes of redirects, but
+                        * is a special builtin for var assigns.
+                        * (unless we are the "command" command.)
+                        */
+                       if (argc == 0 && !(cmd_flags & DO_NOFUNC))
+                               cmdentry.cmdtype = CMDSPLBLTIN;
+
                        /* exec is a special builtin, but needs this list... */
                        cmdenviron = varlist.list;
                        /* we must check 'readonly' flag for all builtins */



Home | Main Index | Thread Index | Old Index