aboutsummaryrefslogtreecommitdiff
path: root/bin/sh
diff options
context:
space:
mode:
authorBryan Drewery <bdrewery@FreeBSD.org>2017-06-04 21:02:48 +0000
committerBryan Drewery <bdrewery@FreeBSD.org>2017-06-04 21:02:48 +0000
commit3ecb77f01413a709ee0dc4f08259494136682e5e (patch)
tree0fbc2517f6af09a4f77dc56b029023fd68ebe64b /bin/sh
parenteab49982780dbd77b4a315b2500374de84023153 (diff)
Notes
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/builtins.def29
-rw-r--r--bin/sh/eval.c7
-rwxr-xr-xbin/sh/mkbuiltins44
3 files changed, 62 insertions, 18 deletions
diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def
index 7d170f349947..a3cea9f6e441 100644
--- a/bin/sh/builtins.def
+++ b/bin/sh/builtins.def
@@ -41,6 +41,9 @@
# without job control.
# The -h flag specifies that this command is to be excluded from systems
# based on the NO_HISTORY compile-time symbol.
+# The -n flag specifies that this command can safely be run in the same
+# process when it is the only command in a command substitution. Some
+# commands have special logic defined in safe_builtin().
# The -s flag specifies that this is a POSIX 'special built-in' command.
# The rest of the line specifies the command name or names used to run the
# command. The entry for bltincmd, which is run when the user does not specify
@@ -48,43 +51,43 @@
#
# NOTE: bltincmd must come first!
-bltincmd builtin
+bltincmd -n builtin
aliascmd alias
bgcmd -j bg
bindcmd bind
breakcmd -s break -s continue
cdcmd cd chdir
-commandcmd command
+commandcmd -n command
dotcmd -s .
-echocmd echo
+echocmd -n echo
evalcmd -s eval
execcmd -s exec
exitcmd -s exit
letcmd let
exportcmd -s export -s readonly
#exprcmd expr
-falsecmd false
+falsecmd -n false
fgcmd -j fg
freebsd_wordexpcmd freebsd_wordexp
getoptscmd getopts
hashcmd hash
histcmd -h fc
-jobidcmd jobid
-jobscmd jobs
-killcmd kill
+jobidcmd -n jobid
+jobscmd -n jobs
+killcmd -n kill
localcmd local
-printfcmd printf
-pwdcmd pwd
+printfcmd -n printf
+pwdcmd -n pwd
readcmd read
returncmd -s return
setcmd -s set
setvarcmd setvar
shiftcmd -s shift
-testcmd test [
-timescmd -s times
+testcmd -n test [
+timescmd -n -s times
trapcmd -s trap
-truecmd -s : true
-typecmd type
+truecmd -n -s : true
+typecmd -n type
ulimitcmd ulimit
umaskcmd umask
unaliascmd unalias
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index a3cb5cb47a6c..7898693c968c 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -800,11 +800,8 @@ xtracecommand(struct arglist *varlist, int argc, char **argv)
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)
+ /* Generated from builtins.def. */
+ if (safe_builtin_always(idx))
return (1);
if (idx == EXPORTCMD || idx == TRAPCMD || idx == ULIMITCMD ||
idx == UMASKCMD)
diff --git a/bin/sh/mkbuiltins b/bin/sh/mkbuiltins
index f449de4b1edc..fb77f509b0ba 100755
--- a/bin/sh/mkbuiltins
+++ b/bin/sh/mkbuiltins
@@ -66,6 +66,9 @@ const unsigned char builtincmd[] = {'
awk '{ for (i = 2 ; i <= NF ; i++) {
if ($i == "-s") {
spc = 1;
+ } else if ($i == "-n") {
+ # Handled later for builtins.h
+ continue
} else {
printf "\t\"\\%03o\\%03o%s\"\n", length($i), (spc ? 128 : 0) + NR-1, $i
spc = 0;
@@ -90,4 +93,45 @@ extern int (*const builtinfunc[])(int, char **);
extern const unsigned char builtincmd[];
'
awk '{ printf "int %s(int, char **);\n", $1}' $temp
+
+# Build safe_builtin_always()
+cat <<EOF
+
+static inline int
+safe_builtin_always(int idx)
+{
+EOF
+awk '
+BEGIN { printed = 0 }
+{
+ for (i = 2 ; i <= NF ; i++) {
+ if ($i == "-s") {
+ continue
+ } else if ($i == "-n") {
+ nofork = 1;
+ } else {
+ if (nofork == 0) {
+ continue
+ }
+ if (printed == 1) {
+ printf " || \n\t "
+ } else {
+ printf "\tif ("
+ }
+ printf "idx == " toupper($1)
+ printed = 1
+ nofork = 0;
+ # Only need to check each once
+ break
+ }
+ }
+}' $temp
+
+cat << EOF
+)
+ return (1);
+ return(0);
+}
+EOF
+
rm -f $temp