summary refs log tree commit diff
path: root/bin/cash/tests/builtins
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-01-10 18:48:02 -0500
committerJune McEnroe <june@causal.agency>2019-01-10 18:48:02 -0500
commit308a14f85158f1545000499a64bc170d688a0db9 (patch)
treedfba0e2c80cbde1c38c814a4c84ce4d2c6d9c09f /bin/cash/tests/builtins
parentRemove character NETHACKOPTIONS (diff)
downloadsrc-308a14f85158f1545000499a64bc170d688a0db9.tar.gz
src-308a14f85158f1545000499a64bc170d688a0db9.zip
Import /usr/src/bin/sh from FreeBSD 12.0-RELEASE
Diffstat (limited to '')
-rw-r--r--bin/cash/tests/builtins/Makefile187
-rw-r--r--bin/cash/tests/builtins/alias.09
-rw-r--r--bin/cash/tests/builtins/alias.0.stdout4
-rw-r--r--bin/cash/tests/builtins/alias.13
-rw-r--r--bin/cash/tests/builtins/alias.1.stderr1
-rw-r--r--bin/cash/tests/builtins/alias3.012
-rw-r--r--bin/cash/tests/builtins/alias3.0.stdout4
-rw-r--r--bin/cash/tests/builtins/alias4.04
-rw-r--r--bin/cash/tests/builtins/break1.016
-rw-r--r--bin/cash/tests/builtins/break2.012
-rw-r--r--bin/cash/tests/builtins/break2.0.stdout1
-rw-r--r--bin/cash/tests/builtins/break3.015
-rw-r--r--bin/cash/tests/builtins/break4.47
-rw-r--r--bin/cash/tests/builtins/break5.412
-rw-r--r--bin/cash/tests/builtins/break6.08
-rw-r--r--bin/cash/tests/builtins/builtin1.031
-rw-r--r--bin/cash/tests/builtins/case1.013
-rw-r--r--bin/cash/tests/builtins/case10.016
-rw-r--r--bin/cash/tests/builtins/case11.06
-rw-r--r--bin/cash/tests/builtins/case12.06
-rw-r--r--bin/cash/tests/builtins/case13.012
-rw-r--r--bin/cash/tests/builtins/case14.05
-rw-r--r--bin/cash/tests/builtins/case15.05
-rw-r--r--bin/cash/tests/builtins/case16.07
-rw-r--r--bin/cash/tests/builtins/case17.03
-rw-r--r--bin/cash/tests/builtins/case18.07
-rw-r--r--bin/cash/tests/builtins/case19.07
-rw-r--r--bin/cash/tests/builtins/case2.0106
-rw-r--r--bin/cash/tests/builtins/case20.09
-rw-r--r--bin/cash/tests/builtins/case21.010
-rw-r--r--bin/cash/tests/builtins/case22.010
-rw-r--r--bin/cash/tests/builtins/case23.05
-rw-r--r--bin/cash/tests/builtins/case3.095
-rw-r--r--bin/cash/tests/builtins/case4.06
-rw-r--r--bin/cash/tests/builtins/case5.057
-rw-r--r--bin/cash/tests/builtins/case6.052
-rw-r--r--bin/cash/tests/builtins/case7.024
-rw-r--r--bin/cash/tests/builtins/case8.032
-rw-r--r--bin/cash/tests/builtins/case9.039
-rw-r--r--bin/cash/tests/builtins/cd1.030
-rw-r--r--bin/cash/tests/builtins/cd10.06
-rw-r--r--bin/cash/tests/builtins/cd11.024
-rw-r--r--bin/cash/tests/builtins/cd2.016
-rw-r--r--bin/cash/tests/builtins/cd3.021
-rw-r--r--bin/cash/tests/builtins/cd4.038
-rw-r--r--bin/cash/tests/builtins/cd5.023
-rw-r--r--bin/cash/tests/builtins/cd6.010
-rw-r--r--bin/cash/tests/builtins/cd7.015
-rw-r--r--bin/cash/tests/builtins/cd8.026
-rw-r--r--bin/cash/tests/builtins/cd9.08
-rw-r--r--bin/cash/tests/builtins/cd9.0.stdout2
-rw-r--r--bin/cash/tests/builtins/command1.05
-rw-r--r--bin/cash/tests/builtins/command10.014
-rw-r--r--bin/cash/tests/builtins/command11.014
-rw-r--r--bin/cash/tests/builtins/command12.07
-rw-r--r--bin/cash/tests/builtins/command2.03
-rw-r--r--bin/cash/tests/builtins/command3.014
-rw-r--r--bin/cash/tests/builtins/command3.0.stdout7
-rw-r--r--bin/cash/tests/builtins/command4.02
-rw-r--r--bin/cash/tests/builtins/command5.015
-rw-r--r--bin/cash/tests/builtins/command5.0.stdout8
-rw-r--r--bin/cash/tests/builtins/command6.022
-rw-r--r--bin/cash/tests/builtins/command6.0.stdout7
-rw-r--r--bin/cash/tests/builtins/command7.034
-rw-r--r--bin/cash/tests/builtins/command8.045
-rw-r--r--bin/cash/tests/builtins/command9.014
-rw-r--r--bin/cash/tests/builtins/dot1.021
-rw-r--r--bin/cash/tests/builtins/dot2.021
-rw-r--r--bin/cash/tests/builtins/dot3.010
-rw-r--r--bin/cash/tests/builtins/dot4.012
-rw-r--r--bin/cash/tests/builtins/echo1.06
-rw-r--r--bin/cash/tests/builtins/echo2.07
-rw-r--r--bin/cash/tests/builtins/echo3.05
-rw-r--r--bin/cash/tests/builtins/eval1.09
-rw-r--r--bin/cash/tests/builtins/eval2.07
-rw-r--r--bin/cash/tests/builtins/eval3.09
-rw-r--r--bin/cash/tests/builtins/eval4.05
-rw-r--r--bin/cash/tests/builtins/eval5.04
-rw-r--r--bin/cash/tests/builtins/eval6.05
-rw-r--r--bin/cash/tests/builtins/eval7.09
-rw-r--r--bin/cash/tests/builtins/eval8.77
-rw-r--r--bin/cash/tests/builtins/exec1.025
-rw-r--r--bin/cash/tests/builtins/exec2.025
-rw-r--r--bin/cash/tests/builtins/exit1.06
-rw-r--r--bin/cash/tests/builtins/exit2.87
-rw-r--r--bin/cash/tests/builtins/exit3.05
-rw-r--r--bin/cash/tests/builtins/export1.03
-rw-r--r--bin/cash/tests/builtins/fc1.027
-rw-r--r--bin/cash/tests/builtins/fc2.034
-rw-r--r--bin/cash/tests/builtins/for1.04
-rw-r--r--bin/cash/tests/builtins/for2.09
-rw-r--r--bin/cash/tests/builtins/for3.08
-rw-r--r--bin/cash/tests/builtins/getopts1.025
-rw-r--r--bin/cash/tests/builtins/getopts1.0.stdout8
-rw-r--r--bin/cash/tests/builtins/getopts10.011
-rw-r--r--bin/cash/tests/builtins/getopts2.06
-rw-r--r--bin/cash/tests/builtins/getopts2.0.stdout1
-rw-r--r--bin/cash/tests/builtins/getopts3.06
-rw-r--r--bin/cash/tests/builtins/getopts4.010
-rw-r--r--bin/cash/tests/builtins/getopts5.010
-rw-r--r--bin/cash/tests/builtins/getopts6.07
-rw-r--r--bin/cash/tests/builtins/getopts7.06
-rw-r--r--bin/cash/tests/builtins/getopts8.08
-rw-r--r--bin/cash/tests/builtins/getopts8.0.stdout5
-rw-r--r--bin/cash/tests/builtins/getopts9.09
-rw-r--r--bin/cash/tests/builtins/getopts9.0.stdout3
-rw-r--r--bin/cash/tests/builtins/hash1.05
-rw-r--r--bin/cash/tests/builtins/hash1.0.stdout1
-rw-r--r--bin/cash/tests/builtins/hash2.04
-rw-r--r--bin/cash/tests/builtins/hash2.0.stdout1
-rw-r--r--bin/cash/tests/builtins/hash3.03
-rw-r--r--bin/cash/tests/builtins/hash3.0.stdout2
-rw-r--r--bin/cash/tests/builtins/hash4.06
-rw-r--r--bin/cash/tests/builtins/jobid1.07
-rw-r--r--bin/cash/tests/builtins/jobid2.09
-rw-r--r--bin/cash/tests/builtins/kill1.08
-rw-r--r--bin/cash/tests/builtins/kill2.07
-rw-r--r--bin/cash/tests/builtins/lineno.016
-rw-r--r--bin/cash/tests/builtins/lineno.0.stdout9
-rw-r--r--bin/cash/tests/builtins/lineno2.010
-rw-r--r--bin/cash/tests/builtins/lineno3.06
-rw-r--r--bin/cash/tests/builtins/lineno3.0.stdout2
-rw-r--r--bin/cash/tests/builtins/local1.013
-rw-r--r--bin/cash/tests/builtins/local2.017
-rw-r--r--bin/cash/tests/builtins/local3.026
-rw-r--r--bin/cash/tests/builtins/local4.012
-rw-r--r--bin/cash/tests/builtins/local5.015
-rw-r--r--bin/cash/tests/builtins/local6.010
-rw-r--r--bin/cash/tests/builtins/local7.010
-rw-r--r--bin/cash/tests/builtins/locale1.0134
-rw-r--r--bin/cash/tests/builtins/locale2.05
-rw-r--r--bin/cash/tests/builtins/printf1.03
-rw-r--r--bin/cash/tests/builtins/printf2.03
-rw-r--r--bin/cash/tests/builtins/printf3.05
-rw-r--r--bin/cash/tests/builtins/printf4.05
-rw-r--r--bin/cash/tests/builtins/read1.026
-rw-r--r--bin/cash/tests/builtins/read1.0.stdout20
-rw-r--r--bin/cash/tests/builtins/read2.031
-rw-r--r--bin/cash/tests/builtins/read3.011
-rw-r--r--bin/cash/tests/builtins/read3.0.stdout9
-rw-r--r--bin/cash/tests/builtins/read4.010
-rw-r--r--bin/cash/tests/builtins/read4.0.stdout8
-rw-r--r--bin/cash/tests/builtins/read5.032
-rw-r--r--bin/cash/tests/builtins/read6.05
-rw-r--r--bin/cash/tests/builtins/read7.05
-rw-r--r--bin/cash/tests/builtins/read8.017
-rw-r--r--bin/cash/tests/builtins/read9.010
-rw-r--r--bin/cash/tests/builtins/return1.07
-rw-r--r--bin/cash/tests/builtins/return2.17
-rw-r--r--bin/cash/tests/builtins/return3.13
-rw-r--r--bin/cash/tests/builtins/return4.016
-rw-r--r--bin/cash/tests/builtins/return5.017
-rw-r--r--bin/cash/tests/builtins/return6.43
-rw-r--r--bin/cash/tests/builtins/return7.46
-rw-r--r--bin/cash/tests/builtins/return8.013
-rw-r--r--bin/cash/tests/builtins/set1.032
-rw-r--r--bin/cash/tests/builtins/set2.03
-rw-r--r--bin/cash/tests/builtins/set3.04
-rw-r--r--bin/cash/tests/builtins/trap1.022
-rw-r--r--bin/cash/tests/builtins/trap10.06
-rw-r--r--bin/cash/tests/builtins/trap11.08
-rw-r--r--bin/cash/tests/builtins/trap12.010
-rw-r--r--bin/cash/tests/builtins/trap13.08
-rw-r--r--bin/cash/tests/builtins/trap14.010
-rw-r--r--bin/cash/tests/builtins/trap15.05
-rw-r--r--bin/cash/tests/builtins/trap16.020
-rw-r--r--bin/cash/tests/builtins/trap17.010
-rw-r--r--bin/cash/tests/builtins/trap2.052
-rw-r--r--bin/cash/tests/builtins/trap3.011
-rw-r--r--bin/cash/tests/builtins/trap4.017
-rw-r--r--bin/cash/tests/builtins/trap5.019
-rw-r--r--bin/cash/tests/builtins/trap6.09
-rw-r--r--bin/cash/tests/builtins/trap7.03
-rw-r--r--bin/cash/tests/builtins/trap8.07
-rw-r--r--bin/cash/tests/builtins/trap9.03
-rw-r--r--bin/cash/tests/builtins/type1.08
-rw-r--r--bin/cash/tests/builtins/type1.0.stderr4
-rw-r--r--bin/cash/tests/builtins/type2.026
-rw-r--r--bin/cash/tests/builtins/type3.03
-rw-r--r--bin/cash/tests/builtins/unalias.021
-rw-r--r--bin/cash/tests/builtins/var-assign.055
-rw-r--r--bin/cash/tests/builtins/var-assign2.055
-rw-r--r--bin/cash/tests/builtins/wait1.023
-rw-r--r--bin/cash/tests/builtins/wait10.05
-rw-r--r--bin/cash/tests/builtins/wait2.015
-rw-r--r--bin/cash/tests/builtins/wait3.021
-rw-r--r--bin/cash/tests/builtins/wait4.012
-rw-r--r--bin/cash/tests/builtins/wait5.012
-rw-r--r--bin/cash/tests/builtins/wait6.03
-rw-r--r--bin/cash/tests/builtins/wait7.04
-rw-r--r--bin/cash/tests/builtins/wait8.07
-rw-r--r--bin/cash/tests/builtins/wait9.1273
192 files changed, 2839 insertions, 0 deletions
diff --git a/bin/cash/tests/builtins/Makefile b/bin/cash/tests/builtins/Makefile
new file mode 100644
index 00000000..a2749595
--- /dev/null
+++ b/bin/cash/tests/builtins/Makefile
@@ -0,0 +1,187 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/Makefile 336320 2018-07-15 21:55:17Z jilles $
+
+PACKAGE=	tests
+
+.include <src.opts.mk>
+
+TESTSDIR=	${TESTSBASE}/bin/sh/${.CURDIR:T}
+
+.PATH: ${.CURDIR:H}
+ATF_TESTS_SH=	functional_test
+
+${PACKAGE}FILES+=		alias.0 alias.0.stdout
+${PACKAGE}FILES+=		alias.1 alias.1.stderr
+${PACKAGE}FILES+=		alias3.0 alias3.0.stdout
+${PACKAGE}FILES+=		alias4.0
+${PACKAGE}FILES+=		break1.0
+${PACKAGE}FILES+=		break2.0 break2.0.stdout
+${PACKAGE}FILES+=		break3.0
+${PACKAGE}FILES+=		break4.4
+${PACKAGE}FILES+=		break5.4
+${PACKAGE}FILES+=		break6.0
+${PACKAGE}FILES+=		builtin1.0
+${PACKAGE}FILES+=		case1.0
+${PACKAGE}FILES+=		case2.0
+${PACKAGE}FILES+=		case3.0
+${PACKAGE}FILES+=		case4.0
+${PACKAGE}FILES+=		case5.0
+${PACKAGE}FILES+=		case6.0
+${PACKAGE}FILES+=		case7.0
+${PACKAGE}FILES+=		case8.0
+${PACKAGE}FILES+=		case9.0
+${PACKAGE}FILES+=		case10.0
+${PACKAGE}FILES+=		case11.0
+${PACKAGE}FILES+=		case12.0
+${PACKAGE}FILES+=		case13.0
+${PACKAGE}FILES+=		case14.0
+${PACKAGE}FILES+=		case15.0
+${PACKAGE}FILES+=		case16.0
+${PACKAGE}FILES+=		case17.0
+${PACKAGE}FILES+=		case18.0
+${PACKAGE}FILES+=		case19.0
+${PACKAGE}FILES+=		case20.0
+${PACKAGE}FILES+=		case21.0
+${PACKAGE}FILES+=		case22.0
+${PACKAGE}FILES+=		case23.0
+${PACKAGE}FILES+=		cd1.0
+${PACKAGE}FILES+=		cd2.0
+${PACKAGE}FILES+=		cd3.0
+${PACKAGE}FILES+=		cd4.0
+${PACKAGE}FILES+=		cd5.0
+${PACKAGE}FILES+=		cd6.0
+${PACKAGE}FILES+=		cd7.0
+${PACKAGE}FILES+=		cd8.0
+${PACKAGE}FILES+=		cd9.0 cd9.0.stdout
+${PACKAGE}FILES+=		cd10.0
+${PACKAGE}FILES+=		cd11.0
+${PACKAGE}FILES+=		command1.0
+${PACKAGE}FILES+=		command2.0
+${PACKAGE}FILES+=		command3.0
+${PACKAGE}FILES+=		command3.0.stdout
+${PACKAGE}FILES+=		command4.0
+${PACKAGE}FILES+=		command5.0
+${PACKAGE}FILES+=		command5.0.stdout
+${PACKAGE}FILES+=		command6.0
+${PACKAGE}FILES+=		command6.0.stdout
+${PACKAGE}FILES+=		command7.0
+${PACKAGE}FILES+=		command8.0
+${PACKAGE}FILES+=		command9.0
+${PACKAGE}FILES+=		command10.0
+${PACKAGE}FILES+=		command11.0
+${PACKAGE}FILES+=		command12.0
+${PACKAGE}FILES+=		dot1.0
+${PACKAGE}FILES+=		dot2.0
+${PACKAGE}FILES+=		dot3.0
+${PACKAGE}FILES+=		dot4.0
+${PACKAGE}FILES+=		echo1.0
+${PACKAGE}FILES+=		echo2.0
+${PACKAGE}FILES+=		echo3.0
+${PACKAGE}FILES+=		eval1.0
+${PACKAGE}FILES+=		eval2.0
+${PACKAGE}FILES+=		eval3.0
+${PACKAGE}FILES+=		eval4.0
+${PACKAGE}FILES+=		eval5.0
+${PACKAGE}FILES+=		eval6.0
+${PACKAGE}FILES+=		eval7.0
+${PACKAGE}FILES+=		eval8.7
+${PACKAGE}FILES+=		exec1.0
+${PACKAGE}FILES+=		exec2.0
+${PACKAGE}FILES+=		exit1.0
+${PACKAGE}FILES+=		exit2.8
+${PACKAGE}FILES+=		exit3.0
+${PACKAGE}FILES+=		export1.0
+${PACKAGE}FILES+=		fc1.0
+${PACKAGE}FILES+=		fc2.0
+${PACKAGE}FILES+=		for1.0
+${PACKAGE}FILES+=		for2.0
+${PACKAGE}FILES+=		for3.0
+${PACKAGE}FILES+=		getopts1.0 getopts1.0.stdout
+${PACKAGE}FILES+=		getopts2.0 getopts2.0.stdout
+${PACKAGE}FILES+=		getopts3.0
+${PACKAGE}FILES+=		getopts4.0
+${PACKAGE}FILES+=		getopts5.0
+${PACKAGE}FILES+=		getopts6.0
+${PACKAGE}FILES+=		getopts7.0
+${PACKAGE}FILES+=		getopts8.0 getopts8.0.stdout
+${PACKAGE}FILES+=		getopts9.0 getopts9.0.stdout
+${PACKAGE}FILES+=		getopts10.0
+${PACKAGE}FILES+=		hash1.0 hash1.0.stdout
+${PACKAGE}FILES+=		hash2.0 hash2.0.stdout
+${PACKAGE}FILES+=		hash3.0 hash3.0.stdout
+${PACKAGE}FILES+=		hash4.0
+${PACKAGE}FILES+=		jobid1.0
+${PACKAGE}FILES+=		jobid2.0
+${PACKAGE}FILES+=		kill1.0 kill2.0
+${PACKAGE}FILES+=		lineno.0 lineno.0.stdout
+${PACKAGE}FILES+=		lineno2.0
+${PACKAGE}FILES+=		lineno3.0 lineno3.0.stdout
+${PACKAGE}FILES+=		local1.0
+${PACKAGE}FILES+=		local2.0
+${PACKAGE}FILES+=		local3.0
+${PACKAGE}FILES+=		local4.0
+${PACKAGE}FILES+=		local5.0
+${PACKAGE}FILES+=		local6.0
+${PACKAGE}FILES+=		local7.0
+.if ${MK_NLS} != "no"
+${PACKAGE}FILES+=		locale1.0
+.endif
+${PACKAGE}FILES+=		locale2.0
+${PACKAGE}FILES+=		printf1.0
+${PACKAGE}FILES+=		printf2.0
+${PACKAGE}FILES+=		printf3.0
+${PACKAGE}FILES+=		printf4.0
+${PACKAGE}FILES+=		read1.0 read1.0.stdout
+${PACKAGE}FILES+=		read2.0
+${PACKAGE}FILES+=		read3.0 read3.0.stdout
+${PACKAGE}FILES+=		read4.0 read4.0.stdout
+${PACKAGE}FILES+=		read5.0
+${PACKAGE}FILES+=		read6.0
+${PACKAGE}FILES+=		read7.0
+${PACKAGE}FILES+=		read8.0
+${PACKAGE}FILES+=		read9.0
+${PACKAGE}FILES+=		return1.0
+${PACKAGE}FILES+=		return2.1
+${PACKAGE}FILES+=		return3.1
+${PACKAGE}FILES+=		return4.0
+${PACKAGE}FILES+=		return5.0
+${PACKAGE}FILES+=		return6.4
+${PACKAGE}FILES+=		return7.4
+${PACKAGE}FILES+=		return8.0
+${PACKAGE}FILES+=		set1.0
+${PACKAGE}FILES+=		set2.0
+${PACKAGE}FILES+=		set3.0
+${PACKAGE}FILES+=		trap1.0
+${PACKAGE}FILES+=		trap10.0
+${PACKAGE}FILES+=		trap11.0
+${PACKAGE}FILES+=		trap12.0
+${PACKAGE}FILES+=		trap13.0
+${PACKAGE}FILES+=		trap14.0
+${PACKAGE}FILES+=		trap15.0
+${PACKAGE}FILES+=		trap16.0
+${PACKAGE}FILES+=		trap17.0
+${PACKAGE}FILES+=		trap2.0
+${PACKAGE}FILES+=		trap3.0
+${PACKAGE}FILES+=		trap4.0
+${PACKAGE}FILES+=		trap5.0
+${PACKAGE}FILES+=		trap6.0
+${PACKAGE}FILES+=		trap7.0
+${PACKAGE}FILES+=		trap8.0
+${PACKAGE}FILES+=		trap9.0
+${PACKAGE}FILES+=		type1.0 type1.0.stderr
+${PACKAGE}FILES+=		type2.0
+${PACKAGE}FILES+=		type3.0
+${PACKAGE}FILES+=		unalias.0
+${PACKAGE}FILES+=		var-assign.0
+${PACKAGE}FILES+=		var-assign2.0
+${PACKAGE}FILES+=		wait1.0
+${PACKAGE}FILES+=		wait2.0
+${PACKAGE}FILES+=		wait3.0
+${PACKAGE}FILES+=		wait4.0
+${PACKAGE}FILES+=		wait5.0
+${PACKAGE}FILES+=		wait6.0
+${PACKAGE}FILES+=		wait7.0
+${PACKAGE}FILES+=		wait8.0
+${PACKAGE}FILES+=		wait9.127
+${PACKAGE}FILES+=		wait10.0
+
+.include <bsd.test.mk>
diff --git a/bin/cash/tests/builtins/alias.0 b/bin/cash/tests/builtins/alias.0
new file mode 100644
index 00000000..7a4864fe
--- /dev/null
+++ b/bin/cash/tests/builtins/alias.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/alias.0 190285 2009-03-22 21:12:00Z stefanf $
+set -e
+
+unalias -a
+alias foo=bar
+alias bar=
+alias quux="1 2 3"
+alias
+alias foo
diff --git a/bin/cash/tests/builtins/alias.0.stdout b/bin/cash/tests/builtins/alias.0.stdout
new file mode 100644
index 00000000..52efaf0b
--- /dev/null
+++ b/bin/cash/tests/builtins/alias.0.stdout
@@ -0,0 +1,4 @@
+bar=''
+foo=bar
+quux='1 2 3'
+foo=bar
diff --git a/bin/cash/tests/builtins/alias.1 b/bin/cash/tests/builtins/alias.1
new file mode 100644
index 00000000..176ce71e
--- /dev/null
+++ b/bin/cash/tests/builtins/alias.1
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/alias.1 149781 2005-09-04 11:59:59Z stefanf $
+unalias -a
+alias foo
diff --git a/bin/cash/tests/builtins/alias.1.stderr b/bin/cash/tests/builtins/alias.1.stderr
new file mode 100644
index 00000000..c9f4011b
--- /dev/null
+++ b/bin/cash/tests/builtins/alias.1.stderr
@@ -0,0 +1 @@
+alias: foo: not found
diff --git a/bin/cash/tests/builtins/alias3.0 b/bin/cash/tests/builtins/alias3.0
new file mode 100644
index 00000000..3185e37e
--- /dev/null
+++ b/bin/cash/tests/builtins/alias3.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/alias3.0 242767 2012-11-08 13:36:19Z jilles $
+set -e
+
+unalias -a
+alias foo=bar
+alias bar=
+alias quux="1 2 3"
+alias foo=bar
+alias bar=
+alias quux="1 2 3"
+alias
+alias foo
diff --git a/bin/cash/tests/builtins/alias3.0.stdout b/bin/cash/tests/builtins/alias3.0.stdout
new file mode 100644
index 00000000..52efaf0b
--- /dev/null
+++ b/bin/cash/tests/builtins/alias3.0.stdout
@@ -0,0 +1,4 @@
+bar=''
+foo=bar
+quux='1 2 3'
+foo=bar
diff --git a/bin/cash/tests/builtins/alias4.0 b/bin/cash/tests/builtins/alias4.0
new file mode 100644
index 00000000..b445c1b1
--- /dev/null
+++ b/bin/cash/tests/builtins/alias4.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/alias4.0 254849 2013-08-25 11:42:53Z jilles $
+
+unalias -a
+alias --
diff --git a/bin/cash/tests/builtins/break1.0 b/bin/cash/tests/builtins/break1.0
new file mode 100644
index 00000000..2d52d18a
--- /dev/null
+++ b/bin/cash/tests/builtins/break1.0
@@ -0,0 +1,16 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break1.0 211349 2010-08-15 21:06:53Z jilles $
+
+if [ "$1" != nested ]; then
+	while :; do
+		set -- nested
+		. "$0"
+		echo bad2
+		exit 2
+	done
+	exit 0
+fi
+# To trigger the bug, the following commands must be at the top level,
+# with newlines in between.
+break
+echo bad1
+exit 1
diff --git a/bin/cash/tests/builtins/break2.0 b/bin/cash/tests/builtins/break2.0
new file mode 100644
index 00000000..1ae7c91e
--- /dev/null
+++ b/bin/cash/tests/builtins/break2.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break2.0 211467 2010-08-18 20:26:50Z jilles $
+
+# It is not immediately obvious that this should work, and someone probably
+# relies on it.
+
+while :; do
+	trap 'break' USR1
+	kill -USR1 $$
+	echo bad
+	exit 1
+done
+echo good
diff --git a/bin/cash/tests/builtins/break2.0.stdout b/bin/cash/tests/builtins/break2.0.stdout
new file mode 100644
index 00000000..12799ccb
--- /dev/null
+++ b/bin/cash/tests/builtins/break2.0.stdout
@@ -0,0 +1 @@
+good
diff --git a/bin/cash/tests/builtins/break3.0 b/bin/cash/tests/builtins/break3.0
new file mode 100644
index 00000000..8a239be6
--- /dev/null
+++ b/bin/cash/tests/builtins/break3.0
@@ -0,0 +1,15 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break3.0 211612 2010-08-22 11:07:46Z jilles $
+
+# We accept this and people might rely on it.
+# However, various other shells do not accept it.
+
+f() {
+	break
+	echo bad1
+}
+
+while :; do
+	f
+	echo bad2
+	exit 2
+done
diff --git a/bin/cash/tests/builtins/break4.4 b/bin/cash/tests/builtins/break4.4
new file mode 100644
index 00000000..cfd3449d
--- /dev/null
+++ b/bin/cash/tests/builtins/break4.4
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break4.4 251180 2013-05-31 14:45:25Z jilles $
+
+# Although this is not specified by POSIX, some configure scripts (gawk 4.1.0)
+# appear to depend on it.
+
+break
+exit 4
diff --git a/bin/cash/tests/builtins/break5.4 b/bin/cash/tests/builtins/break5.4
new file mode 100644
index 00000000..b1e3b8e1
--- /dev/null
+++ b/bin/cash/tests/builtins/break5.4
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break5.4 251180 2013-05-31 14:45:25Z jilles $
+
+# Although this is not specified by POSIX, some configure scripts (gawk 4.1.0)
+# appear to depend on it.
+# In some uncommitted code, the subshell environment corrupted the outer
+# shell environment's state.
+
+(for i in a b c; do
+	exit 3
+done)
+break
+exit 4
diff --git a/bin/cash/tests/builtins/break6.0 b/bin/cash/tests/builtins/break6.0
new file mode 100644
index 00000000..a803aaff
--- /dev/null
+++ b/bin/cash/tests/builtins/break6.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/break6.0 268927 2014-07-20 20:29:09Z jilles $
+# Per POSIX, this need only work if LONG_MAX > 4294967295.
+
+while :; do
+	break 4294967296
+	echo bad
+	exit 3
+done
diff --git a/bin/cash/tests/builtins/builtin1.0 b/bin/cash/tests/builtins/builtin1.0
new file mode 100644
index 00000000..3f419c2e
--- /dev/null
+++ b/bin/cash/tests/builtins/builtin1.0
@@ -0,0 +1,31 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/builtin1.0 201431 2010-01-03 15:01:38Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "[ $* ]"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+builtin : || echo "Bad return code at $LINENO"
+builtin true || echo "Bad return code at $LINENO"
+builtin ls 2>/dev/null && echo "Bad return code at $LINENO"
+check '"$(builtin pwd)" = "$(pwd)"'
+check '-z "$(builtin :)"'
+check '-z "$(builtin true)"'
+check '-z "$( (builtin nosuchtool) 2>/dev/null)"'
+check '-z "$(builtin nosuchtool 2>/dev/null)"'
+check '-z "$(builtin nosuchtool 2>/dev/null; :)"'
+check '-z "$( (builtin ls) 2>/dev/null)"'
+check '-z "$(builtin ls 2>/dev/null)"'
+check '-z "$(builtin ls 2>/dev/null; :)"'
+check '-n "$( (builtin nosuchtool) 2>&1)"'
+check '-n "$(builtin nosuchtool 2>&1)"'
+check '-n "$(builtin nosuchtool 2>&1; :)"'
+check '-n "$( (builtin ls) 2>&1)"'
+check '-n "$(builtin ls 2>&1)"'
+check '-n "$(builtin ls 2>&1; :)"'
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/case1.0 b/bin/cash/tests/builtins/case1.0
new file mode 100644
index 00000000..6c050c62
--- /dev/null
+++ b/bin/cash/tests/builtins/case1.0
@@ -0,0 +1,13 @@
+#$FreeBSD: releng/12.0/bin/sh/tests/builtins/case1.0 172440 2007-10-04 16:14:48Z stefanf $
+f()
+{
+	false
+	case $1 in
+	foo) true ;;
+	bar) false ;;
+	esac
+}
+
+f foo || exit 1
+f bar && exit 1
+f quux || exit 1
diff --git a/bin/cash/tests/builtins/case10.0 b/bin/cash/tests/builtins/case10.0
new file mode 100644
index 00000000..e53576e4
--- /dev/null
+++ b/bin/cash/tests/builtins/case10.0
@@ -0,0 +1,16 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case10.0 223546 2011-06-25 20:37:43Z jilles $
+
+case ! in
+[\!!]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case ! in
+['!'!]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case ! in
+["!"!]) ;;
+*) echo Failed at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case11.0 b/bin/cash/tests/builtins/case11.0
new file mode 100644
index 00000000..01c0080a
--- /dev/null
+++ b/bin/cash/tests/builtins/case11.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case11.0 228007 2011-11-26 22:28:25Z jilles $
+
+false
+case x in
+*)
+esac
diff --git a/bin/cash/tests/builtins/case12.0 b/bin/cash/tests/builtins/case12.0
new file mode 100644
index 00000000..2d96c740
--- /dev/null
+++ b/bin/cash/tests/builtins/case12.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case12.0 228007 2011-11-26 22:28:25Z jilles $
+
+false
+case x in
+y)
+esac
diff --git a/bin/cash/tests/builtins/case13.0 b/bin/cash/tests/builtins/case13.0
new file mode 100644
index 00000000..37a8ffbe
--- /dev/null
+++ b/bin/cash/tests/builtins/case13.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case13.0 228943 2011-12-28 23:51:17Z jilles $
+
+case ^ in
+[\^^]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case s in
+[\^^]) echo Failed at $LINENO ;;
+[s\]]) ;;
+*) echo Failed at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case14.0 b/bin/cash/tests/builtins/case14.0
new file mode 100644
index 00000000..49387625
--- /dev/null
+++ b/bin/cash/tests/builtins/case14.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case14.0 230154 2012-01-15 20:04:05Z jilles $
+
+case `false` in
+no) exit 3 ;;
+esac
diff --git a/bin/cash/tests/builtins/case15.0 b/bin/cash/tests/builtins/case15.0
new file mode 100644
index 00000000..6ca773ff
--- /dev/null
+++ b/bin/cash/tests/builtins/case15.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case15.0 230154 2012-01-15 20:04:05Z jilles $
+
+case x in
+`false`) exit 3 ;;
+esac
diff --git a/bin/cash/tests/builtins/case16.0 b/bin/cash/tests/builtins/case16.0
new file mode 100644
index 00000000..e6431cc4
--- /dev/null
+++ b/bin/cash/tests/builtins/case16.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case16.0 230154 2012-01-15 20:04:05Z jilles $
+
+f() { return 42; }
+f
+case x in
+x) [ $? = 42 ] ;;
+esac
diff --git a/bin/cash/tests/builtins/case17.0 b/bin/cash/tests/builtins/case17.0
new file mode 100644
index 00000000..be0827c6
--- /dev/null
+++ b/bin/cash/tests/builtins/case17.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case17.0 230161 2012-01-15 21:39:38Z jilles $
+
+! case x in x) false ;& y) esac
diff --git a/bin/cash/tests/builtins/case18.0 b/bin/cash/tests/builtins/case18.0
new file mode 100644
index 00000000..590fe8d9
--- /dev/null
+++ b/bin/cash/tests/builtins/case18.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case18.0 230161 2012-01-15 21:39:38Z jilles $
+
+case x$(false) in
+x)	;&
+y)	[ $? != 0 ] ;;
+z)	false ;;
+esac
diff --git a/bin/cash/tests/builtins/case19.0 b/bin/cash/tests/builtins/case19.0
new file mode 100644
index 00000000..f3496369
--- /dev/null
+++ b/bin/cash/tests/builtins/case19.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case19.0 230161 2012-01-15 21:39:38Z jilles $
+
+[ "`case x in
+x)	false ;&
+y)	;&
+z)	echo $? ;;
+esac`" != 0 ]
diff --git a/bin/cash/tests/builtins/case2.0 b/bin/cash/tests/builtins/case2.0
new file mode 100644
index 00000000..cc737f42
--- /dev/null
+++ b/bin/cash/tests/builtins/case2.0
@@ -0,0 +1,106 @@
+# Generated by ./test-fnmatch -s 1, do not edit.
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case2.0 207821 2010-05-09 16:15:40Z jilles $
+failures=
+failed() { printf '%s\n' "Failed: $1 '$2' '$3'"; failures=x$failures; }
+testmatch() { eval "case \$2 in ''$1) ;; *) failed testmatch \"\$@\";; esac"; }
+testnomatch() { eval "case \$2 in ''$1) failed testnomatch \"\$@\";; esac"; }
+testmatch '' ''
+testmatch 'a' 'a'
+testnomatch 'a' 'b'
+testnomatch 'a' 'A'
+testmatch '*' 'a'
+testmatch '*' 'aa'
+testmatch '*a' 'a'
+testnomatch '*a' 'b'
+testnomatch '*a*' 'b'
+testmatch '*a*b*' 'ab'
+testmatch '*a*b*' 'qaqbq'
+testmatch '*a*bb*' 'qaqbqbbq'
+testmatch '*a*bc*' 'qaqbqbcq'
+testmatch '*a*bb*' 'qaqbqbb'
+testmatch '*a*bc*' 'qaqbqbc'
+testmatch '*a*bb' 'qaqbqbb'
+testmatch '*a*bc' 'qaqbqbc'
+testnomatch '*a*bb' 'qaqbqbbq'
+testnomatch '*a*bc' 'qaqbqbcq'
+testnomatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaa'
+testmatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaaa'
+testmatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaaaa'
+testnomatch '.*.*.*.*.*.*.*.*.*.*' '.........'
+testmatch '.*.*.*.*.*.*.*.*.*.*' '..........'
+testmatch '.*.*.*.*.*.*.*.*.*.*' '...........'
+testnomatch '*?*?*?*?*?*?*?*?*?*?*' '123456789'
+testnomatch '??????????*' '123456789'
+testnomatch '*??????????' '123456789'
+testmatch '*?*?*?*?*?*?*?*?*?*?*' '1234567890'
+testmatch '??????????*' '1234567890'
+testmatch '*??????????' '1234567890'
+testmatch '*?*?*?*?*?*?*?*?*?*?*' '12345678901'
+testmatch '??????????*' '12345678901'
+testmatch '*??????????' '12345678901'
+testmatch '[x]' 'x'
+testmatch '[*]' '*'
+testmatch '[?]' '?'
+testmatch '[' '['
+testmatch '[[]' '['
+testnomatch '[[]' 'x'
+testnomatch '[*]' ''
+testnomatch '[*]' 'x'
+testnomatch '[?]' 'x'
+testmatch '*[*]*' 'foo*foo'
+testnomatch '*[*]*' 'foo'
+testmatch '[0-9]' '0'
+testmatch '[0-9]' '5'
+testmatch '[0-9]' '9'
+testnomatch '[0-9]' '/'
+testnomatch '[0-9]' ':'
+testnomatch '[0-9]' '*'
+testnomatch '[!0-9]' '0'
+testnomatch '[!0-9]' '5'
+testnomatch '[!0-9]' '9'
+testmatch '[!0-9]' '/'
+testmatch '[!0-9]' ':'
+testmatch '[!0-9]' '*'
+testmatch '*[0-9]' 'a0'
+testmatch '*[0-9]' 'a5'
+testmatch '*[0-9]' 'a9'
+testnomatch '*[0-9]' 'a/'
+testnomatch '*[0-9]' 'a:'
+testnomatch '*[0-9]' 'a*'
+testnomatch '*[!0-9]' 'a0'
+testnomatch '*[!0-9]' 'a5'
+testnomatch '*[!0-9]' 'a9'
+testmatch '*[!0-9]' 'a/'
+testmatch '*[!0-9]' 'a:'
+testmatch '*[!0-9]' 'a*'
+testmatch '*[0-9]' 'a00'
+testmatch '*[0-9]' 'a55'
+testmatch '*[0-9]' 'a99'
+testmatch '*[0-9]' 'a0a0'
+testmatch '*[0-9]' 'a5a5'
+testmatch '*[0-9]' 'a9a9'
+testmatch '\*' '*'
+testmatch '\?' '?'
+testmatch '\[x]' '[x]'
+testmatch '\[' '['
+testmatch '\\' '\'
+testmatch '*\**' 'foo*foo'
+testnomatch '*\**' 'foo'
+testmatch '*\\*' 'foo\foo'
+testnomatch '*\\*' 'foo'
+testmatch '\(' '('
+testmatch '\a' 'a'
+testnomatch '\*' 'a'
+testnomatch '\?' 'a'
+testnomatch '\*' '\*'
+testnomatch '\?' '\?'
+testnomatch '\[x]' '\[x]'
+testnomatch '\[x]' '\x'
+testnomatch '\[' '\['
+testnomatch '\(' '\('
+testnomatch '\a' '\a'
+testmatch '.*' '.'
+testmatch '.*' '..'
+testmatch '.*' '.a'
+testmatch 'a*' 'a.'
+[ -z "$failures" ]
diff --git a/bin/cash/tests/builtins/case20.0 b/bin/cash/tests/builtins/case20.0
new file mode 100644
index 00000000..32f46bc1
--- /dev/null
+++ b/bin/cash/tests/builtins/case20.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case20.0 287148 2015-08-25 21:55:15Z jilles $
+
+# Shells do not agree about what this pattern should match, but it is
+# certain that it must not crash and the missing close bracket must not
+# be simply ignored.
+
+case B in
+[[:alpha:]) echo bad ;;
+esac
diff --git a/bin/cash/tests/builtins/case21.0 b/bin/cash/tests/builtins/case21.0
new file mode 100644
index 00000000..ec8089f0
--- /dev/null
+++ b/bin/cash/tests/builtins/case21.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case21.0 318258 2017-05-13 20:28:32Z jilles $
+
+case 5 in
+[0$((-9))]) ;;
+*) echo bad1 ;;
+esac
+
+case - in
+[0$((-9))]) echo bad2 ;;
+esac
diff --git a/bin/cash/tests/builtins/case22.0 b/bin/cash/tests/builtins/case22.0
new file mode 100644
index 00000000..c80dc017
--- /dev/null
+++ b/bin/cash/tests/builtins/case22.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case22.0 318269 2017-05-14 13:14:19Z jilles $
+
+case 5 in
+[0"$((-9))"]) echo bad1 ;;
+esac
+
+case - in
+[0"$((-9))"]) ;;
+*) echo bad2 ;;
+esac
diff --git a/bin/cash/tests/builtins/case23.0 b/bin/cash/tests/builtins/case23.0
new file mode 100644
index 00000000..c0f36562
--- /dev/null
+++ b/bin/cash/tests/builtins/case23.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case23.0 333092 2018-04-29 17:46:08Z jilles $
+
+case [ in
+[[:alpha:]]) echo bad
+esac
diff --git a/bin/cash/tests/builtins/case3.0 b/bin/cash/tests/builtins/case3.0
new file mode 100644
index 00000000..4eb688fe
--- /dev/null
+++ b/bin/cash/tests/builtins/case3.0
@@ -0,0 +1,95 @@
+# Generated by ./test-fnmatch -s 2, do not edit.
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case3.0 207821 2010-05-09 16:15:40Z jilles $
+failures=
+failed() { printf '%s\n' "Failed: $1 '$2' '$3'"; failures=x$failures; }
+# We do not treat a backslash specially in this case,
+# but this is not the case in all shells.
+netestmatch() { case $2 in $1) ;; *) failed netestmatch "$@";; esac; }
+netestnomatch() { case $2 in $1) failed netestnomatch "$@";; esac; }
+netestmatch '' ''
+netestmatch 'a' 'a'
+netestnomatch 'a' 'b'
+netestnomatch 'a' 'A'
+netestmatch '*' 'a'
+netestmatch '*' 'aa'
+netestmatch '*a' 'a'
+netestnomatch '*a' 'b'
+netestnomatch '*a*' 'b'
+netestmatch '*a*b*' 'ab'
+netestmatch '*a*b*' 'qaqbq'
+netestmatch '*a*bb*' 'qaqbqbbq'
+netestmatch '*a*bc*' 'qaqbqbcq'
+netestmatch '*a*bb*' 'qaqbqbb'
+netestmatch '*a*bc*' 'qaqbqbc'
+netestmatch '*a*bb' 'qaqbqbb'
+netestmatch '*a*bc' 'qaqbqbc'
+netestnomatch '*a*bb' 'qaqbqbbq'
+netestnomatch '*a*bc' 'qaqbqbcq'
+netestnomatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaa'
+netestmatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaaa'
+netestmatch '*a*a*a*a*a*a*a*a*a*a*' 'aaaaaaaaaaa'
+netestnomatch '.*.*.*.*.*.*.*.*.*.*' '.........'
+netestmatch '.*.*.*.*.*.*.*.*.*.*' '..........'
+netestmatch '.*.*.*.*.*.*.*.*.*.*' '...........'
+netestnomatch '*?*?*?*?*?*?*?*?*?*?*' '123456789'
+netestnomatch '??????????*' '123456789'
+netestnomatch '*??????????' '123456789'
+netestmatch '*?*?*?*?*?*?*?*?*?*?*' '1234567890'
+netestmatch '??????????*' '1234567890'
+netestmatch '*??????????' '1234567890'
+netestmatch '*?*?*?*?*?*?*?*?*?*?*' '12345678901'
+netestmatch '??????????*' '12345678901'
+netestmatch '*??????????' '12345678901'
+netestmatch '[x]' 'x'
+netestmatch '[*]' '*'
+netestmatch '[?]' '?'
+netestmatch '[' '['
+netestmatch '[[]' '['
+netestnomatch '[[]' 'x'
+netestnomatch '[*]' ''
+netestnomatch '[*]' 'x'
+netestnomatch '[?]' 'x'
+netestmatch '*[*]*' 'foo*foo'
+netestnomatch '*[*]*' 'foo'
+netestmatch '[0-9]' '0'
+netestmatch '[0-9]' '5'
+netestmatch '[0-9]' '9'
+netestnomatch '[0-9]' '/'
+netestnomatch '[0-9]' ':'
+netestnomatch '[0-9]' '*'
+netestnomatch '[!0-9]' '0'
+netestnomatch '[!0-9]' '5'
+netestnomatch '[!0-9]' '9'
+netestmatch '[!0-9]' '/'
+netestmatch '[!0-9]' ':'
+netestmatch '[!0-9]' '*'
+netestmatch '*[0-9]' 'a0'
+netestmatch '*[0-9]' 'a5'
+netestmatch '*[0-9]' 'a9'
+netestnomatch '*[0-9]' 'a/'
+netestnomatch '*[0-9]' 'a:'
+netestnomatch '*[0-9]' 'a*'
+netestnomatch '*[!0-9]' 'a0'
+netestnomatch '*[!0-9]' 'a5'
+netestnomatch '*[!0-9]' 'a9'
+netestmatch '*[!0-9]' 'a/'
+netestmatch '*[!0-9]' 'a:'
+netestmatch '*[!0-9]' 'a*'
+netestmatch '*[0-9]' 'a00'
+netestmatch '*[0-9]' 'a55'
+netestmatch '*[0-9]' 'a99'
+netestmatch '*[0-9]' 'a0a0'
+netestmatch '*[0-9]' 'a5a5'
+netestmatch '*[0-9]' 'a9a9'
+netestmatch '\*' '\*'
+netestmatch '\?' '\?'
+netestmatch '\' '\'
+netestnomatch '\\' '\'
+netestmatch '\\' '\\'
+netestmatch '*\*' 'foo\foo'
+netestnomatch '*\*' 'foo'
+netestmatch '.*' '.'
+netestmatch '.*' '..'
+netestmatch '.*' '.a'
+netestmatch 'a*' 'a.'
+[ -z "$failures" ]
diff --git a/bin/cash/tests/builtins/case4.0 b/bin/cash/tests/builtins/case4.0
new file mode 100644
index 00000000..c900630b
--- /dev/null
+++ b/bin/cash/tests/builtins/case4.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case4.0 220654 2011-04-15 15:14:58Z jilles $
+
+set -- "*"
+case x in
+"$1") echo failed ;;
+esac
diff --git a/bin/cash/tests/builtins/case5.0 b/bin/cash/tests/builtins/case5.0
new file mode 100644
index 00000000..a1dce3d3
--- /dev/null
+++ b/bin/cash/tests/builtins/case5.0
@@ -0,0 +1,57 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case5.0 221646 2011-05-08 11:32:20Z jilles $
+
+unset LC_ALL
+LC_CTYPE=en_US.UTF-8
+export LC_CTYPE
+
+c1=e
+# a umlaut
+c2=$(printf '\303\244')
+# euro sign
+c3=$(printf '\342\202\254')
+# some sort of 't' outside BMP
+c4=$(printf '\360\235\225\245')
+
+ok=0
+case $c1$c2$c3$c4 in
+*) ok=1 ;;
+esac
+if [ $ok = 0 ]; then
+	echo wrong at $LINENO
+	exit 3
+fi
+
+case $c1$c2$c3$c4 in
+$c1$c2$c3$c4) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+"$c1$c2$c3$c4") ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+????) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1.$c2.$c3.$c4 in
+?.?.?.?) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+[!a][!b][!c][!d]) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+[$c1][$c2][$c3][$c4]) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+["$c1"]["$c2"]["$c3"]["$c4"]) ;;
+*) echo wrong at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case6.0 b/bin/cash/tests/builtins/case6.0
new file mode 100644
index 00000000..38557bc1
--- /dev/null
+++ b/bin/cash/tests/builtins/case6.0
@@ -0,0 +1,52 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case6.0 223007 2011-06-12 12:27:17Z jilles $
+
+unset LC_ALL
+LC_CTYPE=de_DE.ISO8859-1
+export LC_CTYPE
+
+c1=e
+# o umlaut
+c2=$(printf '\366')
+# non-break space
+c3=$(printf '\240')
+c4=$(printf '\240')
+# $c2$c3$c4 form one utf-8 character
+
+ok=0
+case $c1$c2$c3$c4 in
+*) ok=1 ;;
+esac
+if [ $ok = 0 ]; then
+	echo wrong at $LINENO
+	exit 3
+fi
+
+case $c1$c2$c3$c4 in
+$c1$c2$c3$c4) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+"$c1$c2$c3$c4") ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+????) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+[!$c2][!b][!c][!d]) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+[$c1][$c2][$c3][$c4]) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2$c3$c4 in
+["$c1"]["$c2"]["$c3"]["$c4"]) ;;
+*) echo wrong at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case7.0 b/bin/cash/tests/builtins/case7.0
new file mode 100644
index 00000000..35978e5c
--- /dev/null
+++ b/bin/cash/tests/builtins/case7.0
@@ -0,0 +1,24 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case7.0 302829 2016-07-14 09:34:42Z ache $
+
+# Character ranges in a locale other than the POSIX locale, not specified
+# by POSIX.
+
+unset LC_ALL
+LC_CTYPE=de_DE.ISO8859-1
+export LC_CTYPE
+LC_COLLATE=de_DE.ISO8859-1
+export LC_COLLATE
+
+c1=e
+# o umlaut
+c2=$(printf '\366')
+
+case $c1$c2 in
+[a-z][a-z]) ;;
+*) echo wrong at $LINENO ;;
+esac
+
+case $c1$c2 in
+[a-f][n-p]) ;;
+*) echo wrong at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case8.0 b/bin/cash/tests/builtins/case8.0
new file mode 100644
index 00000000..22c31111
--- /dev/null
+++ b/bin/cash/tests/builtins/case8.0
@@ -0,0 +1,32 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case8.0 223120 2011-06-15 21:48:10Z jilles $
+
+case aZ_ in
+[[:alpha:]_][[:upper:]_][[:alpha:]_]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case ' ' in
+[[:alpha:][:digit:]]) echo Failed at $LINENO ;;
+[![:alpha:][:digit:]]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case '.X.' in
+*[[:lower:]]*) echo Failed at $LINENO ;;
+*[[:upper:]]*) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case ' ' in
+[![:print:]]) echo Failed at $LINENO ;;
+[![:alnum:][:punct:]]) ;;
+*) echo Failed at $LINENO ;;
+esac
+
+case '
+' in
+[[:print:]]) echo Failed at $LINENO ;;
+['
+'[:digit:]]) ;;
+*) echo Failed at $LINENO ;;
+esac
diff --git a/bin/cash/tests/builtins/case9.0 b/bin/cash/tests/builtins/case9.0
new file mode 100644
index 00000000..c7b05bd8
--- /dev/null
+++ b/bin/cash/tests/builtins/case9.0
@@ -0,0 +1,39 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/case9.0 223186 2011-06-17 13:03:49Z jilles $
+
+errors=0
+
+f() {
+	result=
+	case $1 in
+	a) result=${result}a ;;
+	b) result=${result}b ;&
+	c) result=${result}c ;&
+	d) result=${result}d ;;
+	e) result=${result}e ;&
+	esac
+}
+
+check() {
+	f "$1"
+	if [ "$result" != "$2" ]; then
+		printf "For %s, expected %s got %s\n" "$1" "$2" "$result"
+		errors=$((errors + 1))
+	fi
+}
+
+check '' ''
+check a a
+check b bcd
+check c cd
+check d d
+check e e
+
+if ! (case 1 in
+	1) false ;&
+	2) true ;;
+esac) then
+	echo "Subshell bad"
+	errors=$((errors + 1))
+fi
+
+exit $((errors != 0))
diff --git a/bin/cash/tests/builtins/cd1.0 b/bin/cash/tests/builtins/cd1.0
new file mode 100644
index 00000000..82a7d105
--- /dev/null
+++ b/bin/cash/tests/builtins/cd1.0
@@ -0,0 +1,30 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd1.0 228975 2011-12-30 00:04:11Z uqs $
+set -e
+
+P=${TMPDIR:-/tmp}
+cd $P
+T=$(mktemp -d sh-test.XXXXXX)
+
+chmod 0 $T
+if [ `id -u` -ne 0 ]; then
+	# Root can always cd, regardless of directory permissions.
+	cd -L $T 2>/dev/null && exit 1
+	[ "$PWD" = "$P" ]
+	[ "$(pwd)" = "$P" ]
+	cd -P $T 2>/dev/null && exit 1
+	[ "$PWD" = "$P" ]
+	[ "$(pwd)" = "$P" ]
+fi
+
+chmod 755 $T
+cd $T
+mkdir -p 1/2/3
+ln -s 1/2 link1
+ln -s 2/3 1/link2
+(cd -L 1/../1 && [ "$(pwd -L)" = "$P/$T/1" ])
+(cd -L link1 && [ "$(pwd -L)" = "$P/$T/link1" ])
+(cd -L link1 && [ "$(pwd -P)" = "$P/$T/1/2" ])
+(cd -P link1 && [ "$(pwd -L)" = "$P/$T/1/2" ])
+(cd -P link1 && [ "$(pwd -P)" = "$P/$T/1/2" ])
+
+rm -rf ${P}/${T}
diff --git a/bin/cash/tests/builtins/cd10.0 b/bin/cash/tests/builtins/cd10.0
new file mode 100644
index 00000000..b5008ca9
--- /dev/null
+++ b/bin/cash/tests/builtins/cd10.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd10.0 320340 2017-06-25 21:53:08Z jilles $
+
+# Precondition
+(cd /bin) || exit
+# Verify write error is ignored.
+$SH +m -ic 'CDPATH=/:; cd bin 1</dev/null'
diff --git a/bin/cash/tests/builtins/cd11.0 b/bin/cash/tests/builtins/cd11.0
new file mode 100644
index 00000000..191723a4
--- /dev/null
+++ b/bin/cash/tests/builtins/cd11.0
@@ -0,0 +1,24 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd11.0 336320 2018-07-15 21:55:17Z jilles $
+
+set -e
+T=$(mktemp -d "${TMPDIR:-/tmp}/sh-test.XXXXXX")
+trap 'rm -rf "$T"' 0
+
+mkdir "$T/%?^&*"
+cd -P "$T/%?^&*"
+D=$(pwd)
+
+mkdir a a/1 b b/1 b/2
+
+CDPATH=$D/a:
+# Basic test.
+cd 1 >/dev/null
+[ "$(pwd)" = "$D/a/1" ]
+# Test that the current directory is not checked before CDPATH.
+cd "$D/b"
+cd 1 >/dev/null
+[ "$(pwd)" = "$D/a/1" ]
+# Test not using a CDPATH entry.
+cd "$D/b"
+cd 2
+[ "$(pwd)" = "$D/b/2" ]
diff --git a/bin/cash/tests/builtins/cd2.0 b/bin/cash/tests/builtins/cd2.0
new file mode 100644
index 00000000..e4807875
--- /dev/null
+++ b/bin/cash/tests/builtins/cd2.0
@@ -0,0 +1,16 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd2.0 216019 2010-11-28 22:49:58Z jilles $
+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 'rm -rf ${T}' 0
+cd $T
+D=$T
+while [ ${#D} -lt $L ]; do
+	mkdir veryverylongdirectoryname
+	cd veryverylongdirectoryname
+	D=$D/veryverylongdirectoryname
+done
+[ $(pwd | wc -c) -eq $((${#D} + 1)) ] # +\n
diff --git a/bin/cash/tests/builtins/cd3.0 b/bin/cash/tests/builtins/cd3.0
new file mode 100644
index 00000000..b41caee2
--- /dev/null
+++ b/bin/cash/tests/builtins/cd3.0
@@ -0,0 +1,21 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd3.0 222154 2011-05-20 22:55:18Z jilles $
+
+# 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/bin/cash/tests/builtins/cd4.0 b/bin/cash/tests/builtins/cd4.0
new file mode 100644
index 00000000..19531321
--- /dev/null
+++ b/bin/cash/tests/builtins/cd4.0
@@ -0,0 +1,38 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd4.0 222154 2011-05-20 22:55:18Z jilles $
+
+# 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
diff --git a/bin/cash/tests/builtins/cd5.0 b/bin/cash/tests/builtins/cd5.0
new file mode 100644
index 00000000..76df7887
--- /dev/null
+++ b/bin/cash/tests/builtins/cd5.0
@@ -0,0 +1,23 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd5.0 222379 2011-05-27 19:36:07Z jilles $
+
+set -e
+T=$(mktemp -d "${TMPDIR:-/tmp}/sh-test.XXXXXX")
+trap 'rm -rf "$T"' 0
+
+cd -P "$T"
+D=$(pwd)
+
+mkdir a a/1 b b/1 b/2
+
+CDPATH=$D/a:
+# Basic test.
+cd 1 >/dev/null
+[ "$(pwd)" = "$D/a/1" ]
+# Test that the current directory is not checked before CDPATH.
+cd "$D/b"
+cd 1 >/dev/null
+[ "$(pwd)" = "$D/a/1" ]
+# Test not using a CDPATH entry.
+cd "$D/b"
+cd 2
+[ "$(pwd)" = "$D/b/2" ]
diff --git a/bin/cash/tests/builtins/cd6.0 b/bin/cash/tests/builtins/cd6.0
new file mode 100644
index 00000000..34c8955a
--- /dev/null
+++ b/bin/cash/tests/builtins/cd6.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd6.0 222381 2011-05-27 20:01:46Z jilles $
+
+set -e
+cd -P /bin
+d=$PWD
+CDPATH=/:
+cd -P .
+[ "$d" = "$PWD" ]
+cd -P ./
+[ "$d" = "$PWD" ]
diff --git a/bin/cash/tests/builtins/cd7.0 b/bin/cash/tests/builtins/cd7.0
new file mode 100644
index 00000000..2219b7b4
--- /dev/null
+++ b/bin/cash/tests/builtins/cd7.0
@@ -0,0 +1,15 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd7.0 222381 2011-05-27 20:01:46Z jilles $
+
+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 ]
diff --git a/bin/cash/tests/builtins/cd8.0 b/bin/cash/tests/builtins/cd8.0
new file mode 100644
index 00000000..5ee87ba1
--- /dev/null
+++ b/bin/cash/tests/builtins/cd8.0
@@ -0,0 +1,26 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd8.0 230095 2012-01-13 23:32:27Z jilles $
+
+# The exact wording of the error message is not standardized, but giving
+# a description of the errno is useful.
+
+LC_ALL=C
+export LC_ALL
+r=0
+
+t() {
+	exec 3>&1
+	errmsg=`cd "$1" 2>&1 >&3 3>&-`
+	exec 3>&-
+	case $errmsg in
+	*[Nn]ot\ a\ directory*)
+		;;
+	*)
+		printf "Wrong error message for %s: %s\n" "$1" "$errmsg"
+		r=3
+		;;
+	esac
+}
+
+t /dev/tty
+t /dev/tty/x
+exit $r
diff --git a/bin/cash/tests/builtins/cd9.0 b/bin/cash/tests/builtins/cd9.0
new file mode 100644
index 00000000..56afe1ec
--- /dev/null
+++ b/bin/cash/tests/builtins/cd9.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/cd9.0 293371 2016-01-07 21:46:07Z jilles $
+
+cd /dev
+cd /bin
+cd - >/dev/null
+pwd
+cd - >/dev/null
+pwd
diff --git a/bin/cash/tests/builtins/cd9.0.stdout b/bin/cash/tests/builtins/cd9.0.stdout
new file mode 100644
index 00000000..dac16a76
--- /dev/null
+++ b/bin/cash/tests/builtins/cd9.0.stdout
@@ -0,0 +1,2 @@
+/dev
+/bin
diff --git a/bin/cash/tests/builtins/command1.0 b/bin/cash/tests/builtins/command1.0
new file mode 100644
index 00000000..55f19961
--- /dev/null
+++ b/bin/cash/tests/builtins/command1.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command1.0 151797 2005-10-28 14:02:42Z stefanf $
+true() {
+	false
+}
+command true
diff --git a/bin/cash/tests/builtins/command10.0 b/bin/cash/tests/builtins/command10.0
new file mode 100644
index 00000000..71bb437a
--- /dev/null
+++ b/bin/cash/tests/builtins/command10.0
@@ -0,0 +1,14 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command10.0 204802 2010-03-06 17:31:09Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "[ $* ]"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+check '"$(f() { shift x; }; { command eval f 2>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/command11.0 b/bin/cash/tests/builtins/command11.0
new file mode 100644
index 00000000..35941fa1
--- /dev/null
+++ b/bin/cash/tests/builtins/command11.0
@@ -0,0 +1,14 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command11.0 205154 2010-03-14 14:24:35Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "[ $* ]"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+check '"$({ command eval \{ shift x\; \} 2\>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/command12.0 b/bin/cash/tests/builtins/command12.0
new file mode 100644
index 00000000..db38709c
--- /dev/null
+++ b/bin/cash/tests/builtins/command12.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command12.0 257929 2013-11-10 23:00:39Z jilles $
+
+alias aa=echo\ \'\"\'
+cmd=$(command -v aa)
+alias aa=echo\ bad
+eval "$cmd"
+[ "$(eval aa)" = \" ]
diff --git a/bin/cash/tests/builtins/command2.0 b/bin/cash/tests/builtins/command2.0
new file mode 100644
index 00000000..41cd2deb
--- /dev/null
+++ b/bin/cash/tests/builtins/command2.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command2.0 151797 2005-10-28 14:02:42Z stefanf $
+PATH=
+command -p cat < /dev/null
diff --git a/bin/cash/tests/builtins/command3.0 b/bin/cash/tests/builtins/command3.0
new file mode 100644
index 00000000..5fd8c92c
--- /dev/null
+++ b/bin/cash/tests/builtins/command3.0
@@ -0,0 +1,14 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command3.0 211399 2010-08-16 17:18:08Z jilles $
+command -v ls
+command -v true
+command -v /bin/ls
+
+fun() {
+	:
+}
+command -v fun
+command -v break
+command -v if
+
+alias foo=bar
+command -v foo
diff --git a/bin/cash/tests/builtins/command3.0.stdout b/bin/cash/tests/builtins/command3.0.stdout
new file mode 100644
index 00000000..67b86915
--- /dev/null
+++ b/bin/cash/tests/builtins/command3.0.stdout
@@ -0,0 +1,7 @@
+/bin/ls
+true
+/bin/ls
+fun
+break
+if
+alias foo=bar
diff --git a/bin/cash/tests/builtins/command4.0 b/bin/cash/tests/builtins/command4.0
new file mode 100644
index 00000000..b0306c31
--- /dev/null
+++ b/bin/cash/tests/builtins/command4.0
@@ -0,0 +1,2 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command4.0 211973 2010-08-29 20:53:24Z jilles $
+! command -v nonexisting
diff --git a/bin/cash/tests/builtins/command5.0 b/bin/cash/tests/builtins/command5.0
new file mode 100644
index 00000000..5a2c1b0b
--- /dev/null
+++ b/bin/cash/tests/builtins/command5.0
@@ -0,0 +1,15 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command5.0 211399 2010-08-16 17:18:08Z jilles $
+command -V ls
+command -V true
+command -V /bin/ls
+
+fun() {
+	:
+}
+command -V fun
+command -V break
+command -V if
+command -V {
+
+alias foo=bar
+command -V foo
diff --git a/bin/cash/tests/builtins/command5.0.stdout b/bin/cash/tests/builtins/command5.0.stdout
new file mode 100644
index 00000000..523f7b22
--- /dev/null
+++ b/bin/cash/tests/builtins/command5.0.stdout
@@ -0,0 +1,8 @@
+ls is /bin/ls
+true is a shell builtin
+/bin/ls is /bin/ls
+fun is a shell function
+break is a special shell builtin
+if is a shell keyword
+{ is a shell keyword
+foo is an alias for bar
diff --git a/bin/cash/tests/builtins/command6.0 b/bin/cash/tests/builtins/command6.0
new file mode 100644
index 00000000..747c3db0
--- /dev/null
+++ b/bin/cash/tests/builtins/command6.0
@@ -0,0 +1,22 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command6.0 218356 2011-02-05 23:00:24Z jilles $
+PATH=/var/empty
+case $(command -pV ls) in
+*/var/empty/ls*)
+	echo "Failed: \$(command -pV ls) should not match */var/empty/ls*" ;;
+"ls is"*" "/*/ls) ;;
+*)
+	echo "Failed: \$(command -pV ls) match \"ls is\"*\" \"/*/ls" ;;
+esac
+command -pV true
+command -pV /bin/ls
+
+fun() {
+	:
+}
+command -pV fun
+command -pV break
+command -pV if
+command -pV {
+
+alias foo=bar
+command -pV foo
diff --git a/bin/cash/tests/builtins/command6.0.stdout b/bin/cash/tests/builtins/command6.0.stdout
new file mode 100644
index 00000000..3180207a
--- /dev/null
+++ b/bin/cash/tests/builtins/command6.0.stdout
@@ -0,0 +1,7 @@
+true is a shell builtin
+/bin/ls is /bin/ls
+fun is a shell function
+break is a special shell builtin
+if is a shell keyword
+{ is a shell keyword
+foo is an alias for bar
diff --git a/bin/cash/tests/builtins/command7.0 b/bin/cash/tests/builtins/command7.0
new file mode 100644
index 00000000..f0621277
--- /dev/null
+++ b/bin/cash/tests/builtins/command7.0
@@ -0,0 +1,34 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command7.0 218356 2011-02-05 23:00:24Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "[ $* ]"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+check '"$(PATH=/libexec command -V ld-elf.so.1)" = "ld-elf.so.1 is /libexec/ld-elf.so.1"'
+check '"$(PATH=/libexec command -V ld-elf.so.1; :)" = "ld-elf.so.1 is /libexec/ld-elf.so.1"'
+check '"$(PATH=/libexec command -pv ld-elf.so.1)" = ""'
+check '"$(PATH=/libexec command -pv ld-elf.so.1; :)" = ""'
+
+PATH=/libexec:$PATH
+
+check '"$(command -V ld-elf.so.1)" = "ld-elf.so.1 is /libexec/ld-elf.so.1"'
+check '"$(command -V ld-elf.so.1; :)" = "ld-elf.so.1 is /libexec/ld-elf.so.1"'
+check '"$(command -pv ld-elf.so.1)" = ""'
+check '"$(command -pv ld-elf.so.1; :)" = ""'
+
+PATH=/libexec
+
+check '"$(command -v ls)" = ""'
+case $(command -pv ls) in
+/*/ls) ;;
+*)
+	echo "Failed: \$(command -pv ls) match /*/ls"
+	: $((failures += 1)) ;;
+esac
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/command8.0 b/bin/cash/tests/builtins/command8.0
new file mode 100644
index 00000000..50dfac3e
--- /dev/null
+++ b/bin/cash/tests/builtins/command8.0
@@ -0,0 +1,45 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command8.0 213738 2010-10-12 18:20:38Z obrien $
+IFS=,
+
+SPECIAL="break,\
+	:,\
+	continue,\
+	. /dev/null,\
+	eval,\
+	exec,\
+	export -p,\
+	readonly -p,\
+	set,\
+	shift 0,\
+	times,\
+	trap,\
+	unset foo"
+
+set -e
+
+# Check that special builtins can be executed via "command".
+
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+	${SH} -c "v=:; while \$v; do v=false; command ${cmd}; done" >/dev/null
+done
+
+while :; do
+	command break
+	echo Error on line $LINENO
+done
+
+set p q r
+command shift 2
+if [ $# -ne 1 ]; then
+	echo Error on line $LINENO
+fi
+
+(
+	command exec >/dev/null
+	echo Error on line $LINENO
+)
+
+set +e
+! command shift 2 2>/dev/null
diff --git a/bin/cash/tests/builtins/command9.0 b/bin/cash/tests/builtins/command9.0
new file mode 100644
index 00000000..821be0a4
--- /dev/null
+++ b/bin/cash/tests/builtins/command9.0
@@ -0,0 +1,14 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/command9.0 204801 2010-03-06 17:09:22Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "[ $* ]"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+check '"$({ command eval shift x 2>/dev/null; } >/dev/null; echo hi)" = hi'
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/dot1.0 b/bin/cash/tests/builtins/dot1.0
new file mode 100644
index 00000000..a0bf12e0
--- /dev/null
+++ b/bin/cash/tests/builtins/dot1.0
@@ -0,0 +1,21 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/dot1.0 208629 2010-05-28 22:08:34Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX) || exit
+trap 'rm -rf $T' 0
+cd $T || exit 3
+unset x
+echo 'x=2' >testscript
+. ./testscript
+[ "$x" = 2 ] || failure $LINENO
+cd / || exit 3
+x=1
+PATH=$T:$PATH . testscript
+[ "$x" = 2 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/dot2.0 b/bin/cash/tests/builtins/dot2.0
new file mode 100644
index 00000000..342e73b1
--- /dev/null
+++ b/bin/cash/tests/builtins/dot2.0
@@ -0,0 +1,21 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/dot2.0 208630 2010-05-28 22:40:24Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX) || exit
+trap 'rm -rf $T' 0
+cd $T || exit 3
+unset x
+echo 'x=2' >testscript
+. -- ./testscript
+[ "$x" = 2 ] || failure $LINENO
+cd / || exit 3
+x=1
+PATH=$T:$PATH . -- testscript
+[ "$x" = 2 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/dot3.0 b/bin/cash/tests/builtins/dot3.0
new file mode 100644
index 00000000..eb67b7b9
--- /dev/null
+++ b/bin/cash/tests/builtins/dot3.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/dot3.0 219390 2011-03-07 23:52:23Z jilles $
+
+# . should return 0 if no command was executed.
+
+if false; then
+	exit 3
+else
+	. /dev/null
+	exit $?
+fi
diff --git a/bin/cash/tests/builtins/dot4.0 b/bin/cash/tests/builtins/dot4.0
new file mode 100644
index 00000000..2b9e86ea
--- /dev/null
+++ b/bin/cash/tests/builtins/dot4.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/dot4.0 222174 2011-05-22 12:15:14Z jilles $
+
+v=abcd
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+r=$( (
+	trap 'exit 0' 0
+	. "$v"
+) 2>&1 >/dev/null) && [ -n "$r" ]
diff --git a/bin/cash/tests/builtins/echo1.0 b/bin/cash/tests/builtins/echo1.0
new file mode 100644
index 00000000..d9267817
--- /dev/null
+++ b/bin/cash/tests/builtins/echo1.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/echo1.0 305305 2016-09-02 21:13:46Z jilles $
+
+# Not specified by POSIX.
+
+[ "`echo -n a b; echo c d; echo e f`" = "a bc d
+e f" ]
diff --git a/bin/cash/tests/builtins/echo2.0 b/bin/cash/tests/builtins/echo2.0
new file mode 100644
index 00000000..ef3d606d
--- /dev/null
+++ b/bin/cash/tests/builtins/echo2.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/echo2.0 305305 2016-09-02 21:13:46Z jilles $
+
+# Not specified by POSIX.
+
+a=`echo -e '\a\b\e\f\n\r\t\v\\\\\0041\c'; echo .`
+b=`printf '\a\b\033\f\n\r\t\v\\\\!.'`
+[ "$a" = "$b" ]
diff --git a/bin/cash/tests/builtins/echo3.0 b/bin/cash/tests/builtins/echo3.0
new file mode 100644
index 00000000..018417bc
--- /dev/null
+++ b/bin/cash/tests/builtins/echo3.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/echo3.0 305305 2016-09-02 21:13:46Z jilles $
+
+# Not specified by POSIX.
+
+[ "`echo -e 'a\cb' c; echo d`" = "ad" ]
diff --git a/bin/cash/tests/builtins/eval1.0 b/bin/cash/tests/builtins/eval1.0
new file mode 100644
index 00000000..3888f1d5
--- /dev/null
+++ b/bin/cash/tests/builtins/eval1.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval1.0 193178 2009-05-31 17:23:27Z stefanf $
+set -e
+
+eval
+eval "" ""
+eval "true"
+! eval "false
+
+"
diff --git a/bin/cash/tests/builtins/eval2.0 b/bin/cash/tests/builtins/eval2.0
new file mode 100644
index 00000000..04ed57dc
--- /dev/null
+++ b/bin/cash/tests/builtins/eval2.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval2.0 194897 2009-06-24 20:22:54Z jilles $
+
+eval '
+false
+
+' && exit 1
+exit 0
diff --git a/bin/cash/tests/builtins/eval3.0 b/bin/cash/tests/builtins/eval3.0
new file mode 100644
index 00000000..89b5398a
--- /dev/null
+++ b/bin/cash/tests/builtins/eval3.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval3.0 196607 2009-08-27 22:23:23Z jilles $
+
+eval 'false;' && exit 1
+eval 'true;' || exit 1
+eval 'false;
+' && exit 1
+eval 'true;
+' || exit 1
+exit 0
diff --git a/bin/cash/tests/builtins/eval4.0 b/bin/cash/tests/builtins/eval4.0
new file mode 100644
index 00000000..111483c3
--- /dev/null
+++ b/bin/cash/tests/builtins/eval4.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval4.0 210738 2010-08-01 22:39:07Z jilles $
+
+# eval should preserve $? from command substitutions when starting
+# the parsed command.
+[ $(eval 'echo $?' $(false)) = 1 ]
diff --git a/bin/cash/tests/builtins/eval5.0 b/bin/cash/tests/builtins/eval5.0
new file mode 100644
index 00000000..056ee756
--- /dev/null
+++ b/bin/cash/tests/builtins/eval5.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval5.0 210829 2010-08-03 22:17:29Z jilles $
+
+# eval should return 0 if no command was executed.
+eval $(false)
diff --git a/bin/cash/tests/builtins/eval6.0 b/bin/cash/tests/builtins/eval6.0
new file mode 100644
index 00000000..02097c76
--- /dev/null
+++ b/bin/cash/tests/builtins/eval6.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval6.0 249220 2013-04-06 22:30:46Z jilles $
+
+# eval should preserve $? from command substitutions when starting
+# the parsed command.
+[ $(false; eval 'echo $?' $(:)) = 0 ]
diff --git a/bin/cash/tests/builtins/eval7.0 b/bin/cash/tests/builtins/eval7.0
new file mode 100644
index 00000000..36cb7c4a
--- /dev/null
+++ b/bin/cash/tests/builtins/eval7.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval7.0 272983 2014-10-12 13:12:06Z jilles $
+# Assumes that break can break out of a loop outside eval.
+
+while :; do
+	eval "break
+echo bad1"
+	echo bad2
+	exit 3
+done
diff --git a/bin/cash/tests/builtins/eval8.7 b/bin/cash/tests/builtins/eval8.7
new file mode 100644
index 00000000..12a3e37e
--- /dev/null
+++ b/bin/cash/tests/builtins/eval8.7
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/eval8.7 272983 2014-10-12 13:12:06Z jilles $
+
+f() {
+	eval "return 7
+echo bad2"
+}
+f
diff --git a/bin/cash/tests/builtins/exec1.0 b/bin/cash/tests/builtins/exec1.0
new file mode 100644
index 00000000..19f2eef1
--- /dev/null
+++ b/bin/cash/tests/builtins/exec1.0
@@ -0,0 +1,25 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/exec1.0 213738 2010-10-12 18:20:38Z obrien $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+(
+	exec >/dev/null
+	echo bad
+)
+[ $? = 0 ] || failure $LINENO
+(
+	exec ${SH} -c 'exit 42'
+	echo bad
+)
+[ $? = 42 ] || failure $LINENO
+(
+	exec /var/empty/nosuch
+	echo bad
+) 2>/dev/null
+[ $? = 127 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/exec2.0 b/bin/cash/tests/builtins/exec2.0
new file mode 100644
index 00000000..9b29bd5d
--- /dev/null
+++ b/bin/cash/tests/builtins/exec2.0
@@ -0,0 +1,25 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/exec2.0 213738 2010-10-12 18:20:38Z obrien $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+(
+	exec -- >/dev/null
+	echo bad
+)
+[ $? = 0 ] || failure $LINENO
+(
+	exec -- ${SH} -c 'exit 42'
+	echo bad
+)
+[ $? = 42 ] || failure $LINENO
+(
+	exec -- /var/empty/nosuch
+	echo bad
+) 2>/dev/null
+[ $? = 127 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/exit1.0 b/bin/cash/tests/builtins/exit1.0
new file mode 100644
index 00000000..0ca4279c
--- /dev/null
+++ b/bin/cash/tests/builtins/exit1.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/exit1.0 216871 2011-01-01 15:25:15Z jilles $
+
+# exit with an argument should overwrite the exit status in an EXIT trap.
+
+trap 'true; exit $?' 0
+false
diff --git a/bin/cash/tests/builtins/exit2.8 b/bin/cash/tests/builtins/exit2.8
new file mode 100644
index 00000000..ee747ccd
--- /dev/null
+++ b/bin/cash/tests/builtins/exit2.8
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/exit2.8 217172 2011-01-08 23:00:38Z jilles $
+
+# exit without arguments is the same as exit $? outside a trap.
+
+trap 'true; true' 0
+(exit 8)
+exit
diff --git a/bin/cash/tests/builtins/exit3.0 b/bin/cash/tests/builtins/exit3.0
new file mode 100644
index 00000000..3855919d
--- /dev/null
+++ b/bin/cash/tests/builtins/exit3.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/exit3.0 217175 2011-01-08 23:08:13Z jilles $
+
+# exit without arguments differs from exit $? in an EXIT trap.
+
+trap 'false; exit' 0
diff --git a/bin/cash/tests/builtins/export1.0 b/bin/cash/tests/builtins/export1.0
new file mode 100644
index 00000000..77a098b5
--- /dev/null
+++ b/bin/cash/tests/builtins/export1.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/export1.0 223183 2011-06-17 10:21:24Z jilles $
+
+env @badness=1 ${SH} -c 'v=`export -p`; eval "$v"'
diff --git a/bin/cash/tests/builtins/fc1.0 b/bin/cash/tests/builtins/fc1.0
new file mode 100644
index 00000000..e52e5884
--- /dev/null
+++ b/bin/cash/tests/builtins/fc1.0
@@ -0,0 +1,27 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/fc1.0 213738 2010-10-12 18:20:38Z obrien $
+set -e
+trap 'echo Broken pipe -- test failed' PIPE
+
+P=${TMPDIR:-/tmp}
+cd $P
+T=$(mktemp -d sh-test.XXXXXX)
+cd $T
+
+mkfifo input output error
+HISTFILE=/dev/null ${SH} +m -i <input >output 2>error &
+{
+	# Syntax error
+	echo ')' >&3
+	# Read error message, shell will read new input now
+	read dummy <&5
+	# Execute bad command again
+	echo 'fc -e true' >&3
+	# Verify that the shell is still running
+	echo 'echo continued' >&3 || rc=3
+	echo 'exit' >&3 || rc=3
+	read line <&4 && [ "$line" = continued ] && : ${rc:=0}
+} 3>input 4<output 5<error
+
+rm input output error
+rmdir ${P}/${T}
+exit ${rc:-3}
diff --git a/bin/cash/tests/builtins/fc2.0 b/bin/cash/tests/builtins/fc2.0
new file mode 100644
index 00000000..9abf4485
--- /dev/null
+++ b/bin/cash/tests/builtins/fc2.0
@@ -0,0 +1,34 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/fc2.0 213738 2010-10-12 18:20:38Z obrien $
+set -e
+trap 'echo Broken pipe -- test failed' PIPE
+
+P=${TMPDIR:-/tmp}
+cd $P
+T=$(mktemp -d sh-test.XXXXXX)
+cd $T
+
+mkfifo input output error
+HISTFILE=/dev/null ${SH} +m -i <input >output 2>error &
+exec 3>input
+{
+	# Command not found, containing slash
+	echo '/var/empty/nonexistent' >&3
+	# Read error message, shell will read new input now
+	read dummy <&5
+	# Execute bad command again
+	echo 'fc -e true; echo continued' >&3
+	read dummy <&5
+	read line <&4 && [ "$line" = continued ] && : ${rc:=0}
+	exec 3>&-
+	# Old sh duplicates itself after the fc, producing another line
+	# of output.
+	if read line <&4; then
+		echo "Extraneous output: $line"
+		rc=1
+	fi
+} 4<output 5<error
+exec 3>&-
+
+rm input output error
+rmdir ${P}/${T}
+exit ${rc:-3}
diff --git a/bin/cash/tests/builtins/for1.0 b/bin/cash/tests/builtins/for1.0
new file mode 100644
index 00000000..51e01e48
--- /dev/null
+++ b/bin/cash/tests/builtins/for1.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/for1.0 226892 2011-10-28 23:02:21Z jilles $
+
+false
+for i in `false`; do exit 3; done
diff --git a/bin/cash/tests/builtins/for2.0 b/bin/cash/tests/builtins/for2.0
new file mode 100644
index 00000000..ab10d9ae
--- /dev/null
+++ b/bin/cash/tests/builtins/for2.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/for2.0 230463 2012-01-22 14:00:33Z jilles $
+
+r=x
+f() { return 42; }
+f
+for i in x; do
+	r=$?
+done
+[ "$r" = 42 ]
diff --git a/bin/cash/tests/builtins/for3.0 b/bin/cash/tests/builtins/for3.0
new file mode 100644
index 00000000..f42cb958
--- /dev/null
+++ b/bin/cash/tests/builtins/for3.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/for3.0 230463 2012-01-22 14:00:33Z jilles $
+
+r=x
+f() { return 42; }
+for i in x`f`; do
+	r=$?
+done
+[ "$r" = 42 ]
diff --git a/bin/cash/tests/builtins/getopts1.0 b/bin/cash/tests/builtins/getopts1.0
new file mode 100644
index 00000000..ceca459f
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts1.0
@@ -0,0 +1,25 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts1.0 297752 2016-04-09 16:06:13Z jilles $
+
+printf -- '-1-\n'
+set -- -abc
+getopts "ab:" OPTION
+printf '%s\n' "${OPTION}"
+
+# In this case 'getopts' should realize that we have not provided the
+# required argument for "-b".
+# Note that Solaris 10's (UNIX 03) /usr/xpg4/bin/sh, /bin/sh, and /bin/ksh;
+# ksh93 20090505; pdksh 5.2.14p2; mksh R39c; bash 4.1 PL7; and zsh 4.3.10.
+# all recognize that "b" is missing its argument on the *first* iteration
+# of 'getopts' and do not produce the "a" in $OPTION.
+printf -- '-2-\n'
+set -- -ab
+getopts "ab:" OPTION
+printf '%s\n' "${OPTION}"
+getopts "ab:" OPTION 3>&2 2>&1 >&3 3>&-
+printf '%s\n' "${OPTION}"
+
+# The 'shift' is aimed at causing an error.
+printf -- '-3-\n'
+shift 1
+getopts "ab:" OPTION
+printf '%s\n' "${OPTION}"
diff --git a/bin/cash/tests/builtins/getopts1.0.stdout b/bin/cash/tests/builtins/getopts1.0.stdout
new file mode 100644
index 00000000..a0a347ee
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts1.0.stdout
@@ -0,0 +1,8 @@
+-1-
+a
+-2-
+a
+No arg for -b option
+?
+-3-
+?
diff --git a/bin/cash/tests/builtins/getopts10.0 b/bin/cash/tests/builtins/getopts10.0
new file mode 100644
index 00000000..59508f9e
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts10.0
@@ -0,0 +1,11 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts10.0 293359 2016-01-07 20:48:24Z jilles $
+
+set -- -x arg
+opt=not
+getopts x opt
+r1=$? OPTIND1=$OPTIND opt1=$opt
+: $(: $((OPTIND = 1)))
+getopts x opt
+r2=$? OPTIND2=$OPTIND
+[ "$r1" = 0 ] && [ "$OPTIND1" = 2 ] && [ "$opt1" = x ] && [ "$r2" != 0 ] &&
+	[ "$OPTIND2" = 2 ]
diff --git a/bin/cash/tests/builtins/getopts2.0 b/bin/cash/tests/builtins/getopts2.0
new file mode 100644
index 00000000..9e26a7d9
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts2.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts2.0 297752 2016-04-09 16:06:13Z jilles $
+set - -ax
+getopts ax option
+set -C
+getopts ax option
+printf '%s\n' "$option"
diff --git a/bin/cash/tests/builtins/getopts2.0.stdout b/bin/cash/tests/builtins/getopts2.0.stdout
new file mode 100644
index 00000000..587be6b4
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts2.0.stdout
@@ -0,0 +1 @@
+x
diff --git a/bin/cash/tests/builtins/getopts3.0 b/bin/cash/tests/builtins/getopts3.0
new file mode 100644
index 00000000..428ad5c3
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts3.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts3.0 265616 2014-05-07 21:45:25Z jilles $
+
+shift $#
+getopts x opt
+r=$?
+[ "$r" != 0 ] && [ "$OPTIND" = 1 ]
diff --git a/bin/cash/tests/builtins/getopts4.0 b/bin/cash/tests/builtins/getopts4.0
new file mode 100644
index 00000000..b67831eb
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts4.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts4.0 265616 2014-05-07 21:45:25Z jilles $
+
+set -- -x
+opt=not
+getopts x opt
+r1=$? OPTIND1=$OPTIND opt1=$opt
+getopts x opt
+r2=$? OPTIND2=$OPTIND
+[ "$r1" = 0 ] && [ "$OPTIND1" = 2 ] && [ "$opt1" = x ] && [ "$r2" != 0 ] &&
+	[ "$OPTIND2" = 2 ]
diff --git a/bin/cash/tests/builtins/getopts5.0 b/bin/cash/tests/builtins/getopts5.0
new file mode 100644
index 00000000..b350caba
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts5.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts5.0 265616 2014-05-07 21:45:25Z jilles $
+
+set -- -x arg
+opt=not
+getopts x opt
+r1=$? OPTIND1=$OPTIND opt1=$opt
+getopts x opt
+r2=$? OPTIND2=$OPTIND
+[ "$r1" = 0 ] && [ "$OPTIND1" = 2 ] && [ "$opt1" = x ] && [ "$r2" != 0 ] &&
+	[ "$OPTIND2" = 2 ]
diff --git a/bin/cash/tests/builtins/getopts6.0 b/bin/cash/tests/builtins/getopts6.0
new file mode 100644
index 00000000..55724ddd
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts6.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts6.0 265844 2014-05-10 17:42:21Z jilles $
+
+set -- -x -y
+getopts :x var || echo "First getopts bad: $?"
+getopts :x var
+r=$?
+[ r != 0 ] && [ "$OPTIND" = 3 ]
diff --git a/bin/cash/tests/builtins/getopts7.0 b/bin/cash/tests/builtins/getopts7.0
new file mode 100644
index 00000000..3b9c01df
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts7.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts7.0 265844 2014-05-10 17:42:21Z jilles $
+
+set -- -x
+getopts :x: var
+r=$?
+[ r != 0 ] && [ "$OPTIND" = 2 ]
diff --git a/bin/cash/tests/builtins/getopts8.0 b/bin/cash/tests/builtins/getopts8.0
new file mode 100644
index 00000000..c9855810
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts8.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts8.0 265849 2014-05-10 19:18:49Z jilles $
+
+set -- -yz -wx
+opt=wrong1 OPTARG=wrong2
+while getopts :x opt; do
+	echo "$opt:${OPTARG-unset}"
+done
+echo "OPTIND=$OPTIND"
diff --git a/bin/cash/tests/builtins/getopts8.0.stdout b/bin/cash/tests/builtins/getopts8.0.stdout
new file mode 100644
index 00000000..f10cefcd
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts8.0.stdout
@@ -0,0 +1,5 @@
+?:y
+?:z
+?:w
+x:unset
+OPTIND=3
diff --git a/bin/cash/tests/builtins/getopts9.0 b/bin/cash/tests/builtins/getopts9.0
new file mode 100644
index 00000000..3f96c4da
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts9.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/getopts9.0 297752 2016-04-09 16:06:13Z jilles $
+
+args='-ab'
+getopts ab opt $args
+printf '%s\n' "$?:$opt:$OPTARG"
+for dummy in dummy1 dummy2; do
+	getopts ab opt $args
+	printf '%s\n' "$?:$opt:$OPTARG"
+done
diff --git a/bin/cash/tests/builtins/getopts9.0.stdout b/bin/cash/tests/builtins/getopts9.0.stdout
new file mode 100644
index 00000000..4d32063f
--- /dev/null
+++ b/bin/cash/tests/builtins/getopts9.0.stdout
@@ -0,0 +1,3 @@
+0:a:
+0:b:
+1:?:
diff --git a/bin/cash/tests/builtins/hash1.0 b/bin/cash/tests/builtins/hash1.0
new file mode 100644
index 00000000..58051796
--- /dev/null
+++ b/bin/cash/tests/builtins/hash1.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/hash1.0 149791 2005-09-05 09:42:10Z stefanf $
+cat /dev/null
+hash
+hash -r
+hash
diff --git a/bin/cash/tests/builtins/hash1.0.stdout b/bin/cash/tests/builtins/hash1.0.stdout
new file mode 100644
index 00000000..3afc3e7b
--- /dev/null
+++ b/bin/cash/tests/builtins/hash1.0.stdout
@@ -0,0 +1 @@
+/bin/cat
diff --git a/bin/cash/tests/builtins/hash2.0 b/bin/cash/tests/builtins/hash2.0
new file mode 100644
index 00000000..d96f911c
--- /dev/null
+++ b/bin/cash/tests/builtins/hash2.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/hash2.0 149791 2005-09-05 09:42:10Z stefanf $
+hash
+hash cat
+hash
diff --git a/bin/cash/tests/builtins/hash2.0.stdout b/bin/cash/tests/builtins/hash2.0.stdout
new file mode 100644
index 00000000..3afc3e7b
--- /dev/null
+++ b/bin/cash/tests/builtins/hash2.0.stdout
@@ -0,0 +1 @@
+/bin/cat
diff --git a/bin/cash/tests/builtins/hash3.0 b/bin/cash/tests/builtins/hash3.0
new file mode 100644
index 00000000..02d89695
--- /dev/null
+++ b/bin/cash/tests/builtins/hash3.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/hash3.0 149791 2005-09-05 09:42:10Z stefanf $
+hash -v cat
+hash
diff --git a/bin/cash/tests/builtins/hash3.0.stdout b/bin/cash/tests/builtins/hash3.0.stdout
new file mode 100644
index 00000000..a34864cd
--- /dev/null
+++ b/bin/cash/tests/builtins/hash3.0.stdout
@@ -0,0 +1,2 @@
+/bin/cat
+/bin/cat
diff --git a/bin/cash/tests/builtins/hash4.0 b/bin/cash/tests/builtins/hash4.0
new file mode 100644
index 00000000..bd07b83e
--- /dev/null
+++ b/bin/cash/tests/builtins/hash4.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/hash4.0 231535 2012-02-11 21:06:45Z jilles $
+
+exec 3>&1
+m=`hash nosuchtool 2>&1 >&3`
+r=$?
+[ "$r" != 0 ] && [ -n "$m" ]
diff --git a/bin/cash/tests/builtins/jobid1.0 b/bin/cash/tests/builtins/jobid1.0
new file mode 100644
index 00000000..fae17708
--- /dev/null
+++ b/bin/cash/tests/builtins/jobid1.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/jobid1.0 254412 2013-08-16 13:48:11Z jilles $
+# Non-standard builtin.
+
+: &
+p1=$!
+p2=$(jobid)
+[ "${p1:?}" = "${p2:?}" ]
diff --git a/bin/cash/tests/builtins/jobid2.0 b/bin/cash/tests/builtins/jobid2.0
new file mode 100644
index 00000000..abfa71ad
--- /dev/null
+++ b/bin/cash/tests/builtins/jobid2.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/jobid2.0 254413 2013-08-16 13:56:43Z jilles $
+
+: &
+p1=$(jobid)
+p2=$(jobid --)
+p3=$(jobid %+)
+p4=$(jobid -- %+)
+[ "${p1:?}" = "${p2:?}" ] && [ "${p2:?}" = "${p3:?}" ] &&
+[ "${p3:?}" = "${p4:?}" ] && [ "${p4:?}" = "${p1:?}" ]
diff --git a/bin/cash/tests/builtins/kill1.0 b/bin/cash/tests/builtins/kill1.0
new file mode 100644
index 00000000..844a0ab9
--- /dev/null
+++ b/bin/cash/tests/builtins/kill1.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/kill1.0 262931 2014-03-08 19:44:34Z jilles $
+
+: &
+p1=$!
+: &
+p2=$!
+wait $p2
+kill %1
diff --git a/bin/cash/tests/builtins/kill2.0 b/bin/cash/tests/builtins/kill2.0
new file mode 100644
index 00000000..c4e70e7c
--- /dev/null
+++ b/bin/cash/tests/builtins/kill2.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/kill2.0 263206 2014-03-15 14:58:48Z jilles $
+
+sleep 1 | sleep 1 &
+kill %+
+wait "$!"
+r=$?
+[ "$r" -gt 128 ] && [ "$(kill -l "$r")" = TERM ]
diff --git a/bin/cash/tests/builtins/lineno.0 b/bin/cash/tests/builtins/lineno.0
new file mode 100644
index 00000000..d70fdf12
--- /dev/null
+++ b/bin/cash/tests/builtins/lineno.0
@@ -0,0 +1,16 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/lineno.0 179023 2008-05-15 19:58:44Z stefanf $
+echo $LINENO
+echo $LINENO
+
+f() {	
+	echo $LINENO
+	echo $LINENO
+}
+
+f
+
+echo ${LINENO:-foo}
+echo ${LINENO=foo}
+echo ${LINENO:+foo}
+echo ${LINENO+foo}
+echo ${#LINENO}
diff --git a/bin/cash/tests/builtins/lineno.0.stdout b/bin/cash/tests/builtins/lineno.0.stdout
new file mode 100644
index 00000000..82583a93
--- /dev/null
+++ b/bin/cash/tests/builtins/lineno.0.stdout
@@ -0,0 +1,9 @@
+2
+3
+2
+3
+12
+13
+foo
+foo
+2
diff --git a/bin/cash/tests/builtins/lineno2.0 b/bin/cash/tests/builtins/lineno2.0
new file mode 100644
index 00000000..e232632d
--- /dev/null
+++ b/bin/cash/tests/builtins/lineno2.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/lineno2.0 262565 2014-02-27 16:54:43Z jilles $
+
+f() {
+	: ${LINENO+${x?}}
+}
+
+unset -v x
+command eval f 2>/dev/null && exit 3
+x=1
+f
diff --git a/bin/cash/tests/builtins/lineno3.0 b/bin/cash/tests/builtins/lineno3.0
new file mode 100644
index 00000000..69e99f76
--- /dev/null
+++ b/bin/cash/tests/builtins/lineno3.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/lineno3.0 272482 2014-10-03 20:24:56Z jilles $
+
+echo before: $LINENO
+dummy=$'a\0
+'
+echo after: $LINENO
diff --git a/bin/cash/tests/builtins/lineno3.0.stdout b/bin/cash/tests/builtins/lineno3.0.stdout
new file mode 100644
index 00000000..6e0e4ac8
--- /dev/null
+++ b/bin/cash/tests/builtins/lineno3.0.stdout
@@ -0,0 +1,2 @@
+before: 3
+after: 6
diff --git a/bin/cash/tests/builtins/local1.0 b/bin/cash/tests/builtins/local1.0
new file mode 100644
index 00000000..a1fb2c38
--- /dev/null
+++ b/bin/cash/tests/builtins/local1.0
@@ -0,0 +1,13 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local1.0 238469 2012-07-15 10:22:13Z jilles $
+# A commonly used but non-POSIX builtin.
+
+f() {
+	local x
+	x=2
+	[ "$x" = 2 ]
+}
+x=1
+f || exit 3
+[ "$x" = 1 ] || exit 3
+f || exit 3
+[ "$x" = 1 ] || exit 3
diff --git a/bin/cash/tests/builtins/local2.0 b/bin/cash/tests/builtins/local2.0
new file mode 100644
index 00000000..185cc39f
--- /dev/null
+++ b/bin/cash/tests/builtins/local2.0
@@ -0,0 +1,17 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local2.0 251797 2013-06-15 22:22:03Z jilles $
+
+f() {
+	local -
+	set -a
+	case $- in
+	*a*) : ;;
+	*) echo In-function \$- bad
+	esac
+}
+case $- in
+*a*) echo Initial \$- bad
+esac
+f
+case $- in
+*a*) echo Final \$- bad
+esac
diff --git a/bin/cash/tests/builtins/local3.0 b/bin/cash/tests/builtins/local3.0
new file mode 100644
index 00000000..3f786408
--- /dev/null
+++ b/bin/cash/tests/builtins/local3.0
@@ -0,0 +1,26 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local3.0 251797 2013-06-15 22:22:03Z jilles $
+
+f() {
+	local "$@"
+	set -a
+	x=7
+	case $- in
+	*a*) : ;;
+	*) echo In-function \$- bad
+	esac
+	[ "$x" = 7 ] || echo In-function \$x bad
+}
+x=1
+case $- in
+*a*) echo Initial \$- bad
+esac
+f x -
+case $- in
+*a*) echo Intermediate \$- bad
+esac
+[ "$x" = 1 ] || echo Intermediate \$x bad
+f - x
+case $- in
+*a*) echo Final \$- bad
+esac
+[ "$x" = 1 ] || echo Final \$x bad
diff --git a/bin/cash/tests/builtins/local4.0 b/bin/cash/tests/builtins/local4.0
new file mode 100644
index 00000000..1b05dfed
--- /dev/null
+++ b/bin/cash/tests/builtins/local4.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local4.0 254339 2013-08-14 21:59:48Z jilles $
+
+f() {
+	local -- x
+	x=2
+	[ "$x" = 2 ]
+}
+x=1
+f || exit 3
+[ "$x" = 1 ] || exit 3
+f || exit 3
+[ "$x" = 1 ] || exit 3
diff --git a/bin/cash/tests/builtins/local5.0 b/bin/cash/tests/builtins/local5.0
new file mode 100644
index 00000000..72bd616c
--- /dev/null
+++ b/bin/cash/tests/builtins/local5.0
@@ -0,0 +1,15 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local5.0 293635 2016-01-10 16:31:28Z jilles $
+
+f() {
+	local PATH IFS elem
+	IFS=:
+	for elem in ''$PATH''; do
+		PATH=/var/empty/$elem:$PATH
+	done
+	ls -d / >/dev/null
+}
+
+p1=$(command -v ls)
+f
+p2=$(command -v ls)
+[ "$p1" = "$p2" ]
diff --git a/bin/cash/tests/builtins/local6.0 b/bin/cash/tests/builtins/local6.0
new file mode 100644
index 00000000..88283edb
--- /dev/null
+++ b/bin/cash/tests/builtins/local6.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local6.0 294582 2016-01-22 18:10:36Z jilles $
+
+f() {
+	local x
+	readonly x=2
+}
+x=3
+f
+x=4
+[ "$x" = 4 ]
diff --git a/bin/cash/tests/builtins/local7.0 b/bin/cash/tests/builtins/local7.0
new file mode 100644
index 00000000..fc820962
--- /dev/null
+++ b/bin/cash/tests/builtins/local7.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/local7.0 294593 2016-01-22 20:10:08Z jilles $
+
+f() {
+	local x
+	readonly x=2
+}
+unset x
+f
+x=4
+[ "$x" = 4 ]
diff --git a/bin/cash/tests/builtins/locale1.0 b/bin/cash/tests/builtins/locale1.0
new file mode 100644
index 00000000..3b6a0987
--- /dev/null
+++ b/bin/cash/tests/builtins/locale1.0
@@ -0,0 +1,134 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/locale1.0 218819 2011-02-18 20:37:09Z jilles $
+# Note: this test depends on strerror() using locale.
+
+failures=0
+
+check() {
+	if ! eval "[ $1 ]"; then
+		echo "Failed: $1 at $2"
+		: $((failures += 1))
+	fi
+}
+
+unset LANG LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME LC_MESSAGES
+unset LANGUAGE
+
+msgeng="No such file or directory"
+msgdut="Bestand of map niet gevonden"
+
+# Verify C locale error message.
+case $(command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+# Various locale variables that should not affect the message.
+case $(LC_ALL=C command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_ALL=C LANG=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_ALL=C LC_MESSAGES=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_CTYPE=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+# Verify Dutch message.
+case $(export LANG=nl_NL.ISO8859-1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(export LC_MESSAGES=nl_NL.ISO8859-1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(export LC_ALL=nl_NL.ISO8859-1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LANG=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_MESSAGES=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_ALL=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+# Verify that command assignments do not set the locale persistently.
+case $(command . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LANG=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_MESSAGES=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(LC_ALL=nl_NL.ISO8859-1 command . /var/empty/foo 2>&1; command . /var/empty/foo 2>&1) in
+	*"$msgdut"*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+# Check special builtin; add colon invocation to avoid depending on certain fix.
+case $(LC_ALL=nl_NL.ISO8859-1 . /var/empty/foo 2>&1; :) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+# Assignments on special builtins are exported to that builtin; the export
+# is not persistent.
+case $(LC_ALL=nl_NL.ISO8859-1 . /dev/null; . /var/empty/foo 2>&1) in
+	*"$msgeng"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+case $(export LC_ALL; LC_ALL=nl_NL.ISO8859-1 . /dev/null; . /var/empty/foo 2>&1) in
+	*"$msgdut"*) ok=1 ;;
+	*) ok=0 ;;
+esac
+check '$ok -eq 1' $LINENO
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/locale2.0 b/bin/cash/tests/builtins/locale2.0
new file mode 100644
index 00000000..cdb17095
--- /dev/null
+++ b/bin/cash/tests/builtins/locale2.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/locale2.0 317912 2017-05-07 19:49:46Z jilles $
+
+$SH -c 'LC_ALL=C true; kill -INT $$; echo continued'
+r=$?
+[ "$r" -gt 128 ] && [ "$(kill -l "$r")" = INT ]
diff --git a/bin/cash/tests/builtins/printf1.0 b/bin/cash/tests/builtins/printf1.0
new file mode 100644
index 00000000..0669bd49
--- /dev/null
+++ b/bin/cash/tests/builtins/printf1.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/printf1.0 214853 2010-11-05 21:47:58Z jilles $
+
+[ "$(printf '%c\0%s%d' x '\' 010 | tr '\0' Z)" = 'xZ\8' ]
diff --git a/bin/cash/tests/builtins/printf2.0 b/bin/cash/tests/builtins/printf2.0
new file mode 100644
index 00000000..f85d39e1
--- /dev/null
+++ b/bin/cash/tests/builtins/printf2.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/printf2.0 214853 2010-11-05 21:47:58Z jilles $
+
+[ "$(printf '%cZ%s%d' x '\' 010)" = 'xZ\8' ]
diff --git a/bin/cash/tests/builtins/printf3.0 b/bin/cash/tests/builtins/printf3.0
new file mode 100644
index 00000000..e6a1dec9
--- /dev/null
+++ b/bin/cash/tests/builtins/printf3.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/printf3.0 216606 2010-12-20 23:06:57Z jilles $
+
+set -e
+v=$(! printf "%d" @wrong 2>/dev/null)
+[ "$v" = "0" ]
diff --git a/bin/cash/tests/builtins/printf4.0 b/bin/cash/tests/builtins/printf4.0
new file mode 100644
index 00000000..ab6abef6
--- /dev/null
+++ b/bin/cash/tests/builtins/printf4.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/printf4.0 216606 2010-12-20 23:06:57Z jilles $
+
+set -e
+v=$(! printf "%d" 4wrong 2>/dev/null)
+[ "$v" = "4" ]
diff --git a/bin/cash/tests/builtins/read1.0 b/bin/cash/tests/builtins/read1.0
new file mode 100644
index 00000000..753613d0
--- /dev/null
+++ b/bin/cash/tests/builtins/read1.0
@@ -0,0 +1,26 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read1.0 190300 2009-03-22 23:00:52Z stefanf $
+set -e
+
+echo "1 2 3"		| { read a; echo "x${a}x"; }
+echo "1 2 3"		| { read a b; echo "x${a}x${b}x"; }
+echo "1 2 3"		| { read a b c; echo "x${a}x${b}x${c}x"; }
+echo "1 2 3"		| { read a b c d; echo "x${a}x${b}x${c}x${d}x"; }
+
+echo "	1  2 3 "	| { read a b c; echo "x${a}x${b}x${c}x"; }
+echo "	1  2 3 "	| { unset IFS; read a b c; echo "x${a}x${b}x${c}x"; }
+echo "	1  2 3 "	| { IFS=$(printf ' \t\n') read a b c; echo "x${a}x${b}x${c}x"; }
+echo "	1  2 3 "	| { IFS= read a b; echo "x${a}x${b}x"; }
+
+echo " 1,2 3 "		| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+echo ", 2 ,3"		| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,,3"		| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 , , 3"		| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,2 3,"		| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,2 3,,"	| { IFS=' ,' read a b c; echo "x${a}x${b}x${c}x"; }
+
+echo " 1,2 3 "		| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
+echo ", 2 ,3"		| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,,3"		| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 , , 3"		| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,2 3,"		| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
+echo " 1 ,2 3,,"	| { IFS=', ' read a b c; echo "x${a}x${b}x${c}x"; }
diff --git a/bin/cash/tests/builtins/read1.0.stdout b/bin/cash/tests/builtins/read1.0.stdout
new file mode 100644
index 00000000..dbcb1af9
--- /dev/null
+++ b/bin/cash/tests/builtins/read1.0.stdout
@@ -0,0 +1,20 @@
+x1 2 3x
+x1x2 3x
+x1x2x3x
+x1x2x3xx
+x1x2x3x
+x1x2x3x
+x1x2x3x
+x	1  2 3 xx
+x1x2x3x
+xx2x3x
+x1xx3x
+x1xx3x
+x1x2x3x
+x1x2x3,,x
+x1x2x3x
+xx2x3x
+x1xx3x
+x1xx3x
+x1x2x3x
+x1x2x3,,x
diff --git a/bin/cash/tests/builtins/read2.0 b/bin/cash/tests/builtins/read2.0
new file mode 100644
index 00000000..f41acd51
--- /dev/null
+++ b/bin/cash/tests/builtins/read2.0
@@ -0,0 +1,31 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read2.0 212187 2010-09-03 21:17:33Z jilles $
+
+set -e
+{
+	echo 1
+	echo two
+	echo three
+} | {
+	read x
+	[ "$x" = 1 ]
+	(read x
+	[ "$x" = two ])
+	read x
+	[ "$x" = three ]
+}
+
+T=`mktemp sh-test.XXXXXX`
+trap 'rm -f "$T"' 0
+{
+	echo 1
+	echo two
+	echo three
+} >$T
+{
+	read x
+	[ "$x" = 1 ]
+	(read x
+	[ "$x" = two ])
+	read x
+	[ "$x" = three ]
+} <$T
diff --git a/bin/cash/tests/builtins/read3.0 b/bin/cash/tests/builtins/read3.0
new file mode 100644
index 00000000..594ef6a1
--- /dev/null
+++ b/bin/cash/tests/builtins/read3.0
@@ -0,0 +1,11 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read3.0 212330 2010-09-08 18:32:23Z jilles $
+
+printf '%s\n' 'a\ b c'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' 'a b\ c'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' 'a\:b:c'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' 'a:b\:c'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\ a'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\:a'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\\ a'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\\ a'	| { read -r a b; printf '%s\n' "x${a}x${b}x"; }
diff --git a/bin/cash/tests/builtins/read3.0.stdout b/bin/cash/tests/builtins/read3.0.stdout
new file mode 100644
index 00000000..8ed98ca9
--- /dev/null
+++ b/bin/cash/tests/builtins/read3.0.stdout
@@ -0,0 +1,9 @@
+xa bxcx
+xaxb cx
+xa:bxcx
+xaxb:cx
+x axx
+x:axx
+x\xx
+x\ axx
+x\\\xax
diff --git a/bin/cash/tests/builtins/read4.0 b/bin/cash/tests/builtins/read4.0
new file mode 100644
index 00000000..9a3a8f41
--- /dev/null
+++ b/bin/cash/tests/builtins/read4.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read4.0 212339 2010-09-08 20:35:43Z jilles $
+
+printf '%s\n' '\a\ b c'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\a b\ c'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\a\:b:c'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\a:b\:c'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\ a'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\:a'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\\ a'	| { read a b; printf '%s\n' "x${a}x${b}x"; }
+printf '%s\n' '\\\:a'	| { IFS=: read a b; printf '%s\n' "x${a}x${b}x"; }
diff --git a/bin/cash/tests/builtins/read4.0.stdout b/bin/cash/tests/builtins/read4.0.stdout
new file mode 100644
index 00000000..a8747a46
--- /dev/null
+++ b/bin/cash/tests/builtins/read4.0.stdout
@@ -0,0 +1,8 @@
+xa bxcx
+xaxb cx
+xa:bxcx
+xaxb:cx
+x\xax
+x\xax
+x\ axx
+x\:axx
diff --git a/bin/cash/tests/builtins/read5.0 b/bin/cash/tests/builtins/read5.0
new file mode 100644
index 00000000..60bca1f7
--- /dev/null
+++ b/bin/cash/tests/builtins/read5.0
@@ -0,0 +1,32 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read5.0 218821 2011-02-18 20:51:13Z jilles $
+
+unset LC_ALL
+LC_CTYPE=en_US.ISO8859-1
+export LC_CTYPE
+
+# Note: the first and last characters are not whitespace.
+# Exclude backslash and newline.
+bad1=`printf %03o \'\\\\`
+bad2=`printf %03o \''
+'`
+e=
+for i in 0 1 2 3; do
+	for j in 0 1 2 3 4 5 6 7; do
+		for k in 0 1 2 3 4 5 6 7; do
+			case $i$j$k in
+			000|$bad1|$bad2) continue ;;
+			esac
+			e="$e\\$i$j$k"
+		done
+	done
+done
+e=`printf "$e"`
+[ "${#e}" = 253 ] || echo length bad
+
+r1=`printf '%s\n' "$e" | { read -r x; printf '%s' "$x"; }`
+[ "$r1" = "$e" ] || echo "read with -r bad"
+r2=`printf '%s\n' "$e" | { read x; printf '%s' "$x"; }`
+[ "$r2" = "$e" ] || echo "read without -r bad 1"
+IFS=
+r3=`printf '%s\n' "$e" | { read x; printf '%s' "$x"; }`
+[ "$r3" = "$e" ] || echo "read without -r bad 2"
diff --git a/bin/cash/tests/builtins/read6.0 b/bin/cash/tests/builtins/read6.0
new file mode 100644
index 00000000..784f59af
--- /dev/null
+++ b/bin/cash/tests/builtins/read6.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read6.0 247190 2013-02-23 15:15:41Z jilles $
+
+: | read x
+r=$?
+[ "$r" = 1 ]
diff --git a/bin/cash/tests/builtins/read7.0 b/bin/cash/tests/builtins/read7.0
new file mode 100644
index 00000000..2df732b9
--- /dev/null
+++ b/bin/cash/tests/builtins/read7.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read7.0 250214 2013-05-03 15:28:31Z jilles $
+
+{ errmsg=`read x <&- 2>&1 >&3`; } 3>&1
+r=$?
+[ "$r" -ge 2 ] && [ "$r" -le 128 ] && [ -n "$errmsg" ]
diff --git a/bin/cash/tests/builtins/read8.0 b/bin/cash/tests/builtins/read8.0
new file mode 100644
index 00000000..2ff60144
--- /dev/null
+++ b/bin/cash/tests/builtins/read8.0
@@ -0,0 +1,17 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read8.0 286826 2015-08-16 12:57:17Z jilles $
+
+read a b c <<\EOF
+\
+A\
+ \
+ \
+ \
+B\
+ \
+ \
+C\
+ \
+ \
+ \
+EOF
+[ "$a.$b.$c" = "A.B.C" ]
diff --git a/bin/cash/tests/builtins/read9.0 b/bin/cash/tests/builtins/read9.0
new file mode 100644
index 00000000..dbd76d3e
--- /dev/null
+++ b/bin/cash/tests/builtins/read9.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/read9.0 287308 2015-08-30 17:24:22Z jilles $
+
+empty=''
+read a b c <<EOF
+\ \ A B\ \ B C\ \ $empty
+EOF
+read d e <<EOF
+D\ $empty
+EOF
+[ "$a.$b.$c.$d.$e" = "  A.B  B.C  .D ." ]
diff --git a/bin/cash/tests/builtins/return1.0 b/bin/cash/tests/builtins/return1.0
new file mode 100644
index 00000000..26ae07ec
--- /dev/null
+++ b/bin/cash/tests/builtins/return1.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return1.0 149791 2005-09-05 09:42:10Z stefanf $
+f() {
+	return 0
+	exit 1
+}
+
+f
diff --git a/bin/cash/tests/builtins/return2.1 b/bin/cash/tests/builtins/return2.1
new file mode 100644
index 00000000..4ed4dbe8
--- /dev/null
+++ b/bin/cash/tests/builtins/return2.1
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return2.1 149791 2005-09-05 09:42:10Z stefanf $
+f() {
+	true && return 1
+	return 0
+}
+
+f
diff --git a/bin/cash/tests/builtins/return3.1 b/bin/cash/tests/builtins/return3.1
new file mode 100644
index 00000000..b34d0040
--- /dev/null
+++ b/bin/cash/tests/builtins/return3.1
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return3.1 149791 2005-09-05 09:42:10Z stefanf $
+return 1
+exit 0
diff --git a/bin/cash/tests/builtins/return4.0 b/bin/cash/tests/builtins/return4.0
new file mode 100644
index 00000000..606e55e6
--- /dev/null
+++ b/bin/cash/tests/builtins/return4.0
@@ -0,0 +1,16 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return4.0 208629 2010-05-28 22:08:34Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX) || exit
+trap 'rm -rf $T' 0
+cd $T || exit 3
+echo 'return 42; exit 4' >testscript
+. ./testscript
+[ "$?" = 42 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/return5.0 b/bin/cash/tests/builtins/return5.0
new file mode 100644
index 00000000..6ce02b32
--- /dev/null
+++ b/bin/cash/tests/builtins/return5.0
@@ -0,0 +1,17 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return5.0 211349 2010-08-15 21:06:53Z jilles $
+
+if [ "$1" != nested ]; then
+	f() {
+		set -- nested
+		. "$0"
+		# Allow return to return from the function or the dot script.
+		return 4
+	}
+	f
+	exit $(($? ^ 4))
+fi
+# To trigger the bug, the following commands must be at the top level,
+# with newlines in between.
+return 4
+echo bad
+exit 1
diff --git a/bin/cash/tests/builtins/return6.4 b/bin/cash/tests/builtins/return6.4
new file mode 100644
index 00000000..1e1eaec9
--- /dev/null
+++ b/bin/cash/tests/builtins/return6.4
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return6.4 212475 2010-09-11 15:07:40Z jilles $
+
+while return 4; do exit 3; done
diff --git a/bin/cash/tests/builtins/return7.4 b/bin/cash/tests/builtins/return7.4
new file mode 100644
index 00000000..de459c15
--- /dev/null
+++ b/bin/cash/tests/builtins/return7.4
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return7.4 212475 2010-09-11 15:07:40Z jilles $
+
+f() {
+	while return 4; do exit 3; done
+}
+f
diff --git a/bin/cash/tests/builtins/return8.0 b/bin/cash/tests/builtins/return8.0
new file mode 100644
index 00000000..4e3b667a
--- /dev/null
+++ b/bin/cash/tests/builtins/return8.0
@@ -0,0 +1,13 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/return8.0 255215 2013-09-04 22:10:16Z jilles $
+
+if [ "$1" = nested ]; then
+	return 17
+fi
+
+f() {
+	set -- nested
+	. "$0"
+	return $(($? ^ 1))
+}
+f
+exit $(($? ^ 16))
diff --git a/bin/cash/tests/builtins/set1.0 b/bin/cash/tests/builtins/set1.0
new file mode 100644
index 00000000..fc39fade
--- /dev/null
+++ b/bin/cash/tests/builtins/set1.0
@@ -0,0 +1,32 @@
+# $FreeBSD$
+
+set +C
+set +f
+set -e
+
+settings=$(set +o)
+set -C
+set -f
+set +e
+case $- in
+*C*) ;;
+*) echo missing C ;;
+esac
+case $- in
+*f*) ;;
+*) echo missing C ;;
+esac
+case $- in
+*e*) echo bad e ;;
+esac
+eval "$settings"
+case $- in
+*C*) echo bad C ;;
+esac
+case $- in
+*f*) echo bad f ;;
+esac
+case $- in
+*e*) ;;
+*) echo missing e ;;
+esac
diff --git a/bin/cash/tests/builtins/set2.0 b/bin/cash/tests/builtins/set2.0
new file mode 100644
index 00000000..38be55ea
--- /dev/null
+++ b/bin/cash/tests/builtins/set2.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/set2.0 223183 2011-06-17 10:21:24Z jilles $
+
+! env @badness=1 ${SH} -c 'v=`set`; eval "$v"' 2>&1 | grep @badness
diff --git a/bin/cash/tests/builtins/set3.0 b/bin/cash/tests/builtins/set3.0
new file mode 100644
index 00000000..c2772e28
--- /dev/null
+++ b/bin/cash/tests/builtins/set3.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/set3.0 296578 2016-03-09 21:05:21Z jilles $
+
+settings1=$(set +o) && set -o nolog && settings2=$(set +o) &&
+[ "$settings1" != "$settings2" ]
diff --git a/bin/cash/tests/builtins/trap1.0 b/bin/cash/tests/builtins/trap1.0
new file mode 100644
index 00000000..061a84cd
--- /dev/null
+++ b/bin/cash/tests/builtins/trap1.0
@@ -0,0 +1,22 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap1.0 213738 2010-10-12 18:20:38Z obrien $
+
+test "$(trap 'echo trapped' EXIT; :)" = trapped || exit 1
+
+test "$(trap 'echo trapped' EXIT; /usr/bin/true)" = trapped || exit 1
+
+result=$(${SH} -c 'trap "echo trapped" EXIT; /usr/bin/false')
+test $? -eq 1 || exit 1
+test "$result" = trapped || exit 1
+
+result=$(${SH} -c 'trap "echo trapped" EXIT; exec /usr/bin/false')
+test $? -eq 1 || exit 1
+test -z "$result" || exit 1
+
+result=0
+trap 'result=$((result+1))' INT
+kill -INT $$
+test "$result" -eq 1 || exit 1
+(kill -INT $$)
+test "$result" -eq 2 || exit 1
+
+exit 0
diff --git a/bin/cash/tests/builtins/trap10.0 b/bin/cash/tests/builtins/trap10.0
new file mode 100644
index 00000000..23515454
--- /dev/null
+++ b/bin/cash/tests/builtins/trap10.0
@@ -0,0 +1,6 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap10.0 230212 2012-01-16 11:07:46Z dumbbell $
+
+# Check that the return statement will not break the EXIT trap, ie. all
+# trap commands are executed before the script exits.
+
+test "$(trap 'printf trap; echo ped' EXIT; f() { return; }; f)" = trapped || exit 1
diff --git a/bin/cash/tests/builtins/trap11.0 b/bin/cash/tests/builtins/trap11.0
new file mode 100644
index 00000000..63eddeee
--- /dev/null
+++ b/bin/cash/tests/builtins/trap11.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap11.0 230212 2012-01-16 11:07:46Z dumbbell $
+
+# Check that the return statement will not break the USR1 trap, ie. all
+# trap commands are executed before the script resumes.
+
+result=$(${SH} -c 'trap "printf trap; echo ped" USR1; f() { return $(kill -USR1 $$); }; f')
+test $? -eq 0 || exit 1
+test "$result" = trapped || exit 1
diff --git a/bin/cash/tests/builtins/trap12.0 b/bin/cash/tests/builtins/trap12.0
new file mode 100644
index 00000000..134391f7
--- /dev/null
+++ b/bin/cash/tests/builtins/trap12.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap12.0 247720 2013-03-03 17:33:59Z jilles $
+
+f() {
+	trap 'return 42' USR1
+	kill -USR1 $$
+	return 3
+}
+f
+r=$?
+[ "$r" = 42 ]
diff --git a/bin/cash/tests/builtins/trap13.0 b/bin/cash/tests/builtins/trap13.0
new file mode 100644
index 00000000..38678bf7
--- /dev/null
+++ b/bin/cash/tests/builtins/trap13.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap13.0 257399 2013-10-30 21:36:15Z jilles $
+
+{
+	trap 'exit 0' INT
+	${SH} -c 'kill -INT $PPID'
+	exit 3
+} &
+wait $!
diff --git a/bin/cash/tests/builtins/trap14.0 b/bin/cash/tests/builtins/trap14.0
new file mode 100644
index 00000000..ce49b4c9
--- /dev/null
+++ b/bin/cash/tests/builtins/trap14.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap14.0 257399 2013-10-30 21:36:15Z jilles $
+
+{
+	trap - INT
+	${SH} -c 'kill -INT $PPID' &
+	wait
+} &
+wait $!
+r=$?
+[ "$r" -gt 128 ] && [ "$(kill -l "$r")" = INT ]
diff --git a/bin/cash/tests/builtins/trap15.0 b/bin/cash/tests/builtins/trap15.0
new file mode 100644
index 00000000..5bb7aeb2
--- /dev/null
+++ b/bin/cash/tests/builtins/trap15.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap15.0 281718 2015-04-18 23:49:57Z bdrewery $
+
+(${SH} -c 'term(){ exit 5;}; trap term TERM; kill -TERM $$') &
+wait >/dev/null 2>&1 $!
+[ $? -eq 5 ]
diff --git a/bin/cash/tests/builtins/trap16.0 b/bin/cash/tests/builtins/trap16.0
new file mode 100644
index 00000000..0c960546
--- /dev/null
+++ b/bin/cash/tests/builtins/trap16.0
@@ -0,0 +1,20 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap16.0 281718 2015-04-18 23:49:57Z bdrewery $
+
+traps=$(${SH} -c 'trap "echo bad" 0; trap - 0; trap')
+[ -z "$traps" ] || exit 1
+traps=$(${SH} -c 'trap "echo bad" 0; trap "" 0; trap')
+expected_traps=$(${SH} -c 'trap "" EXIT; trap')
+[ "$traps" = "$expected_traps" ] || exit 2
+traps=$(${SH} -c 'trap "echo bad" 0; trap 0; trap')
+[ -z "$traps" ] || exit 3
+traps=$(${SH} -c 'trap "echo bad" 0; trap -- 0; trap')
+[ -z "$traps" ] || exit 4
+traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap - 0 1 2; trap')
+[ -z "$traps" ] || exit 5
+traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap "" 0 1 2; trap')
+expected_traps=$(${SH} -c 'trap "" EXIT HUP INT; trap')
+[ "$traps" = "$expected_traps" ] || exit 6
+traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap 0 1 2; trap')
+[ -z "$traps" ] || exit 7
+traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap -- 0 1 2; trap')
+[ -z "$traps" ] || exit 8
diff --git a/bin/cash/tests/builtins/trap17.0 b/bin/cash/tests/builtins/trap17.0
new file mode 100644
index 00000000..ec2e5870
--- /dev/null
+++ b/bin/cash/tests/builtins/trap17.0
@@ -0,0 +1,10 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap17.0 297360 2016-03-28 18:58:40Z jilles $
+# This use-after-free bug probably needs non-default settings to show up.
+
+v1=nothing v2=nothing
+trap 'trap "echo bad" USR1
+v1=trap_received
+v2=trap_invoked
+:' USR1
+kill -USR1 "$$"
+[ "$v1.$v2" = trap_received.trap_invoked ]
diff --git a/bin/cash/tests/builtins/trap2.0 b/bin/cash/tests/builtins/trap2.0
new file mode 100644
index 00000000..020dcfd9
--- /dev/null
+++ b/bin/cash/tests/builtins/trap2.0
@@ -0,0 +1,52 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap2.0 194517 2009-06-19 22:15:59Z jilles $
+# This is really a test for outqstr(), which is readily accessible via trap.
+
+runtest()
+{
+	teststring=$1
+	trap -- "$teststring" USR1
+	traps=$(trap)
+	if [ "$teststring" != "-" ] && [ -z "$traps" ]; then
+		# One possible reading of POSIX requires the above to return an
+		# empty string because backquote commands are executed in a
+		# subshell and subshells shall reset traps. However, an example
+		# in the normative description of the trap builtin shows the
+		# same usage as here, it is useful and our /bin/sh allows it.
+		echo '$(trap) is broken'
+		exit 1
+	fi
+	trap - USR1
+	eval "$traps"
+	traps2=$(trap)
+	if [ "$traps" != "$traps2" ]; then
+		echo "Mismatch for '$teststring'"
+		exit 1
+	fi
+}
+
+runtest 'echo'
+runtest 'echo hi'
+runtest "'echo' 'hi'"
+runtest '"echo" $PATH'
+runtest '\echo "$PATH"'
+runtest ' 0'
+runtest '0 '
+runtest ' 1'
+runtest '1 '
+i=1
+while [ $i -le 127 ]; do
+	c=$(printf \\"$(printf %o $i)")
+	if [ $i -lt 48 ] || [ $i -gt 57 ]; then
+		runtest "$c"
+	fi
+	runtest " $c$c"
+	runtest "a$c"
+	i=$((i+1))
+done
+IFS=,
+runtest ' '
+runtest ','
+unset IFS
+runtest ' '
+
+exit 0
diff --git a/bin/cash/tests/builtins/trap3.0 b/bin/cash/tests/builtins/trap3.0
new file mode 100644
index 00000000..e08f7355
--- /dev/null
+++ b/bin/cash/tests/builtins/trap3.0
@@ -0,0 +1,11 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap3.0 218889 2011-02-20 14:18:58Z jilles $
+
+{
+	trap '' garbage && exit 3
+	trap - garbage && exit 3
+	trap true garbage && exit 3
+	trap '' 99999 && exit 3
+	trap - 99999 && exit 3
+	trap true 99999 && exit 3
+} 2>/dev/null
+exit 0
diff --git a/bin/cash/tests/builtins/trap4.0 b/bin/cash/tests/builtins/trap4.0
new file mode 100644
index 00000000..5c31f165
--- /dev/null
+++ b/bin/cash/tests/builtins/trap4.0
@@ -0,0 +1,17 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap4.0 217035 2011-01-05 23:17:29Z jilles $
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX)
+trap 'rm -rf $T' 0
+cd $T || exit 3
+mkfifo fifo1
+
+v=$(
+	exec 3>&1
+	: <fifo1 &
+	{
+		wait $!
+		trap 'trap "" PIPE; echo trapped >&3 2>/dev/null' PIPE
+		echo x 2>/dev/null
+	} >fifo1
+)
+test "$v" = trapped
diff --git a/bin/cash/tests/builtins/trap5.0 b/bin/cash/tests/builtins/trap5.0
new file mode 100644
index 00000000..541dff30
--- /dev/null
+++ b/bin/cash/tests/builtins/trap5.0
@@ -0,0 +1,19 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap5.0 217461 2011-01-15 21:09:00Z jilles $
+
+set -e
+trap - USR1
+initial=$(trap)
+trap -- -l USR1
+added=$(trap)
+[ -n "$added" ]
+trap - USR1
+second=$(trap)
+[ "$initial" = "$second" ]
+eval "$added"
+added2=$(trap)
+added3=$(trap --)
+[ "$added" = "$added2" ]
+[ "$added2" = "$added3" ]
+trap -- - USR1
+third=$(trap)
+[ "$initial" = "$third" ]
diff --git a/bin/cash/tests/builtins/trap6.0 b/bin/cash/tests/builtins/trap6.0
new file mode 100644
index 00000000..e28097a9
--- /dev/null
+++ b/bin/cash/tests/builtins/trap6.0
@@ -0,0 +1,9 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap6.0 217472 2011-01-16 13:56:41Z jilles $
+
+v=$(
+	${SH} -c 'trap "echo ok; exit" USR1; kill -USR1 $$' &
+	# Suppress possible message about exit on signal
+	wait $! >/dev/null 2>&1
+)
+r=$(kill -l $?)
+[ "$v" = "ok" ] && { [ "$r" = "USR1" ] || [ "$r" = "usr1" ]; }
diff --git a/bin/cash/tests/builtins/trap7.0 b/bin/cash/tests/builtins/trap7.0
new file mode 100644
index 00000000..a6facbdc
--- /dev/null
+++ b/bin/cash/tests/builtins/trap7.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap7.0 217996 2011-01-27 23:08:20Z jilles $
+
+[ "$(trap 'echo trapped' EXIT)" = trapped ]
diff --git a/bin/cash/tests/builtins/trap8.0 b/bin/cash/tests/builtins/trap8.0
new file mode 100644
index 00000000..d9cb2cc2
--- /dev/null
+++ b/bin/cash/tests/builtins/trap8.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap8.0 218889 2011-02-20 14:18:58Z jilles $
+
+# I am not sure if POSIX requires the shell to continue processing
+# further trap names in the same trap command after an invalid one.
+
+test -n "$(trap true garbage TERM 2>/dev/null || trap)" || exit 3
+exit 0
diff --git a/bin/cash/tests/builtins/trap9.0 b/bin/cash/tests/builtins/trap9.0
new file mode 100644
index 00000000..cfcee29d
--- /dev/null
+++ b/bin/cash/tests/builtins/trap9.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/trap9.0 230211 2012-01-16 10:59:44Z dumbbell $
+
+test "$(trap 'printf trap; echo ped' EXIT; f() { :; }; f)" = trapped || exit 1
diff --git a/bin/cash/tests/builtins/type1.0 b/bin/cash/tests/builtins/type1.0
new file mode 100644
index 00000000..b4a6db2f
--- /dev/null
+++ b/bin/cash/tests/builtins/type1.0
@@ -0,0 +1,8 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/type1.0 165931 2007-01-11 00:25:20Z stefanf $
+command -v not-here && exit 1
+command -v /not-here && exit 1
+command -V not-here && exit 1
+command -V /not-here && exit 1
+type not-here && exit 1
+type /not-here && exit 1
+exit 0
diff --git a/bin/cash/tests/builtins/type1.0.stderr b/bin/cash/tests/builtins/type1.0.stderr
new file mode 100644
index 00000000..7853418a
--- /dev/null
+++ b/bin/cash/tests/builtins/type1.0.stderr
@@ -0,0 +1,4 @@
+not-here: not found
+/not-here: No such file or directory
+not-here: not found
+/not-here: No such file or directory
diff --git a/bin/cash/tests/builtins/type2.0 b/bin/cash/tests/builtins/type2.0
new file mode 100644
index 00000000..82891e50
--- /dev/null
+++ b/bin/cash/tests/builtins/type2.0
@@ -0,0 +1,26 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/type2.0 201344 2009-12-31 17:44:24Z jilles $
+
+failures=0
+
+check() {
+	if ! eval "$*"; then
+		echo "Failed: $*"
+		: $((failures += 1))
+	fi
+}
+
+check 'PATH=/libexec type ld-elf.so.1 >/dev/null'
+check '! PATH=/libexec type ls 2>/dev/null'
+
+PATH=/libexec:$PATH
+
+check 'type ld-elf.so.1 >/dev/null'
+
+PATH=/libexec
+
+check 'type ld-elf.so.1 >/dev/null'
+check '! type ls 2>/dev/null'
+check 'PATH=/bin type ls >/dev/null'
+check '! PATH=/bin type ld-elf.so.1 2>/dev/null'
+
+exit $((failures > 0))
diff --git a/bin/cash/tests/builtins/type3.0 b/bin/cash/tests/builtins/type3.0
new file mode 100644
index 00000000..e60d40ba
--- /dev/null
+++ b/bin/cash/tests/builtins/type3.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/type3.0 255072 2013-08-30 12:09:59Z jilles $
+
+[ "$(type type)" = "$(type -- type)" ]
diff --git a/bin/cash/tests/builtins/unalias.0 b/bin/cash/tests/builtins/unalias.0
new file mode 100644
index 00000000..813fea14
--- /dev/null
+++ b/bin/cash/tests/builtins/unalias.0
@@ -0,0 +1,21 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/unalias.0 149781 2005-09-04 11:59:59Z stefanf $
+set -e
+
+alias false=true
+false
+unalias false
+false && exit 1
+unalias false && exit 1
+
+alias a1=foo a2=bar
+unalias a1 a2
+unalias a1 && exit 1
+unalias a2 && exit 1
+alias a2=bar
+unalias a1 a2 && exit 1
+
+alias a1=foo a2=bar
+unalias -a
+unalias a1 && exit 1
+unalias a2 && exit 1
+exit 0
diff --git a/bin/cash/tests/builtins/var-assign.0 b/bin/cash/tests/builtins/var-assign.0
new file mode 100644
index 00000000..9869795e
--- /dev/null
+++ b/bin/cash/tests/builtins/var-assign.0
@@ -0,0 +1,55 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/var-assign.0 327281 2017-12-28 08:22:26Z eadler $
+IFS=,
+
+SPECIAL="break,\
+	:,\
+	continue,\
+	. /dev/null,
+	eval,
+	exec,
+	export -p,
+	readonly -p,
+	set,
+	shift 0,
+	times,
+	trap,
+	unset foo"
+
+UTILS="alias,\
+	bg,\
+	bind,\
+	cd,\
+	command echo,\
+	echo,\
+	false,\
+	fc -l,\
+	fg,\
+	getopts a var,\
+	hash,\
+	jobs,\
+	printf a,\
+	pwd,\
+	read var < /dev/null,\
+	test,\
+	true,\
+	type ls,\
+	ulimit,\
+	umask,\
+	unalias -a,\
+	wait"
+
+set -e
+
+# For special built-ins variable assignments affect the shell environment.
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+	${SH} -c "VAR=1; VAR=0 ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
+
+# For other built-ins and utilities they do not.
+set -- ${UTILS}
+for cmd in "$@"
+do
+	${SH} -c "VAR=0; VAR=1 ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
diff --git a/bin/cash/tests/builtins/var-assign2.0 b/bin/cash/tests/builtins/var-assign2.0
new file mode 100644
index 00000000..ff60f72a
--- /dev/null
+++ b/bin/cash/tests/builtins/var-assign2.0
@@ -0,0 +1,55 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/var-assign2.0 213738 2010-10-12 18:20:38Z obrien $
+IFS=,
+
+SPECIAL="break,\
+	:,\
+	continue,\
+	. /dev/null,\
+	eval,\
+	exec,\
+	export -p,\
+	readonly -p,\
+	set,\
+	shift 0,\
+	times,\
+	trap,\
+	unset foo"
+
+UTILS="alias,\
+	bg,\
+	bind,\
+	cd,\
+	command echo,\
+	echo,\
+	false,\
+	fc -l,\
+	fg,\
+	getopts a var,\
+	hash,\
+	jobs,\
+	printf a,\
+	pwd,\
+	read var < /dev/null,\
+	test,\
+	true,\
+	type ls,\
+	ulimit,\
+	umask,\
+	unalias -a,\
+	wait"
+
+set -e
+
+# With 'command', variable assignments do not affect the shell environment.
+
+set -- ${SPECIAL}
+for cmd in "$@"
+do
+	${SH} -c "VAR=0; VAR=1 command ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
+
+set -- ${UTILS}
+for cmd in "$@"
+do
+	${SH} -c "VAR=0; VAR=1 command ${cmd}; exit \${VAR}" >/dev/null 2>&1
+done
diff --git a/bin/cash/tests/builtins/wait1.0 b/bin/cash/tests/builtins/wait1.0
new file mode 100644
index 00000000..4e8ae080
--- /dev/null
+++ b/bin/cash/tests/builtins/wait1.0
@@ -0,0 +1,23 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait1.0 208476 2010-05-23 22:10:20Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+exit 4 & p4=$!
+exit 8 & p8=$!
+wait $p4
+[ $? = 4 ] || failure $LINENO
+wait $p8
+[ $? = 8 ] || failure $LINENO
+
+exit 3 & p3=$!
+exit 7 & p7=$!
+wait $p7
+[ $? = 7 ] || failure $LINENO
+wait $p3
+[ $? = 3 ] || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/wait10.0 b/bin/cash/tests/builtins/wait10.0
new file mode 100644
index 00000000..f2f51855
--- /dev/null
+++ b/bin/cash/tests/builtins/wait10.0
@@ -0,0 +1,5 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait10.0 251430 2013-06-05 19:40:52Z jilles $
+# Init cannot be a child of the shell.
+exit 49 & p49=$!
+wait 1 "$p49"
+[ "$?" = 49 ]
diff --git a/bin/cash/tests/builtins/wait2.0 b/bin/cash/tests/builtins/wait2.0
new file mode 100644
index 00000000..c6a93607
--- /dev/null
+++ b/bin/cash/tests/builtins/wait2.0
@@ -0,0 +1,15 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait2.0 208476 2010-05-23 22:10:20Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+for i in 1 2 3 4 5 6 7 8 9 10; do
+	exit $i &
+done
+wait || failure $LINENO
+wait || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/wait3.0 b/bin/cash/tests/builtins/wait3.0
new file mode 100644
index 00000000..b03d07f6
--- /dev/null
+++ b/bin/cash/tests/builtins/wait3.0
@@ -0,0 +1,21 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait3.0 236771 2012-06-08 22:54:25Z jilles $
+
+failures=
+failure() {
+	echo "Error at line $1" >&2
+	failures=x$failures
+}
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX)
+trap 'rm -rf $T' 0
+cd $T || exit 3
+mkfifo fifo1
+for i in 1 2 3 4 5 6 7 8 9 10; do
+	exit $i 4<fifo1 &
+done
+exec 3>fifo1
+wait || failure $LINENO
+(${SH} -c echo >&3) 2>/dev/null && failure $LINENO
+wait || failure $LINENO
+
+test -z "$failures"
diff --git a/bin/cash/tests/builtins/wait4.0 b/bin/cash/tests/builtins/wait4.0
new file mode 100644
index 00000000..dbaeeb10
--- /dev/null
+++ b/bin/cash/tests/builtins/wait4.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait4.0 247206 2013-02-23 22:50:57Z jilles $
+
+T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX`
+trap 'rm -rf $T' 0
+cd $T || exit 3
+mkfifo fifo1
+trapped=
+trap trapped=1 QUIT
+{ kill -QUIT $$; sleep 1; exit 4; } >fifo1 &
+wait $! <fifo1
+r=$?
+[ "$r" -gt 128 ] && [ -n "$trapped" ]
diff --git a/bin/cash/tests/builtins/wait5.0 b/bin/cash/tests/builtins/wait5.0
new file mode 100644
index 00000000..b9a8ed49
--- /dev/null
+++ b/bin/cash/tests/builtins/wait5.0
@@ -0,0 +1,12 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait5.0 247206 2013-02-23 22:50:57Z jilles $
+
+T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX`
+trap 'rm -rf $T' 0
+cd $T || exit 3
+mkfifo fifo1
+trapped=
+trap trapped=1 QUIT
+{ kill -QUIT $$; sleep 1; exit 4; } >fifo1 &
+wait <fifo1
+r=$?
+[ "$r" -gt 128 ] && [ -n "$trapped" ]
diff --git a/bin/cash/tests/builtins/wait6.0 b/bin/cash/tests/builtins/wait6.0
new file mode 100644
index 00000000..2a790ae2
--- /dev/null
+++ b/bin/cash/tests/builtins/wait6.0
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait6.0 248349 2013-03-15 20:29:31Z jilles $
+
+wait --
diff --git a/bin/cash/tests/builtins/wait7.0 b/bin/cash/tests/builtins/wait7.0
new file mode 100644
index 00000000..893cdcb7
--- /dev/null
+++ b/bin/cash/tests/builtins/wait7.0
@@ -0,0 +1,4 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait7.0 248349 2013-03-15 20:29:31Z jilles $
+
+: &
+wait -- $!
diff --git a/bin/cash/tests/builtins/wait8.0 b/bin/cash/tests/builtins/wait8.0
new file mode 100644
index 00000000..8212035b
--- /dev/null
+++ b/bin/cash/tests/builtins/wait8.0
@@ -0,0 +1,7 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait8.0 251429 2013-06-05 19:08:22Z jilles $
+
+exit 44 & p44=$!
+exit 45 & p45=$!
+exit 7 & p7=$!
+wait "$p44" "$p7" "$p45"
+[ "$?" = 45 ]
diff --git a/bin/cash/tests/builtins/wait9.127 b/bin/cash/tests/builtins/wait9.127
new file mode 100644
index 00000000..0e0866c3
--- /dev/null
+++ b/bin/cash/tests/builtins/wait9.127
@@ -0,0 +1,3 @@
+# $FreeBSD: releng/12.0/bin/sh/tests/builtins/wait9.127 251430 2013-06-05 19:40:52Z jilles $
+# Init cannot be a child of the shell.
+wait 1