summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/eval.c32
-rw-r--r--tools/regression/bin/sh/expansion/cmdsubst10.051
2 files changed, 78 insertions, 5 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 903f783..25c3fcf 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -643,7 +643,31 @@ out:
result->fd, result->buf, result->nleft, result->jp));
}
-
+/*
+ * Check if a builtin can safely be executed in the same process,
+ * even though it should be in a subshell (command substitution).
+ * Note that jobid, jobs, times and trap can show information not
+ * available in a child process; this is deliberate.
+ * The arguments should already have been expanded.
+ */
+static int
+safe_builtin(int idx, int argc, char **argv)
+{
+ if (idx == BLTINCMD || idx == COMMANDCMD || idx == ECHOCMD ||
+ idx == FALSECMD || idx == JOBIDCMD || idx == JOBSCMD ||
+ idx == KILLCMD || idx == PRINTFCMD || idx == PWDCMD ||
+ idx == TESTCMD || idx == TIMESCMD || idx == TRUECMD ||
+ idx == TYPECMD)
+ return (1);
+ if (idx == EXPORTCMD || idx == TRAPCMD || idx == ULIMITCMD ||
+ idx == UMASKCMD)
+ return (argc <= 1 || (argc == 2 && argv[1][0] == '-'));
+ if (idx == SETCMD)
+ return (argc <= 1 || (argc == 2 && (argv[1][0] == '-' ||
+ argv[1][0] == '+') && argv[1][1] == 'o' &&
+ argv[1][2] == '\0'));
+ return (0);
+}
/*
* Execute a simple command.
@@ -861,10 +885,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|| ((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN)
&& ((flags & EV_EXIT) == 0 || have_traps()))
|| ((flags & EV_BACKCMD) != 0
- && (cmdentry.cmdtype != CMDBUILTIN
- || cmdentry.u.index == CDCMD
- || cmdentry.u.index == DOTCMD
- || cmdentry.u.index == EVALCMD))) {
+ && (cmdentry.cmdtype != CMDBUILTIN ||
+ !safe_builtin(cmdentry.u.index, argc, argv)))) {
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
diff --git a/tools/regression/bin/sh/expansion/cmdsubst10.0 b/tools/regression/bin/sh/expansion/cmdsubst10.0
new file mode 100644
index 0000000..7cf17a3
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/cmdsubst10.0
@@ -0,0 +1,51 @@
+# $FreeBSD$
+
+a1=$(alias)
+: $(alias testalias=abcd)
+a2=$(alias)
+[ "$a1" = "$a2" ] || echo Error at line $LINENO
+
+alias testalias2=abcd
+a1=$(alias)
+: $(unalias testalias2)
+a2=$(alias)
+[ "$a1" = "$a2" ] || echo Error at line $LINENO
+
+[ "$(command -V pwd)" = "$(command -V pwd; exit $?)" ] || echo Error at line $LINENO
+
+v=1
+: $(export v=2)
+[ "$v" = 1 ] || echo Error at line $LINENO
+
+rotest=1
+: $(readonly rotest=2)
+[ "$rotest" = 1 ] || echo Error at line $LINENO
+
+set +u
+: $(set -u)
+case $- in
+*u*) echo Error at line $LINENO ;;
+esac
+set +u
+
+set +u
+: $(set -o nounset)
+case $- in
+*u*) echo Error at line $LINENO ;;
+esac
+set +u
+
+set +u
+: $(command set -u)
+case $- in
+*u*) echo Error at line $LINENO ;;
+esac
+set +u
+
+umask 77
+u1=$(umask)
+: $(umask 022)
+u2=$(umask)
+[ "$u1" = "$u2" ] || echo Error at line $LINENO
+
+dummy=$(exit 3); [ $? -eq 3 ] || echo Error at line $LINENO
OpenPOWER on IntegriCloud