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.
This commit is contained in:
parent
b6daac4f83
commit
d7fa5d2fb9
@ -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 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||
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 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||
|
||||
/* 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 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||
exitshell(exitstatus);
|
||||
break;
|
||||
|
||||
case CMDBUILTIN:
|
||||
case CMDSPLBLTIN:
|
||||
VXTRACE(DBG_EVAL, ("builtin command%s: ",vforked?" VF":""), trargs(argv));
|
||||
VTRACE(DBG_EVAL, ("special "));
|
||||
case CMDBUILTIN:
|
||||
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 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||
}
|
||||
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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user