aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile9
-rw-r--r--bin/cat/Makefile12
-rw-r--r--bin/cat/d_align.in3
-rw-r--r--bin/cat/d_align.out3
-rwxr-xr-xbin/cat/t_cat.sh59
-rw-r--r--bin/cp/Makefile8
-rwxr-xr-xbin/cp/t_cp.sh294
-rw-r--r--bin/dd/Makefile8
-rwxr-xr-xbin/dd/t_dd.sh130
-rw-r--r--bin/df/Makefile27
-rw-r--r--bin/df/getmntinfo.c218
-rwxr-xr-xbin/df/t_df.sh148
-rw-r--r--bin/expr/Makefile8
-rwxr-xr-xbin/expr/t_expr.sh228
-rw-r--r--bin/pax/Makefile8
-rwxr-xr-xbin/pax/t_pax.sh54
-rw-r--r--bin/ps/Makefile12
-rw-r--r--bin/ps/keywords123
-rwxr-xr-xbin/ps/t_ps.sh404
-rw-r--r--bin/sh/Makefile21
-rw-r--r--bin/sh/dotcmd/Makefile40
-rw-r--r--bin/sh/dotcmd/out/case_break_case.out8
-rw-r--r--bin/sh/dotcmd/out/case_break_compound.out8
-rw-r--r--bin/sh/dotcmd/out/case_break_file.out6
-rw-r--r--bin/sh/dotcmd/out/case_break_for.out7
-rw-r--r--bin/sh/dotcmd/out/case_break_func.out8
-rw-r--r--bin/sh/dotcmd/out/case_break_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/case_break_until.out7
-rw-r--r--bin/sh/dotcmd/out/case_break_while.out7
-rw-r--r--bin/sh/dotcmd/out/case_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/case_continue_for.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_until.out8
-rw-r--r--bin/sh/dotcmd/out/case_continue_while.out8
-rw-r--r--bin/sh/dotcmd/out/case_return_case.out6
-rw-r--r--bin/sh/dotcmd/out/case_return_compound.out6
-rw-r--r--bin/sh/dotcmd/out/case_return_file.out5
-rw-r--r--bin/sh/dotcmd/out/case_return_for.out6
-rw-r--r--bin/sh/dotcmd/out/case_return_func.out7
-rw-r--r--bin/sh/dotcmd/out/case_return_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/case_return_until.out6
-rw-r--r--bin/sh/dotcmd/out/case_return_while.out6
-rw-r--r--bin/sh/dotcmd/out/compound_break_case.out8
-rw-r--r--bin/sh/dotcmd/out/compound_break_compound.out8
-rw-r--r--bin/sh/dotcmd/out/compound_break_file.out6
-rw-r--r--bin/sh/dotcmd/out/compound_break_for.out7
-rw-r--r--bin/sh/dotcmd/out/compound_break_func.out8
-rw-r--r--bin/sh/dotcmd/out/compound_break_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/compound_break_until.out7
-rw-r--r--bin/sh/dotcmd/out/compound_break_while.out7
-rw-r--r--bin/sh/dotcmd/out/compound_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/compound_continue_for.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_until.out8
-rw-r--r--bin/sh/dotcmd/out/compound_continue_while.out8
-rw-r--r--bin/sh/dotcmd/out/compound_return_case.out6
-rw-r--r--bin/sh/dotcmd/out/compound_return_compound.out6
-rw-r--r--bin/sh/dotcmd/out/compound_return_file.out5
-rw-r--r--bin/sh/dotcmd/out/compound_return_for.out6
-rw-r--r--bin/sh/dotcmd/out/compound_return_func.out7
-rw-r--r--bin/sh/dotcmd/out/compound_return_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/compound_return_until.out6
-rw-r--r--bin/sh/dotcmd/out/compound_return_while.out6
-rw-r--r--bin/sh/dotcmd/out/file_break_case.out6
-rw-r--r--bin/sh/dotcmd/out/file_break_compound.out6
-rw-r--r--bin/sh/dotcmd/out/file_break_file.out4
-rw-r--r--bin/sh/dotcmd/out/file_break_for.out5
-rw-r--r--bin/sh/dotcmd/out/file_break_func.out6
-rw-r--r--bin/sh/dotcmd/out/file_break_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/file_break_until.out5
-rw-r--r--bin/sh/dotcmd/out/file_break_while.out5
-rw-r--r--bin/sh/dotcmd/out/file_continue_case.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_compound.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_file.out4
-rw-r--r--bin/sh/dotcmd/out/file_continue_for.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_func.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_until.out6
-rw-r--r--bin/sh/dotcmd/out/file_continue_while.out6
-rw-r--r--bin/sh/dotcmd/out/file_return_case.out4
-rw-r--r--bin/sh/dotcmd/out/file_return_compound.out4
-rw-r--r--bin/sh/dotcmd/out/file_return_file.out3
-rw-r--r--bin/sh/dotcmd/out/file_return_for.out4
-rw-r--r--bin/sh/dotcmd/out/file_return_func.out5
-rw-r--r--bin/sh/dotcmd/out/file_return_subshell.out4
-rw-r--r--bin/sh/dotcmd/out/file_return_until.out4
-rw-r--r--bin/sh/dotcmd/out/file_return_while.out4
-rw-r--r--bin/sh/dotcmd/out/for_break_case.out5
-rw-r--r--bin/sh/dotcmd/out/for_break_compound.out5
-rw-r--r--bin/sh/dotcmd/out/for_break_file.out4
-rw-r--r--bin/sh/dotcmd/out/for_break_for.out12
-rw-r--r--bin/sh/dotcmd/out/for_break_func.out5
-rw-r--r--bin/sh/dotcmd/out/for_break_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/for_break_until.out12
-rw-r--r--bin/sh/dotcmd/out/for_break_while.out12
-rw-r--r--bin/sh/dotcmd/out/for_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/for_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/for_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/for_continue_for.out14
-rw-r--r--bin/sh/dotcmd/out/for_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/for_continue_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/for_continue_until.out14
-rw-r--r--bin/sh/dotcmd/out/for_continue_while.out14
-rw-r--r--bin/sh/dotcmd/out/for_return_case.out10
-rw-r--r--bin/sh/dotcmd/out/for_return_compound.out10
-rw-r--r--bin/sh/dotcmd/out/for_return_file.out8
-rw-r--r--bin/sh/dotcmd/out/for_return_for.out10
-rw-r--r--bin/sh/dotcmd/out/for_return_func.out12
-rw-r--r--bin/sh/dotcmd/out/for_return_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/for_return_until.out10
-rw-r--r--bin/sh/dotcmd/out/for_return_while.out10
-rw-r--r--bin/sh/dotcmd/out/func_break_case.out8
-rw-r--r--bin/sh/dotcmd/out/func_break_compound.out8
-rw-r--r--bin/sh/dotcmd/out/func_break_file.out6
-rw-r--r--bin/sh/dotcmd/out/func_break_for.out7
-rw-r--r--bin/sh/dotcmd/out/func_break_func.out8
-rw-r--r--bin/sh/dotcmd/out/func_break_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/func_break_until.out7
-rw-r--r--bin/sh/dotcmd/out/func_break_while.out7
-rw-r--r--bin/sh/dotcmd/out/func_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/func_continue_for.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_until.out8
-rw-r--r--bin/sh/dotcmd/out/func_continue_while.out8
-rw-r--r--bin/sh/dotcmd/out/func_return_case.out6
-rw-r--r--bin/sh/dotcmd/out/func_return_compound.out6
-rw-r--r--bin/sh/dotcmd/out/func_return_file.out5
-rw-r--r--bin/sh/dotcmd/out/func_return_for.out6
-rw-r--r--bin/sh/dotcmd/out/func_return_func.out7
-rw-r--r--bin/sh/dotcmd/out/func_return_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/func_return_until.out6
-rw-r--r--bin/sh/dotcmd/out/func_return_while.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_break_case.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_break_compound.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_break_file.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_break_for.out7
-rw-r--r--bin/sh/dotcmd/out/subshell_break_func.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_break_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_break_until.out7
-rw-r--r--bin/sh/dotcmd/out/subshell_break_while.out7
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_for.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_subshell.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_until.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_continue_while.out8
-rw-r--r--bin/sh/dotcmd/out/subshell_return_case.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_return_compound.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_return_file.out5
-rw-r--r--bin/sh/dotcmd/out/subshell_return_for.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_return_func.out7
-rw-r--r--bin/sh/dotcmd/out/subshell_return_subshell.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_return_until.out6
-rw-r--r--bin/sh/dotcmd/out/subshell_return_while.out6
-rw-r--r--bin/sh/dotcmd/out/until_break_case.out5
-rw-r--r--bin/sh/dotcmd/out/until_break_compound.out5
-rw-r--r--bin/sh/dotcmd/out/until_break_file.out4
-rw-r--r--bin/sh/dotcmd/out/until_break_for.out12
-rw-r--r--bin/sh/dotcmd/out/until_break_func.out5
-rw-r--r--bin/sh/dotcmd/out/until_break_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/until_break_until.out12
-rw-r--r--bin/sh/dotcmd/out/until_break_while.out12
-rw-r--r--bin/sh/dotcmd/out/until_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/until_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/until_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/until_continue_for.out14
-rw-r--r--bin/sh/dotcmd/out/until_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/until_continue_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/until_continue_until.out14
-rw-r--r--bin/sh/dotcmd/out/until_continue_while.out14
-rw-r--r--bin/sh/dotcmd/out/until_return_case.out10
-rw-r--r--bin/sh/dotcmd/out/until_return_compound.out10
-rw-r--r--bin/sh/dotcmd/out/until_return_file.out8
-rw-r--r--bin/sh/dotcmd/out/until_return_for.out10
-rw-r--r--bin/sh/dotcmd/out/until_return_func.out12
-rw-r--r--bin/sh/dotcmd/out/until_return_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/until_return_until.out10
-rw-r--r--bin/sh/dotcmd/out/until_return_while.out10
-rw-r--r--bin/sh/dotcmd/out/while_break_case.out5
-rw-r--r--bin/sh/dotcmd/out/while_break_compound.out5
-rw-r--r--bin/sh/dotcmd/out/while_break_file.out4
-rw-r--r--bin/sh/dotcmd/out/while_break_for.out12
-rw-r--r--bin/sh/dotcmd/out/while_break_func.out5
-rw-r--r--bin/sh/dotcmd/out/while_break_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/while_break_until.out12
-rw-r--r--bin/sh/dotcmd/out/while_break_while.out12
-rw-r--r--bin/sh/dotcmd/out/while_continue_case.out8
-rw-r--r--bin/sh/dotcmd/out/while_continue_compound.out8
-rw-r--r--bin/sh/dotcmd/out/while_continue_file.out6
-rw-r--r--bin/sh/dotcmd/out/while_continue_for.out14
-rw-r--r--bin/sh/dotcmd/out/while_continue_func.out8
-rw-r--r--bin/sh/dotcmd/out/while_continue_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/while_continue_until.out14
-rw-r--r--bin/sh/dotcmd/out/while_continue_while.out14
-rw-r--r--bin/sh/dotcmd/out/while_return_case.out10
-rw-r--r--bin/sh/dotcmd/out/while_return_compound.out10
-rw-r--r--bin/sh/dotcmd/out/while_return_file.out8
-rw-r--r--bin/sh/dotcmd/out/while_return_for.out10
-rw-r--r--bin/sh/dotcmd/out/while_return_func.out12
-rw-r--r--bin/sh/dotcmd/out/while_return_subshell.out10
-rw-r--r--bin/sh/dotcmd/out/while_return_until.out10
-rw-r--r--bin/sh/dotcmd/out/while_return_while.out10
-rwxr-xr-xbin/sh/dotcmd/scoped_command129
-rwxr-xr-xbin/sh/dotcmd/t_dotcmd.sh76
-rwxr-xr-xbin/sh/t_compexit.sh63
-rwxr-xr-xbin/sh/t_evaltested.sh60
-rwxr-xr-xbin/sh/t_exit.sh105
-rwxr-xr-xbin/sh/t_expand.sh142
-rwxr-xr-xbin/sh/t_fsplit.sh186
-rwxr-xr-xbin/sh/t_here.sh73
-rwxr-xr-xbin/sh/t_set_e.sh289
-rwxr-xr-xbin/sh/t_ulimit.sh46
-rwxr-xr-xbin/sh/t_varquote.sh81
-rwxr-xr-xbin/sh/t_wait.sh59
-rw-r--r--bin/sleep/Makefile8
-rwxr-xr-xbin/sleep/t_sleep.sh72
-rw-r--r--bin/tar/Makefile8
-rwxr-xr-xbin/tar/t_tar.sh51
229 files changed, 4743 insertions, 0 deletions
diff --git a/bin/Makefile b/bin/Makefile
new file mode 100644
index 000000000000..ba1cac0065bd
--- /dev/null
+++ b/bin/Makefile
@@ -0,0 +1,9 @@
+# $NetBSD: Makefile,v 1.3 2012/03/30 15:49:24 njoly Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin
+
+TESTS_SUBDIRS= cat cp dd df expr pax ps sh sleep tar
+
+.include <bsd.test.mk>
diff --git a/bin/cat/Makefile b/bin/cat/Makefile
new file mode 100644
index 000000000000..52ce91febcb7
--- /dev/null
+++ b/bin/cat/Makefile
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1 2012/03/27 08:16:33 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/cat
+TESTS_SH= t_cat
+
+FILESDIR= ${TESTSDIR}
+FILES+= d_align.in
+FILES+= d_align.out
+
+.include <bsd.test.mk>
diff --git a/bin/cat/d_align.in b/bin/cat/d_align.in
new file mode 100644
index 000000000000..31bf4a7a143f
--- /dev/null
+++ b/bin/cat/d_align.in
@@ -0,0 +1,3 @@
+a b c
+1 2 3
+x y z
diff --git a/bin/cat/d_align.out b/bin/cat/d_align.out
new file mode 100644
index 000000000000..fd324697185b
--- /dev/null
+++ b/bin/cat/d_align.out
@@ -0,0 +1,3 @@
+ 1 a b c$
+ 2 1 2 3$
+ 3 x y z$
diff --git a/bin/cat/t_cat.sh b/bin/cat/t_cat.sh
new file mode 100755
index 000000000000..1b7a9307eeeb
--- /dev/null
+++ b/bin/cat/t_cat.sh
@@ -0,0 +1,59 @@
+# $NetBSD: t_cat.sh,v 1.2 2012/03/27 17:57:02 jruoho Exp $
+#
+# Copyright (c) 2012 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Jukka Ruohonen.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case align
+align_head() {
+ atf_set "descr" "Test that cat(1) aligns the output " \
+ "right with options '-be' (PR bin/4841)"
+}
+
+align_body() {
+
+ atf_check -s ignore -o file:$(atf_get_srcdir)/d_align.out \
+ -x "cat -be $(atf_get_srcdir)/d_align.in"
+}
+
+atf_test_case nonexistent
+nonexistent_head() {
+ atf_set "descr" "Test that cat(1) doesn't return zero exit " \
+ "status for a nonexistent file (PR bin/3538)"
+}
+
+nonexistent_body() {
+
+ atf_check -s not-exit:0 -o empty -e not-empty \
+ -x "cat /some/name/that/does/not/exist"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case align
+ atf_add_test_case nonexistent
+}
diff --git a/bin/cp/Makefile b/bin/cp/Makefile
new file mode 100644
index 000000000000..b5afd3f23817
--- /dev/null
+++ b/bin/cp/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:10 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/cp
+TESTS_SH= t_cp
+
+.include <bsd.test.mk>
diff --git a/bin/cp/t_cp.sh b/bin/cp/t_cp.sh
new file mode 100755
index 000000000000..be55c7cb0ef3
--- /dev/null
+++ b/bin/cp/t_cp.sh
@@ -0,0 +1,294 @@
+# $NetBSD: t_cp.sh,v 1.1 2012/03/17 16:33:10 jruoho Exp $
+#
+# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+FILES="file file2 file3 link dir dir2 dirlink target"
+
+cleanup() {
+ rm -fr ${FILES}
+}
+
+cp_compare() {
+ echo "Ensuring that $2 and $3 are identical"
+ cmp -s $2 $3 || atf_fail "$2 and $3 are different"
+}
+
+reset() {
+ cleanup
+ echo "I'm a file" > file
+ echo "I'm a file, 2" > file2
+ echo "I'm a file, 3" > file3
+ ln -s file link
+ mkdir dir
+ ln -s dir dirlink
+}
+
+atf_test_case file_to_file
+file_to_file_head() {
+ atf_set "descr" "Checks the copy of a file to a file"
+}
+file_to_file_body() {
+ reset
+
+ file_to_file_simple
+ file_to_file_preserve
+ file_to_file_noflags
+}
+
+file_to_file_simple() {
+ rm -f file2
+ umask 022
+ chmod 777 file
+ atf_check -s eq:0 -o empty -e empty cp file file2
+ cp_compare file_to_file_simple file file2
+ if [ `stat -f "%Lp" file2` != "755" ]; then
+ atf_fail "new file not created with umask"
+ fi
+
+ chmod 644 file
+ chmod 777 file2
+ cp_compare file_to_file_simple file file2
+ if [ `stat -f "%Lp" file2` != "777" ]; then
+ atf_fail "existing files permissions not retained"
+ fi
+}
+
+file_to_file_preserve() {
+ rm file3
+ chmod 644 file
+ chflags nodump file
+ atf_check -s eq:0 -o empty -e empty cp -p file file3
+ finfo=`stat -f "%p%u%g%m%z%f" file`
+ f3info=`stat -f "%p%u%g%m%z%f" file3`
+ if [ $finfo != $f3info ]; then
+ atf_fail "attributes not preserved"
+ fi
+}
+
+file_to_file_noflags() {
+ rm file3
+ chmod 644 file
+ chflags nodump file
+ atf_check -s eq:0 -o empty -e empty cp -p -N file file3
+ finfo=`stat -f "%f" file`
+ f3info=`stat -f "%f" file3`
+ if [ $finfo = $f3info ]; then
+ atf_fail "-p -N preserved file flags"
+ fi
+}
+
+atf_test_case file_to_link
+file_to_link_head() {
+ atf_set "descr" "Checks the copy of a file to a symbolic link"
+}
+file_to_link_body() {
+ reset
+ atf_check -s eq:0 -o empty -e empty cp file2 link
+ cp_compare file_to_link file file2
+}
+
+atf_test_case link_to_file
+link_to_file_head() {
+ atf_set "descr" "Checks the copy of a symbolic link to a file"
+}
+link_to_file_body() {
+ reset
+ # file and link are identical (not copied).
+ atf_check -s eq:1 -o empty -e ignore cp link file
+ atf_check -s eq:0 -o empty -e empty cp link file2
+ cp_compare link_to_file file file2
+}
+
+atf_test_case file_over_link
+file_over_link_head() {
+ atf_set "descr" "Checks the copy of a file to a symbolic link" \
+ "without following it"
+}
+file_over_link_body() {
+ reset
+ atf_check -s eq:0 -o empty -e empty cp -P file link
+ cp_compare file_over_link file link
+}
+
+atf_test_case link_over_file
+link_over_file_head() {
+ atf_set "descr" "Checks the copy of a symbolic link to a file" \
+ "without following the former"
+}
+link_over_file_body() {
+ reset
+ atf_check -s eq:0 -o empty -e empty cp -P link file
+ if [ `readlink link` != `readlink file` ]; then
+ atf_fail "readlink link != readlink file"
+ fi
+}
+
+atf_test_case files_to_dir
+files_to_dir_head() {
+ atf_set "descr" "Checks the copy of multiple files into a directory"
+}
+files_to_dir_body() {
+ reset
+ # can't copy multiple files to a file
+ atf_check -s eq:1 -o empty -e ignore cp file file2 file3
+ atf_check -s eq:0 -o empty -e empty cp file file2 link dir
+ cp_compare files_to_dir file "dir/file"
+}
+
+atf_test_case dir_to_file
+dir_to_file_head() {
+ atf_set "descr" "Checks the copy of a directory onto a file, which" \
+ "should not work"
+}
+dir_to_file_body() {
+ reset
+ # can't copy a dir onto a file
+ atf_check -s eq:1 -o empty -e ignore cp dir file
+ atf_check -s eq:1 -o empty -e ignore cp -R dir file
+}
+
+atf_test_case file_to_linkdir
+file_to_linkdir_head() {
+ atf_set "descr" "Checks the copy of a file to a symbolic link that" \
+ "points to a directory"
+}
+file_to_linkdir_body() {
+ reset
+ atf_check -s eq:0 -o empty -e empty cp file dirlink
+ cp_compare file_to_linkdir file "dir/file"
+
+ # overwrite the link
+ atf_check -s eq:0 -o empty -e empty cp -P file dirlink
+ atf_check -s eq:1 -o empty -e empty readlink dirlink
+ cp_compare file_to_linkdir file dirlink
+}
+
+atf_test_case linkdir_to_file
+linkdir_to_file_head() {
+ atf_set "descr" "Checks the copy of a symbolic link that points to" \
+ "a directory onto a file"
+}
+linkdir_to_file_body() {
+ reset
+ # cannot copy a dir onto a file
+ atf_check -s eq:1 -o empty -e ignore cp dirlink file
+
+ # overwrite the link
+ atf_check -s eq:0 -o empty -e empty cp -P dirlink file
+ if [ `readlink file` != `readlink dirlink` ]; then
+ atf_fail "readlink link != readlink file"
+ fi
+}
+
+dir_to_dne_no_R() {
+ atf_check -s eq:1 -o empty -e ignore cp dir dir2
+}
+
+dir_to_dne() {
+ atf_check -s eq:0 -o empty -e empty cp -R dir dir2
+ cp_compare dir_to_dne "dir/file" "dir2/file"
+ readlink dir2/link >/dev/null
+ if [ $? -gt 0 ]; then
+ atf_fail "-R didn't copy a link as a link"
+ fi
+}
+
+dir_to_dir_H() {
+ dir_to_dir_setup
+ atf_check -s eq:0 -o empty -e empty cp -R dir dir2
+
+ chmod 777 dir
+
+ # copy a dir into a dir, only command-line links are followed
+ atf_check -s eq:0 -o empty -e empty cp -R -H dirlink dir2
+ cp_compare dir_to_dir_H "dir/file" "dir2/dirlink/file"
+ readlink dir2/dirlink/link >/dev/null
+ if [ $? -gt 0 ]; then
+ atf_fail "didn't copy a link as a link"
+ fi
+
+ # Created directories have the same mode as the corresponding
+ # source directory, unmodified by the process's umask.
+ if [ `stat -f "%Lp" dir2/dirlink` != "777" ]; then
+ atf_fail "-R modified dir perms with umask"
+ fi
+}
+
+dir_to_dir_L() {
+ dir_to_dir_setup
+ atf_check -s eq:0 -o empty -e empty cp -R dir dir2
+ atf_check -s eq:0 -o empty -e empty cp -R -H dirlink dir2
+
+ # copy a dir into a dir, following all links
+ atf_check -s eq:0 -o empty -e empty cp -R -H -L dirlink dir2/dirlink
+ cp_compare dir_to_dir_L "dir/file" "dir2/dirlink/dirlink/file"
+ # fail if -R -L copied a link as a link
+ atf_check -s eq:1 -o ignore -e empty readlink dir2/dirlink/dirlink/link
+}
+
+dir_to_dir_subdir_exists() {
+ # recursively copy a dir into another dir, with some subdirs already
+ # existing
+ cleanup
+
+ mkdir -p dir/1 dir/2 dir/3 target/2
+ echo "file" > dir/2/file
+ atf_check -s eq:0 -o empty -e empty cp -R dir/* target
+ cp_compare dir_to_dir_subdir_exists "dir/2/file" "target/2/file"
+}
+
+dir_to_dir_setup() {
+ reset
+ umask 077
+ cp -P file file2 file3 link dir
+}
+
+atf_test_case dir_to_dir
+dir_to_dir_head() {
+ atf_set "descr" "Checks the copy of a directory onto another directory"
+}
+dir_to_dir_body() {
+ dir_to_dir_setup
+ dir_to_dne_no_R
+ dir_to_dne
+ dir_to_dir_H
+ dir_to_dir_L
+ dir_to_dir_subdir_exists
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case file_to_file
+ atf_add_test_case file_to_link
+ atf_add_test_case link_to_file
+ atf_add_test_case file_over_link
+ atf_add_test_case link_over_file
+ atf_add_test_case files_to_dir
+ atf_add_test_case file_to_linkdir
+ atf_add_test_case linkdir_to_file
+ atf_add_test_case dir_to_file
+ atf_add_test_case dir_to_dir
+}
diff --git a/bin/dd/Makefile b/bin/dd/Makefile
new file mode 100644
index 000000000000..8e741d5c1d15
--- /dev/null
+++ b/bin/dd/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/dd
+TESTS_SH= t_dd
+
+.include <bsd.test.mk>
diff --git a/bin/dd/t_dd.sh b/bin/dd/t_dd.sh
new file mode 100755
index 000000000000..d713ad9cb246
--- /dev/null
+++ b/bin/dd/t_dd.sh
@@ -0,0 +1,130 @@
+# $NetBSD: t_dd.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+test_dd_length() {
+ result=$1
+ cmd=$2
+ set -- x `eval $cmd | wc -c`
+ res=$2
+ if [ x"$res" != x"$result" ]; then
+ atf_fail "Expected $result bytes of output, got $res: $cmd"
+ fi
+}
+
+atf_test_case length
+length_head() {
+ # XXX The PR should be stored in a tag.
+ atf_set "descr" "Test for result messages accidentally pumped into" \
+ "the output file if the standard IO descriptors are" \
+ "closed. The last of the three following tests is" \
+ "the one expected to fail. (NetBSD PR bin/8521)"
+}
+length_body() {
+ test_dd_length 512 \
+ "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >/dev/null 2>/dev/null"
+ test_dd_length 512 \
+ "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >&- 2>/dev/null"
+ test_dd_length 512 \
+ "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >&- 2>&-"
+}
+
+test_dd_io() {
+ res="`echo -n "$2" | eval $1`"
+ if [ x"$res" != x"$3" ]; then
+ atf_fail "Expected \"$3\", got \"$res\": $1"
+ fi
+}
+
+allbits1="\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
+
+ebcdicbits1="\000\001\002\003\067\055\056\057\026\005\045\013\014\015\016\017\020\021\022\023\074\075\062\046\030\031\077\047\034\035\036\037\100\132\177\173\133\154\120\175\115\135\134\116\153\140\113\141\360\361\362\363\364\365\366\367\370\371\172\136\114\176\156\157\174\301\302\303\304\305\306\307\310\311\321\322\323\324\325\326\327\330\331\342\343\344\345\346\347\350\351\255\340\275\232\155\171\201\202\203\204\205\206\207\210\211\221\222\223\224\225\226\227\230\231\242\243\244\245\246\247\250\251\300\117\320\137\007\040\041\042\043\044\025\006\027\050\051\052\053\054\011\012\033\060\061\032\063\064\065\066\010\070\071\072\073\004\024\076\341\101\102\103\104\105\106\107\110\111\121\122\123\124\125\126\127\130\131\142\143\144\145\146\147\150\151\160\161\162\163\164\165\166\167\170\200\212\213\214\215\216\217\220\152\233\234\235\236\237\240\252\253\254\112\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\241\276\277\312\313\314\315\316\317\332\333\334\335\336\337\352\353\354\355\356\357\372\373\374\375\376\377"
+
+allvisbits=`echo -n "$allbits1" | unvis | vis`
+ebcdicvisbits=`echo -n "$ebcdicbits1" | unvis | vis`
+
+atf_test_case io
+io_head() {
+ atf_set "descr" "This checks the combination of bs= with" \
+ "conv=ebcdic. Prior to revision 1.24 of dd's" \
+ "args.c, the conv option would be ignored."
+}
+io_body() {
+ test_dd_io "unvis | dd 2>/dev/null | vis" \
+ "$allvisbits" "$allvisbits"
+ test_dd_io "unvis | dd ibs=1 2>/dev/null | vis" \
+ "$allvisbits" "$allvisbits"
+ test_dd_io "unvis | dd obs=1 2>/dev/null | vis" \
+ "$allvisbits" "$allvisbits"
+ test_dd_io "unvis | dd bs=1 2>/dev/null | vis" \
+ "$allvisbits" "$allvisbits"
+
+ test_dd_io "unvis | dd conv=ebcdic 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic ibs=512 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic obs=512 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic bs=512 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+
+ test_dd_io "unvis | dd conv=ebcdic 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic ibs=1 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic obs=1 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+ test_dd_io "unvis | dd conv=ebcdic bs=1 2>/dev/null | vis" \
+ "$allvisbits" "$ebcdicvisbits"
+}
+
+atf_test_case seek
+seek_head() {
+ atf_set "descr" "Tests output file seeking"
+}
+
+seek_body() {
+ echo TEST1234 > testfile
+ atf_check -s exit:0 -e ignore \
+ dd if=/dev/zero of=testfile seek=1 bs=8k count=1
+ atf_check -s exit:0 -e ignore -o match:'^TEST1234$' dd if=testfile
+ eval $(stat -s testfile)
+ atf_check_equal $st_size $((2*8192))
+
+ echo -n TEST1234 > tf2
+ atf_check -s exit:0 -e ignore -x \
+ 'dd bs=4 if=/dev/zero count=1 | tr \\0 \\n | dd of=tf2 bs=4 seek=1'
+ atf_check -s exit:0 -e ignore -o match:'^TEST$' dd if=tf2
+ eval $(stat -s tf2)
+ atf_check_equal $st_size 8
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case length
+ atf_add_test_case io
+ atf_add_test_case seek
+}
diff --git a/bin/df/Makefile b/bin/df/Makefile
new file mode 100644
index 000000000000..1a65f60a67a6
--- /dev/null
+++ b/bin/df/Makefile
@@ -0,0 +1,27 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+NOMAN= # defined
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/df
+
+TESTS_SH= t_df
+
+BINDIR= ${TESTSDIR}
+PROG= h_df
+.PATH: ${NETBSDSRCDIR}/bin/df
+SRCS= df.c getmntinfo.c
+
+LDADD+= -lutil
+DPADD+= ${LIBUTIL}
+
+# Pass -DINTREE to make to test using humanize_number.c in source tree
+# directly instead of the one in libc.
+.if defined(INTREE)
+.PATH: ${NETBSDSRCDIR}/lib/libc/gen
+CPPFLAGS+= -I${NETBSDSRCDIR}/lib/libc/include
+SRCS+= humanize_number.c
+.endif
+
+.include <bsd.test.mk>
diff --git a/bin/df/getmntinfo.c b/bin/df/getmntinfo.c
new file mode 100644
index 000000000000..4ad1f40ce6be
--- /dev/null
+++ b/bin/df/getmntinfo.c
@@ -0,0 +1,218 @@
+/* $NetBSD: getmntinfo.c,v 1.1 2012/03/17 16:33:11 jruoho Exp $ */
+/*
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define KB * 1024
+#define MB * 1024 KB
+#define GB * 1024 MB
+
+static struct statvfs *getnewstatvfs(void);
+static void other_variants(const struct statvfs *, const int *, int,
+ const int *, int);
+static void setup_filer(void);
+static void setup_ld0g(void);
+static void setup_strpct(void);
+
+static struct statvfs *allstatvfs;
+static int sftotal, sfused;
+
+struct statvfs *
+getnewstatvfs(void)
+{
+
+ if (sftotal == sfused) {
+ sftotal = sftotal ? sftotal * 2 : 1;
+ allstatvfs = realloc(allstatvfs,
+ sftotal * sizeof(struct statvfs));
+ if (allstatvfs == NULL)
+ err(EXIT_FAILURE, "realloc");
+ }
+
+ return (&allstatvfs[sfused++]);
+}
+
+void
+other_variants(const struct statvfs *tmpl, const int *minfree, int minfreecnt,
+ const int *consumed, int consumedcnt)
+{
+ int64_t total, used;
+ struct statvfs *sf;
+ int i, j;
+
+ for (i = 0; i < minfreecnt; i++)
+ for (j = 0; j < consumedcnt; j++) {
+ sf = getnewstatvfs();
+ *sf = *tmpl;
+ total = (int64_t)(u_long)sf->f_blocks * sf->f_bsize;
+ used = total * consumed[j] / 100;
+ sf->f_bfree = (total - used) / sf->f_bsize;
+ sf->f_bavail = (total * (100 - minfree[i]) / 100 -
+ used) / (int)sf->f_bsize;
+ sf->f_bresvd = sf->f_bfree - sf->f_bavail;
+ }
+}
+
+/*
+ * Parameter taken from:
+ * http://mail-index.NetBSD.org/tech-userlevel/2004/03/24/0001.html
+ */
+void
+setup_filer(void)
+{
+ static const struct statvfs tmpl = {
+#define BSIZE 512
+#define TOTAL 1147ULL GB
+#define USED 132ULL MB
+ .f_bsize = BSIZE,
+ .f_frsize = BSIZE,
+ .f_blocks = TOTAL / BSIZE,
+ .f_bfree = (TOTAL - USED) / BSIZE,
+ .f_bavail = (TOTAL - USED) / BSIZE,
+ .f_bresvd = 0,
+ .f_mntfromname = "filer:/",
+ .f_mntonname = "/filer",
+#undef USED
+#undef TOTAL
+#undef BSIZE
+ };
+ static const int minfree[] = { 0, 5, 10, 15, };
+ static const int consumed[] = { 0, 20, 60, 95, 100 };
+
+ *getnewstatvfs() = tmpl;
+ other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]),
+ consumed, sizeof(consumed) / sizeof(consumed[0]));
+}
+
+/*
+ * Parameter taken from:
+ * http://mail-index.NetBSD.org/current-users/2004/03/01/0038.html
+ */
+void
+setup_ld0g(void)
+{
+ static const struct statvfs tmpl = {
+#define BSIZE 4096 /* Guess */
+#define TOTAL 1308726116ULL KB
+#define USED 17901268ULL KB
+#define AVAIL 1225388540ULL KB
+ .f_bsize = BSIZE,
+ .f_frsize = BSIZE,
+ .f_blocks = TOTAL / BSIZE,
+ .f_bfree = (TOTAL - USED) / BSIZE,
+ .f_bavail = AVAIL / BSIZE,
+ .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE,
+ .f_mntfromname = "/dev/ld0g",
+ .f_mntonname = "/anon-root",
+#undef AVAIL
+#undef USED
+#undef TOTAL
+#undef BSIZE
+ };
+ static const int minfree[] = { 0, 5, 10, 15, };
+ static const int consumed[] = { 0, 20, 60, 95, 100 };
+
+ *getnewstatvfs() = tmpl;
+ other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]),
+ consumed, sizeof(consumed) / sizeof(consumed[0]));
+}
+
+/*
+ * Test of strpct() with huge number.
+ */
+void
+setup_strpct(void)
+{
+ static const struct statvfs tmpl = {
+#define BSIZE 4096 /* Guess */
+#define TOTAL 0x4ffffffffULL KB
+#define USED (TOTAL / 2)
+#define AVAIL (TOTAL / 2)
+ .f_bsize = BSIZE,
+ .f_frsize = BSIZE,
+ .f_blocks = TOTAL / BSIZE,
+ .f_bfree = (TOTAL - USED) / BSIZE,
+ .f_bavail = AVAIL / BSIZE,
+ .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE,
+ .f_mntfromname = "/dev/strpct",
+ .f_mntonname = "/strpct",
+#undef AVAIL
+#undef USED
+#undef TOTAL
+#undef BSIZE
+ };
+
+ *getnewstatvfs() = tmpl;
+}
+
+/*
+ * Parameter taken from:
+ * http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=23600
+ */
+static void
+setup_pr23600(void)
+{
+ static const struct statvfs tmpl = {
+#define BSIZE 512
+#define TOTAL 20971376ULL
+#define USED 5719864ULL
+#define AVAIL 15251512ULL
+ .f_bsize = BSIZE,
+ .f_frsize = BSIZE,
+ .f_blocks = TOTAL,
+ .f_bfree = TOTAL - USED,
+ .f_bavail = AVAIL,
+ .f_bresvd = TOTAL - USED - AVAIL,
+ .f_mntfromname = "/dev/wd0e",
+ .f_mntonname = "/mount/windows/C",
+#undef AVAIL
+#undef USED
+#undef TOTAL
+#undef BSIZE
+ };
+
+ *getnewstatvfs() = tmpl;
+}
+
+int
+getmntinfo(struct statvfs **mntbuf, int flags)
+{
+
+ setup_filer();
+ setup_ld0g();
+ setup_strpct();
+ setup_pr23600();
+
+ *mntbuf = allstatvfs;
+ return (sfused);
+}
diff --git a/bin/df/t_df.sh b/bin/df/t_df.sh
new file mode 100755
index 000000000000..ffb5aad3e0d0
--- /dev/null
+++ b/bin/df/t_df.sh
@@ -0,0 +1,148 @@
+# $NetBSD: t_df.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case normal
+normal_head() {
+ atf_set "descr" "Checks that the output of df without flags is" \
+ "correct according to some already-known, sane" \
+ "output"
+}
+normal_body() {
+ cat >expout <<EOF
+Filesystem 1K-blocks Used Avail %Cap Mounted on
+filer:/ 1202716672 135168 1202581504 0% /filer
+filer:/ 1202716672 0 1202716672 0% /filer
+filer:/ 1202716672 240543334 962173337 20% /filer
+filer:/ 1202716672 721630003 481086668 60% /filer
+filer:/ 1202716672 1142580838 60135833 95% /filer
+filer:/ 1202716672 1202716672 0 100% /filer
+filer:/ 1202716672 0 1142580838 0% /filer
+filer:/ 1202716672 240543334 902037504 21% /filer
+filer:/ 1202716672 721630003 420950835 63% /filer
+filer:/ 1202716672 1142580838 0 100% /filer
+filer:/ 1202716672 1202716672 -60135833 105% /filer
+filer:/ 1202716672 0 1082445004 0% /filer
+filer:/ 1202716672 240543334 841901670 22% /filer
+filer:/ 1202716672 721630003 360815001 66% /filer
+filer:/ 1202716672 1142580838 -60135833 105% /filer
+filer:/ 1202716672 1202716672 -120271667 111% /filer
+filer:/ 1202716672 0 1022309171 0% /filer
+filer:/ 1202716672 240543334 781765836 23% /filer
+filer:/ 1202716672 721630003 300679168 70% /filer
+filer:/ 1202716672 1142580838 -120271667 111% /filer
+filer:/ 1202716672 1202716672 -180407500 117% /filer
+/dev/ld0g 1308726116 17901268 1225388540 1% /anon-root
+/dev/ld0g 1308726116 0 1308726116 0% /anon-root
+/dev/ld0g 1308726116 261745224 1046980892 20% /anon-root
+/dev/ld0g 1308726116 785235672 523490444 60% /anon-root
+/dev/ld0g 1308726116 1243289812 65436304 95% /anon-root
+/dev/ld0g 1308726116 1308726116 0 100% /anon-root
+/dev/ld0g 1308726116 0 1243289808 0% /anon-root
+/dev/ld0g 1308726116 261745224 981544584 21% /anon-root
+/dev/ld0g 1308726116 785235672 458054140 63% /anon-root
+/dev/ld0g 1308726116 1243289812 0 100% /anon-root
+/dev/ld0g 1308726116 1308726116 -65436304 105% /anon-root
+/dev/ld0g 1308726116 0 1177853504 0% /anon-root
+/dev/ld0g 1308726116 261745224 916108280 22% /anon-root
+/dev/ld0g 1308726116 785235672 392617832 66% /anon-root
+/dev/ld0g 1308726116 1243289812 -65436304 105% /anon-root
+/dev/ld0g 1308726116 1308726116 -130872608 111% /anon-root
+/dev/ld0g 1308726116 0 1112417196 0% /anon-root
+/dev/ld0g 1308726116 261745224 850671972 23% /anon-root
+/dev/ld0g 1308726116 785235672 327181528 70% /anon-root
+/dev/ld0g 1308726116 1243289812 -130872608 111% /anon-root
+/dev/ld0g 1308726116 1308726116 -196308916 117% /anon-root
+/dev/strpct 21474836476 10737418240 10737418236 50% /strpct
+/dev/wd0e 10485688 2859932 7625756 27% /mount/windows/C
+EOF
+ atf_check -s eq:0 -o file:expout -e empty \
+ -x "BLOCKSIZE=1k $(atf_get_srcdir)/h_df -n"
+}
+
+atf_test_case hflag
+hflag_head() {
+ atf_set "descr" "Checks that the output of df is correct according" \
+ "to some already-known, sane output when using the" \
+ "human readable format"
+}
+hflag_body() {
+ cat >expout <<EOF
+Filesystem Size Used Avail %Cap Mounted on
+filer:/ 1.1T 132M 1.1T 0% /filer
+filer:/ 1.1T 0B 1.1T 0% /filer
+filer:/ 1.1T 229G 918G 20% /filer
+filer:/ 1.1T 688G 459G 60% /filer
+filer:/ 1.1T 1.1T 57G 95% /filer
+filer:/ 1.1T 1.1T 0B 100% /filer
+filer:/ 1.1T 0B 1.1T 0% /filer
+filer:/ 1.1T 229G 860G 21% /filer
+filer:/ 1.1T 688G 401G 63% /filer
+filer:/ 1.1T 1.1T 0B 100% /filer
+filer:/ 1.1T 1.1T -57G 105% /filer
+filer:/ 1.1T 0B 1.0T 0% /filer
+filer:/ 1.1T 229G 803G 22% /filer
+filer:/ 1.1T 688G 344G 66% /filer
+filer:/ 1.1T 1.1T -57G 105% /filer
+filer:/ 1.1T 1.1T -115G 111% /filer
+filer:/ 1.1T 0B 975G 0% /filer
+filer:/ 1.1T 229G 746G 23% /filer
+filer:/ 1.1T 688G 287G 70% /filer
+filer:/ 1.1T 1.1T -115G 111% /filer
+filer:/ 1.1T 1.1T -172G 117% /filer
+/dev/ld0g 1.2T 17G 1.1T 1% /anon-root
+/dev/ld0g 1.2T 0B 1.2T 0% /anon-root
+/dev/ld0g 1.2T 250G 998G 20% /anon-root
+/dev/ld0g 1.2T 749G 499G 60% /anon-root
+/dev/ld0g 1.2T 1.2T 62G 95% /anon-root
+/dev/ld0g 1.2T 1.2T 0B 100% /anon-root
+/dev/ld0g 1.2T 0B 1.2T 0% /anon-root
+/dev/ld0g 1.2T 250G 936G 21% /anon-root
+/dev/ld0g 1.2T 749G 437G 63% /anon-root
+/dev/ld0g 1.2T 1.2T 0B 100% /anon-root
+/dev/ld0g 1.2T 1.2T -62G 105% /anon-root
+/dev/ld0g 1.2T 0B 1.1T 0% /anon-root
+/dev/ld0g 1.2T 250G 874G 22% /anon-root
+/dev/ld0g 1.2T 749G 374G 66% /anon-root
+/dev/ld0g 1.2T 1.2T -62G 105% /anon-root
+/dev/ld0g 1.2T 1.2T -125G 111% /anon-root
+/dev/ld0g 1.2T 0B 1.0T 0% /anon-root
+/dev/ld0g 1.2T 250G 811G 23% /anon-root
+/dev/ld0g 1.2T 749G 312G 70% /anon-root
+/dev/ld0g 1.2T 1.2T -125G 111% /anon-root
+/dev/ld0g 1.2T 1.2T -187G 117% /anon-root
+/dev/strpct 20T 10T 10T 50% /strpct
+/dev/wd0e 10G 2.7G 7.3G 27% /mount/windows/C
+EOF
+ atf_check -s eq:0 -o file:expout -e empty \
+ -x "BLOCKSIZE=1k $(atf_get_srcdir)/h_df -hn"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case normal
+ atf_add_test_case hflag
+}
diff --git a/bin/expr/Makefile b/bin/expr/Makefile
new file mode 100644
index 000000000000..fb82d9c5931f
--- /dev/null
+++ b/bin/expr/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/expr
+TESTS_SH= t_expr
+
+.include <bsd.test.mk>
diff --git a/bin/expr/t_expr.sh b/bin/expr/t_expr.sh
new file mode 100755
index 000000000000..4f9d5963187e
--- /dev/null
+++ b/bin/expr/t_expr.sh
@@ -0,0 +1,228 @@
+# $NetBSD: t_expr.sh,v 1.3 2012/03/27 07:23:06 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# The first arg will get eval'd so escape any meta characters
+# The 2nd arg is an expected string/response from expr for that op.
+test_expr() {
+ echo "Expression '${1}', expecting '${2}'"
+ res=`eval expr $1 2>&1`
+ if [ "$res" != "$2" ]; then
+ atf_fail "Expected $2, got $res from expression: " \
+ "`eval echo $1`"
+ fi
+}
+
+atf_test_case lang
+lang_ops_head() {
+ atf_set "descr" "Test that expr(1) works with non-C LANG (PR bin/2486)"
+}
+lang_body() {
+
+ export LANG=nonexistent
+ atf_check -s exit:0 -o inline:"21\n" -e empty -x "expr 10 + 11"
+
+ export LANG=ru_RU.KOI8-R
+ atf_check -s exit:0 -o inline:"21\n" -e empty -x "expr 10 + 11"
+}
+
+atf_test_case overflow
+overflow_head() {
+ atf_set "descr" "Test overflow cases"
+}
+overflow_body() {
+ test_expr '4611686018427387904 + 4611686018427387903' \
+ '9223372036854775807'
+ test_expr '4611686018427387904 + 4611686018427387904' \
+ "expr: integer overflow or underflow occurred for operation '4611686018427387904 + 4611686018427387904'"
+ test_expr '4611686018427387904 - -4611686018427387904' \
+ "expr: integer overflow or underflow occurred for operation '4611686018427387904 - -4611686018427387904'"
+ test_expr '-4611686018427387904 - 4611686018427387903' \
+ '-9223372036854775807'
+ test_expr '-4611686018427387904 - 4611686018427387905' \
+ "expr: integer overflow or underflow occurred for operation '-4611686018427387904 - 4611686018427387905'"
+ test_expr '-4611686018427387904 \* 1' '-4611686018427387904'
+ test_expr '-4611686018427387904 \* -1' '4611686018427387904'
+ test_expr '-4611686018427387904 \* 2' '-9223372036854775808'
+ test_expr '-4611686018427387904 \* 3' \
+ "expr: integer overflow or underflow occurred for operation '-4611686018427387904 * 3'"
+ test_expr '-4611686018427387904 \* -2' \
+ "expr: integer overflow or underflow occurred for operation '-4611686018427387904 * -2'"
+ test_expr '4611686018427387904 \* 1' '4611686018427387904'
+ test_expr '4611686018427387904 \* 2' \
+ "expr: integer overflow or underflow occurred for operation '4611686018427387904 * 2'"
+ test_expr '4611686018427387904 \* 3' \
+ "expr: integer overflow or underflow occurred for operation '4611686018427387904 * 3'"
+}
+
+atf_test_case gtkmm
+gtkmm_head() {
+ atf_set "descr" "Test from gtk-- configure that cause problems on old expr"
+}
+gtkmm_body() {
+ test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 5' '1'
+ test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 6' '0'
+ test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 3 \& 5 \>= 5' '0'
+ test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 2 \& 4 = 4 \& 5 \>= 5' '0'
+ test_expr '3 \> 2 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 6' '1'
+ test_expr '3 \> 3 \| 3 = 3 \& 4 \> 3 \| 3 = 3 \& 4 = 4 \& 5 \>= 5' '1'
+}
+
+atf_test_case colon_vs_math
+colon_vs_math_head() {
+ atf_set "descr" "Basic precendence test with the : operator vs. math"
+}
+colon_vs_math_body() {
+ test_expr '2 : 4 / 2' '0'
+ test_expr '4 : 4 % 3' '1'
+}
+
+atf_test_case arithmetic_ops
+arithmetic_ops_head() {
+ atf_set "descr" "Dangling arithemtic operator"
+}
+arithmetic_ops_body() {
+ test_expr '.java_wrapper : /' '0'
+ test_expr '4 : \*' '0'
+ test_expr '4 : +' '0'
+ test_expr '4 : -' '0'
+ test_expr '4 : /' '0'
+ test_expr '4 : %' '0'
+}
+
+atf_test_case basic_math
+basic_math_head() {
+ atf_set "descr" "Basic math test"
+}
+basic_math_body() {
+ test_expr '2 + 4 \* 5' '22'
+}
+
+atf_test_case basic_functional
+basic_functional_head() {
+ atf_set "descr" "Basic functional tests"
+}
+basic_functional_body() {
+ test_expr '2' '2'
+ test_expr '-4' '-4'
+ test_expr 'hello' 'hello'
+}
+
+atf_test_case compare_ops_precedence
+compare_ops_precedence_head() {
+ atf_set "descr" "Compare operator precendence test"
+}
+compare_ops_precedence_body() {
+ test_expr '2 \> 1 \* 17' '0'
+}
+
+atf_test_case compare_ops
+compare_ops_head() {
+ atf_set "descr" "Compare operator tests"
+}
+compare_ops_body() {
+ test_expr '2 \!= 5' '1'
+ test_expr '2 \!= 2' '0'
+ test_expr '2 \<= 3' '1'
+ test_expr '2 \<= 2' '1'
+ test_expr '2 \<= 1' '0'
+ test_expr '2 \< 3' '1'
+ test_expr '2 \< 2' '0'
+ test_expr '2 = 2' '1'
+ test_expr '2 = 4' '0'
+ test_expr '2 \>= 1' '1'
+ test_expr '2 \>= 2' '1'
+ test_expr '2 \>= 3' '0'
+ test_expr '2 \> 1' '1'
+ test_expr '2 \> 2' '0'
+}
+
+atf_test_case multiply
+multiply_head() {
+ atf_set "descr" "Test the multiply operator (PR bin/12838)"
+}
+multiply_body() {
+ test_expr '1 \* -1' '-1'
+ test_expr '2 \> 1 \* 17' '0'
+}
+
+atf_test_case negative
+negative_head() {
+ atf_set "descr" "Test the additive inverse"
+}
+negative_body() {
+ test_expr '-1 + 5' '4'
+ test_expr '- 1 + 5' 'expr: syntax error'
+
+ test_expr '5 + -1' '4'
+ test_expr '5 + - 1' 'expr: syntax error'
+
+ test_expr '1 - -5' '6'
+}
+
+atf_test_case math_precedence
+math_precedence_head() {
+ atf_set "descr" "More complex math test for precedence"
+}
+math_precedence_body() {
+ test_expr '-3 + -1 \* 4 + 3 / -6' '-7'
+}
+
+atf_test_case precedence
+precedence_head() {
+ atf_set "descr" "Test precedence"
+}
+precedence_body() {
+ # This is messy but the shell escapes cause that
+ test_expr 'X1/2/3 : X\\\(.\*[^/]\\\)//\*[^/][^/]\*/\*$ \| . : \\\(.\\\)' '1/2'
+}
+
+atf_test_case regex
+regex_head() {
+ atf_set "descr" "Test proper () returning \1 from a regex"
+}
+regex_body() {
+ # This is messy but the shell escapes cause that
+ test_expr '1/2 : .\*/\\\(.\*\\\)' '2'
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case lang
+ atf_add_test_case overflow
+ atf_add_test_case gtkmm
+ atf_add_test_case colon_vs_math
+ atf_add_test_case arithmetic_ops
+ atf_add_test_case basic_math
+ atf_add_test_case basic_functional
+ atf_add_test_case compare_ops_precedence
+ atf_add_test_case compare_ops
+ atf_add_test_case multiply
+ atf_add_test_case negative
+ atf_add_test_case math_precedence
+ atf_add_test_case precedence
+ atf_add_test_case regex
+}
diff --git a/bin/pax/Makefile b/bin/pax/Makefile
new file mode 100644
index 000000000000..9e4ddae746e9
--- /dev/null
+++ b/bin/pax/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/pax
+TESTS_SH= t_pax
+
+.include <bsd.test.mk>
diff --git a/bin/pax/t_pax.sh b/bin/pax/t_pax.sh
new file mode 100755
index 000000000000..63ae7f8965ce
--- /dev/null
+++ b/bin/pax/t_pax.sh
@@ -0,0 +1,54 @@
+# $NetBSD: t_pax.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case append
+append_head() {
+ atf_set "descr" "Ensure that appending a file to an archive" \
+ "produces the same results as if the file" \
+ "had been there during the archive's creation"
+}
+append_body() {
+ touch foo bar
+
+ # store both foo and bar into file1.tar
+ atf_check -s eq:0 -o empty -e empty \
+ pax -w -b 512 -x ustar -f file1.tar foo bar
+
+ # store foo into file2.tar, then append bar to file2.tar
+ atf_check -s eq:0 -o empty -e empty \
+ pax -w -b 512 -x ustar -f file2.tar foo
+ atf_check -s eq:0 -o empty -e empty \
+ pax -w -b 512 -x ustar -f file2.tar -a bar
+
+ # ensure that file1.tar and file2.tar are equal
+ atf_check -s eq:0 -o empty -e empty cmp file1.tar file2.tar
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case append
+}
diff --git a/bin/ps/Makefile b/bin/ps/Makefile
new file mode 100644
index 000000000000..74d2cae00327
--- /dev/null
+++ b/bin/ps/Makefile
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/ps
+
+TESTS_SH= t_ps
+
+FILESDIR= ${TESTSDIR}
+FILES= keywords
+
+.include <bsd.test.mk>
diff --git a/bin/ps/keywords b/bin/ps/keywords
new file mode 100644
index 000000000000..3f05f5464b84
--- /dev/null
+++ b/bin/ps/keywords
@@ -0,0 +1,123 @@
+# $NetBSD: keywords,v 1.2 2014/01/16 04:16:32 mlelstv Exp $
+#
+# Table of keywords for use with ps "-o" option.
+#
+# The first column (keyword) is the name of a keyword.
+#
+# The second column (header) is the default column header associated
+# with the keyword, except if the keyword is an alias, in which case the
+# second column is the name of another keyword.
+#
+# The third column (flag) may be blank, "LJUST", or "ALIAS". "ALIAS"
+# means that the keyword is an alias. "LJUST" means that the keyword
+# should be displayed in a left-justified column. The default is that
+# the keyword should be displayed in a right-justified column.
+#
+# keyword header flag
+#
+ktracep KTRACEP
+nwchan WCHAN
+p_ru P_RU
+paddr PADDR
+rlink RLINK
+%cpu %CPU
+%mem %MEM
+acflag ACFLG
+acflg acflag ALIAS
+args command ALIAS
+blocked sigmask ALIAS
+caught sigcatch ALIAS
+comm COMMAND LJUST
+command COMMAND LJUST
+cpu CPU
+cputime time ALIAS
+ctime CTIME
+egid EGID
+egroup EGROUP LJUST
+etime ELAPSED
+euid EUID
+euser EUSER LJUST
+f F
+flags f ALIAS
+gid GID
+group GROUP LJUST
+groupnames GROUPNAMES LJUST
+groups GROUPS LJUST
+holdcnt HOLDCNT
+ignored sigignore ALIAS
+inblk INBLK
+inblock inblk ALIAS
+jobc JOBC
+ktrace KTRACE
+laddr LADDR
+lid LID
+lim LIM
+login LOGIN LJUST
+logname login ALIAS
+lstart STARTED LJUST
+lstate STAT LJUST
+ltime LTIME
+majflt MAJFLT
+minflt MINFLT
+msgrcv MSGRCV
+msgsnd MSGSND
+ni nice ALIAS
+nice NI
+nivcsw NIVCSW
+nlwp NLWP
+nsignals nsigs ALIAS
+nsigs NSIGS
+nswap NSWAP
+nvcsw NVCSW
+oublk OUBLK
+oublock oublk ALIAS
+pagein PAGEIN
+pcpu %cpu ALIAS
+pending sig ALIAS
+pgid PGID
+pid PID
+pmem %mem ALIAS
+ppid PPID
+pri PRI
+re RE
+rgid RGID
+rgroup RGROUP LJUST
+rlwp RLWP
+rss RSS
+rssize rsz ALIAS
+rsz RSZ
+ruid RUID
+ruser RUSER LJUST
+sess SESS
+sid SID
+sig PENDING
+sigcatch CAUGHT
+sigignore IGNORED
+sigmask BLOCKED
+sl SL
+start STARTED
+stat state ALIAS
+state STAT LJUST
+stime STIME
+svgid SVGID
+svgroup SVGROUP LJUST
+svuid SVUID
+svuser SVUSER LJUST
+tdev TDEV
+time TIME
+tpgid TPGID
+tsess TSESS
+tsiz TSIZ
+tt TTY LJUST
+tty TTY LJUST
+uaddr UADDR
+ucomm UCOMM LJUST
+uid UID
+upr UPR
+user USER LJUST
+usrpri upr ALIAS
+utime UTIME
+vsize vsz ALIAS
+vsz VSZ
+wchan WCHAN LJUST
+xstat XSTAT
diff --git a/bin/ps/t_ps.sh b/bin/ps/t_ps.sh
new file mode 100755
index 000000000000..8f8829bc3543
--- /dev/null
+++ b/bin/ps/t_ps.sh
@@ -0,0 +1,404 @@
+# $NetBSD: t_ps.sh,v 1.2 2014/01/16 04:16:32 mlelstv Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# the implementation of "ps" to test
+: ${TEST_PS:="ps"}
+# tab and newline characters
+tab="$(printf '\t')"
+# nl="$(printf '\n')" doesn't work
+nl='
+'
+
+#
+# Parse the "keywords" file into a load of shell variables
+#
+setup_keywords()
+{
+ # Set variables representing the header text
+ # for all normal keywords (except aliases), and
+ # for regular expressions to match the text in left- or
+ # right-justified columns.
+ # For example, head_text_p_cpu="%CPU" head_regexp_p_cpu=" *%CPU".
+ while read keyword heading flag
+ do
+ case "$keyword" in
+ ''|\#*) continue
+ ;;
+ esac
+ [ x"$flag" = x"ALIAS" ] && continue
+ kvar="${keyword}"
+ case "${keyword}" in
+ %*) kvar="p_${keyword#%}"
+ ;;
+ esac
+ eval head_text_${kvar}=\'"${heading}"\'
+ case "${flag}" in
+ '') # right justified
+ eval head_regexp_${kvar}=\'" *${heading}"\'
+ ;;
+ LJUST) # left justified
+ eval head_regexp_${kvar}=\'"${heading} *"\'
+ ;;
+ *) atf_fail "unknown flag in keywords"
+ ;;
+ esac
+ done <"$(atf_get_srcdir)/keywords"
+
+ # Now do the aliases.
+ while read keyword heading flag
+ do
+ case "$keyword" in
+ ''|\#*) continue
+ ;;
+ esac
+ [ x"$flag" != x"ALIAS" ] && continue
+ kvar="${keyword}"
+ avar="${heading}"
+ case "${keyword}" in
+ %*) kvar="p_${keyword#%}"
+ ;;
+ esac
+ case "${heading}" in
+ %*) avar="p_${heading#%}"
+ ;;
+ esac
+ eval head_text_${kvar}=\"\$head_text_${avar}\"
+ eval head_regexp_${kvar}=\"\$head_regexp_${avar}\"
+ done <"$(atf_get_srcdir)/keywords"
+
+ # default sets of keywords
+ default_keywords='pid tty stat time command'
+ j_keywords='user pid ppid pgid sess jobc state tt time command'
+ l_keywords='uid pid ppid cpu pri nice vsz rss wchan state tt time command'
+ s_keywords='uid pid ppid cpu lid nlwp pri nice vsz rss wchan lstate tt ltime command'
+ u_keywords='user pid %cpu %mem vsz rss tt state start time command'
+ v_keywords='pid state time sl re pagein vsz rss lim tsiz %cpu %mem command'
+}
+
+# Convert a list of keywords like "pid comm" to a regexp
+# like " *PID COMMAND *"
+heading_keywords_to_regexp()
+{
+ local keywords="$1"
+ local regexp
+ regexp="$(echo "$keywords" | \
+ sed -E -e 's/\%/p_/g' -e 's/(^| )/\1\$head_regexp_/g')"
+ eval regexp=\""${regexp}"\"
+ regexp="^${regexp}\$"
+ echo "$regexp"
+}
+
+#
+# Check that a string matches a regexp; use the specified id
+# in error or success messages.
+#
+check_regexp() {
+ local id="$1" string="$2" regexp="$3"
+ if ! expr "$string" : "$regexp" >/dev/null
+ then
+ atf_fail "${id}: expected [${regexp}], got [${string}]"
+ false
+ fi
+}
+
+#
+# Run "ps $args -p $$"; check that only one line is printed,
+# without a preceding header line.
+#
+check_no_heading_line()
+{
+ local args="$1"
+ local output="$(eval "${TEST_PS} $args -p $$")"
+ case "$output" in
+ *"$nl"*)
+ local firstline="${output%%${nl}*}"
+ atf_fail "check_no_heading_line [$args] got [$firstline]"
+ ;;
+ *)
+ ;;
+ esac
+}
+
+#
+# Run "ps $args"; check that the heading matches the expected regexp.
+#
+check_heading_regexp()
+{
+ args="$1"
+ regexp="$2"
+ actual="$( eval "${TEST_PS} $args" | sed -e 1q )"
+ check_regexp "heading [$args]" "${actual}" "${regexp}"
+}
+
+#
+# Run "ps $args"; check that the heading matches a regexp constructed
+# from the specified keywords.
+#
+check_heading_keywords()
+{
+ args="$1"
+ keywords="$2"
+ check_heading_regexp "$args" "$(heading_keywords_to_regexp "$keywords")"
+}
+
+#
+# Try several variations on "ps $flag", "ps -$flag", etc.,
+# and check that the heading always has the correct keywords.
+#
+check_heading_variations()
+{
+ flag="$1"
+ keywords="$2"
+ for args in "$flag" "-$flag" "-$flag$flag -$flag"; do
+ check_heading_keywords "$args" "$keywords"
+ done
+}
+
+atf_test_case default_columns
+default_columns_head()
+{
+ atf_set "descr" "Checks that the default set of columns is correct" \
+ "and also check that the columns printed by the -j," \
+ "-l, -s, -u and -v flags alone are correct"
+}
+default_columns_body()
+{
+ setup_keywords
+ check_heading_keywords '' "$default_keywords"
+ check_heading_variations 'j' "$j_keywords"
+ check_heading_variations 'l' "$l_keywords"
+ check_heading_variations 's' "$s_keywords"
+ check_heading_variations 'u' "$u_keywords"
+ check_heading_variations 'v' "$v_keywords"
+}
+
+atf_test_case minus_O
+minus_O_head()
+{
+ atf_set "descr" "Checks that 'ps -O foo' inserts columns just after" \
+ "the pid column"
+}
+minus_O_body()
+{
+ setup_keywords
+ check_heading_keywords '-O %cpu,%mem' \
+ "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
+ check_heading_keywords '-O %cpu -O %mem' \
+ "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
+ check_heading_keywords '-O%cpu -O%mem' \
+ "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')"
+}
+
+atf_test_case minus_o
+minus_o_head()
+{
+ atf_set "descr" "Checks simple cases of 'ps -o foo' to control which" \
+ "columns are printed; this does not test header" \
+ "overriding via 'ps -o foo=BAR'"
+}
+minus_o_body()
+{
+ setup_keywords
+ # Keywords for "-o name" override the default display
+ check_heading_keywords '-o pid,%cpu,%mem' \
+ "pid %cpu %mem"
+ check_heading_keywords '-o pid -o %cpu,%mem' \
+ "pid %cpu %mem"
+ check_heading_keywords '-opid -o %cpu,%mem' \
+ "pid %cpu %mem"
+ # Space works like comma
+ check_heading_keywords '-opid -o "%cpu %mem"' \
+ "pid %cpu %mem"
+ # Check missing pid
+ check_heading_keywords '-o comm' \
+ "comm"
+ # Check pid present but not first
+ check_heading_keywords '-o comm,pid' \
+ "comm pid"
+}
+
+atf_test_case override_heading_simple
+override_heading_simple_head()
+{
+ atf_set "descr" "Tests simple uses of header overriding via" \
+ "'ps -o foo=BAR'. This does not test columns " \
+ "with null headings, or headings with embedded" \
+ "space, ',' or '='."
+}
+override_heading_simple_body()
+{
+ setup_keywords
+ check_heading_regexp '-o pid=PPP -o comm' \
+ '^ *PPP '"${head_text_comm}"'$' # no trailing space
+ check_heading_regexp '-o pid=PPP -o comm=CCC' \
+ '^ *PPP CCC$'
+ check_heading_regexp '-o pid,comm=CCC' \
+ '^'"${head_regexp_pid}"' CCC$'
+ check_heading_regexp '-o pid -o comm=CCC' \
+ '^'"${head_regexp_pid}"' CCC$'
+ # Check missing pid
+ check_heading_regexp '-o comm=CCC' \
+ '^CCC$'
+ # Check pid present but not first
+ check_heading_regexp '-o comm=CCC -o pid=PPP' \
+ '^CCC *PPP$'
+ check_heading_regexp '-o comm,pid=PPP' \
+ '^'"${head_regexp_comm}"' *PPP$'
+}
+
+atf_test_case override_heading_embedded_specials
+override_heading_embedded_specials_head()
+{
+ atf_set "descr" "Tests header overriding with embedded space," \
+ "',' or '='. Everything after the first '='" \
+ "is part of the heading."
+}
+override_heading_embedded_specials_body()
+{
+ setup_keywords
+ # Check embedded "," or "=" in override header.
+ check_heading_regexp '-o comm,pid==' \
+ '^'"${head_regexp_comm}"' *=$'
+ check_heading_regexp '-o comm,pid=,' \
+ '^'"${head_regexp_comm}"' *,$'
+ check_heading_regexp '-o pid=PPP,comm' \
+ '^ *PPP,comm$' # not like '-o pid=PPP -o comm'
+ check_heading_regexp '-o pid=PPP,comm=CCC' \
+ '^ *PPP,comm=CCC$' # not like '-o pid=PPP -o comm=CCC'
+ check_heading_regexp '-o comm,pid=PPP,QQQ' \
+ '^'"${head_regexp_comm}"' *PPP,QQQ$'
+ check_heading_regexp '-o comm,pid=ppid,tty=state' \
+ '^'"${head_regexp_comm}"' *ppid,tty=state$'
+ # Check embedded space or tab in override header.
+ check_heading_regexp '-o comm,pid="PPP QQQ"' \
+ '^'"${head_regexp_comm}"' *PPP QQQ$'
+ check_heading_regexp '-o comm,pid="PPP${tab}QQQ"' \
+ '^'"${head_regexp_comm}"' *PPP'"${tab}"'QQQ$'
+}
+
+atf_test_case override_heading_some_null
+override_heading_some_null_head()
+{
+ atf_set "descr" "Tests simple uses of null column headings" \
+ "overriding via 'ps -o foo=BAR -o baz='. This" \
+ "does not test the case where all columns have" \
+ "null headings."
+}
+override_heading_some_null_body()
+{
+ setup_keywords
+ check_heading_regexp '-o pid=PPP -o comm=' \
+ '^ *PPP *$'
+ check_heading_regexp '-o pid= -o comm=CCC' \
+ '^ * CCC$'
+ check_heading_regexp '-o pid -o comm=' \
+ '^'"${head_regexp_pid}"' *$'
+ # Check missing pid
+ check_heading_regexp '-o ppid= -o comm=CCC' \
+ '^ * CCC$'
+ check_heading_regexp '-o ppid=PPP -o comm=' \
+ '^ *PPP *$'
+ # Check pid present but not first
+ check_heading_regexp '-o comm= -o pid=PPP' \
+ '^ * PPP$'
+ check_heading_regexp '-o comm,pid=' \
+ '^'"${head_regexp_comm}"' *$'
+ # A field with a null custom heading retains a minimum width
+ # derived from the default heading. This does not apply
+ # to a field with a very short (non-null) custom heading.
+ #
+ # We choose "holdcnt" as a column whose width is likely to be
+ # determined entirely by the header width, because the values
+ # are likely to be very small.
+ check_heading_regexp '-o holdcnt -o holdcnt -o holdcnt' \
+ '^HOLDCNT HOLDCNT HOLDCNT$'
+ check_heading_regexp '-o holdcnt -o holdcnt= -o holdcnt' \
+ '^HOLDCNT HOLDCNT$'
+ check_heading_regexp '-o holdcnt -o holdcnt=HH -o holdcnt' \
+ '^HOLDCNT HH HOLDCNT$'
+}
+
+atf_test_case override_heading_all_null
+override_heading_all_null_head()
+{
+ atf_set "descr" "Tests the use of 'ps -o foo= -o bar=' (with a" \
+ "null heading for every column). The heading" \
+ "should not be printed at all in this case."
+}
+override_heading_all_null_body()
+{
+ setup_keywords
+ # A heading with a space is not a null heading,
+ # so should not be suppressed
+ check_heading_regexp '-o comm=" "' \
+ '^ *$'
+ # Null headings should be suppressed
+ check_no_heading_line '-o pid= -o comm='
+ check_no_heading_line '-o pid= -o comm='
+ # Check missing pid
+ check_no_heading_line '-o ppid='
+ check_no_heading_line '-o comm='
+ check_no_heading_line '-o command='
+ check_no_heading_line '-o ppid= -o comm='
+ check_no_heading_line '-o comm= -o ppid='
+ # Check pid present but not first
+ check_no_heading_line '-o comm= -o pid='
+ check_no_heading_line '-o ppid= -o pid= -o command='
+}
+
+atf_test_case duplicate_column
+duplicate_column_head()
+{
+ atf_set "descr" "Tests the use of -o options to display the" \
+ "same column more than once"
+}
+duplicate_column_body()
+{
+ setup_keywords
+ # two custom headers
+ check_heading_regexp '-o pid=PPP -o pid=QQQ' \
+ '^ *PPP *QQQ$'
+ # one custom header, before and after default header
+ check_heading_regexp '-o pid=PPP -o pid' \
+ '^ *PPP '"${head_regexp_pid}"'$'
+ check_heading_regexp '-o pid -o pid=QQQ' \
+ '^'"${head_regexp_pid}"' *QQQ$'
+ # custom headers both before and after default header
+ check_heading_regexp '-o pid=PPP -o pid -o pid=QQQ' \
+ '^ *PPP '"${head_regexp_pid}"' *QQQ$'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case default_columns
+ atf_add_test_case minus_O
+ atf_add_test_case minus_o
+ atf_add_test_case override_heading_simple
+ atf_add_test_case override_heading_embedded_specials
+ atf_add_test_case override_heading_some_null
+ atf_add_test_case override_heading_all_null
+ atf_add_test_case duplicate_column
+}
diff --git a/bin/sh/Makefile b/bin/sh/Makefile
new file mode 100644
index 000000000000..8e36e6df6c88
--- /dev/null
+++ b/bin/sh/Makefile
@@ -0,0 +1,21 @@
+# $NetBSD: Makefile,v 1.4 2014/09/11 18:25:30 dholland Exp $
+#
+
+.include <bsd.own.mk>
+
+TESTSDIR = ${TESTSBASE}/bin/sh
+
+TESTS_SUBDIRS += dotcmd
+
+TESTS_SH= t_compexit
+TESTS_SH+= t_exit
+TESTS_SH+= t_expand
+TESTS_SH+= t_evaltested
+TESTS_SH+= t_fsplit
+TESTS_SH+= t_here
+TESTS_SH+= t_set_e
+TESTS_SH+= t_ulimit
+TESTS_SH+= t_varquote
+TESTS_SH+= t_wait
+
+.include <bsd.test.mk>
diff --git a/bin/sh/dotcmd/Makefile b/bin/sh/dotcmd/Makefile
new file mode 100644
index 000000000000..fa9376237e2f
--- /dev/null
+++ b/bin/sh/dotcmd/Makefile
@@ -0,0 +1,40 @@
+# $NetBSD: Makefile,v 1.2 2014/07/27 14:24:17 apb Exp $
+#
+
+.include <bsd.own.mk>
+
+TESTSDIR = ${TESTSBASE}/bin/sh/dotcmd
+
+TESTS_SH = t_dotcmd
+
+FILESDIR = ${TESTSDIR}/out
+
+# Testing scripts: dotcmd in various scopes includes a file with
+# return / break / continue in various scopes.
+#
+.for cmd_scope in case compound file for func subshell until while
+. for cmd in return break continue
+FILES += ${cmd}_${cmd_scope}
+FILESDIR_${cmd}_${cmd_scope} = ${TESTSDIR}
+FILESBUILD_${cmd}_${cmd_scope} = yes
+
+${cmd}_${cmd_scope}: scoped_command
+ ${HOST_SH} ${.CURDIR}/scoped_command '${cmd_scope}' '${cmd}' '${cmd}' \
+ >'${.TARGET}'
+
+. for dot_scope in case compound file for func subshell until while
+FILES += \
+ ${dot_scope}_${cmd}_${cmd_scope} \
+ out/${dot_scope}_${cmd}_${cmd_scope}.out
+FILESDIR_${dot_scope}_${cmd}_${cmd_scope} = ${TESTSDIR}
+FILESBUILD_${dot_scope}_${cmd}_${cmd_scope} = yes
+FILESMODE_${dot_scope}_${cmd}_${cmd_scope} = ${BINMODE}
+
+${dot_scope}_${cmd}_${cmd_scope}: scoped_command
+ ${HOST_SH} ${.CURDIR}/scoped_command '${dot_scope}' \
+ '. "${cmd}_${cmd_scope}"' 'dotcmd' 'dotcmd' >'${.TARGET}'
+. endfor
+. endfor
+.endfor
+
+.include <bsd.test.mk>
diff --git a/bin/sh/dotcmd/out/case_break_case.out b/bin/sh/dotcmd/out/case_break_case.out
new file mode 100644
index 000000000000..4c4205563e80
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_case.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before case
+before break
+after break, return value: 0
+after case
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_compound.out b/bin/sh/dotcmd/out/case_break_compound.out
new file mode 100644
index 000000000000..01113ca97a69
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_compound.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+compound start
+before break
+after break, return value: 0
+compound end
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_file.out b/bin/sh/dotcmd/out/case_break_file.out
new file mode 100644
index 000000000000..52640203d8da
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_file.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before break
+after break, return value: 0
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_for.out b/bin/sh/dotcmd/out/case_break_for.out
new file mode 100644
index 000000000000..e116ee2b6a66
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_for.out
@@ -0,0 +1,7 @@
+before case
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_func.out b/bin/sh/dotcmd/out/case_break_func.out
new file mode 100644
index 000000000000..906a804d2185
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_func.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before function
+before break
+after break
+after function
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_subshell.out b/bin/sh/dotcmd/out/case_break_subshell.out
new file mode 100644
index 000000000000..073caff318ba
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_subshell.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+subshell start
+before break
+after break, return value: 0
+subshell end
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_until.out b/bin/sh/dotcmd/out/case_break_until.out
new file mode 100644
index 000000000000..f47bd43cccba
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_until.out
@@ -0,0 +1,7 @@
+before case
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_break_while.out b/bin/sh/dotcmd/out/case_break_while.out
new file mode 100644
index 000000000000..e9a73f8112b1
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_break_while.out
@@ -0,0 +1,7 @@
+before case
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_case.out b/bin/sh/dotcmd/out/case_continue_case.out
new file mode 100644
index 000000000000..7919427ae304
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_case.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before case
+before continue
+after continue, return value: 0
+after case
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_compound.out b/bin/sh/dotcmd/out/case_continue_compound.out
new file mode 100644
index 000000000000..9195e0889eb9
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_compound.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+compound start
+before continue
+after continue, return value: 0
+compound end
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_file.out b/bin/sh/dotcmd/out/case_continue_file.out
new file mode 100644
index 000000000000..100a5906f0a4
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_file.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before continue
+after continue, return value: 0
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_for.out b/bin/sh/dotcmd/out/case_continue_for.out
new file mode 100644
index 000000000000..9a078d0abc1e
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_for.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_func.out b/bin/sh/dotcmd/out/case_continue_func.out
new file mode 100644
index 000000000000..6282c89d7437
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_func.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before function
+before continue
+after continue
+after function
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_subshell.out b/bin/sh/dotcmd/out/case_continue_subshell.out
new file mode 100644
index 000000000000..b066ab64b7d7
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_subshell.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+subshell start
+before continue
+after continue, return value: 0
+subshell end
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_until.out b/bin/sh/dotcmd/out/case_continue_until.out
new file mode 100644
index 000000000000..afc85b6561a1
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_until.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_continue_while.out b/bin/sh/dotcmd/out/case_continue_while.out
new file mode 100644
index 000000000000..cb4137d23391
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_continue_while.out
@@ -0,0 +1,8 @@
+before case
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_case.out b/bin/sh/dotcmd/out/case_return_case.out
new file mode 100644
index 000000000000..734369d564e3
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_case.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_compound.out b/bin/sh/dotcmd/out/case_return_compound.out
new file mode 100644
index 000000000000..2fae84e35df0
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_compound.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_file.out b/bin/sh/dotcmd/out/case_return_file.out
new file mode 100644
index 000000000000..f97ecc6dab50
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_file.out
@@ -0,0 +1,5 @@
+before case
+before dotcmd
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_for.out b/bin/sh/dotcmd/out/case_return_for.out
new file mode 100644
index 000000000000..d863537007be
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_for.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_func.out b/bin/sh/dotcmd/out/case_return_func.out
new file mode 100644
index 000000000000..aed8fa4db71a
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_func.out
@@ -0,0 +1,7 @@
+before case
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_subshell.out b/bin/sh/dotcmd/out/case_return_subshell.out
new file mode 100644
index 000000000000..364d2458e604
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_subshell.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_until.out b/bin/sh/dotcmd/out/case_return_until.out
new file mode 100644
index 000000000000..daf3811e2e9a
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_until.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/case_return_while.out b/bin/sh/dotcmd/out/case_return_while.out
new file mode 100644
index 000000000000..ef6a6764d515
--- /dev/null
+++ b/bin/sh/dotcmd/out/case_return_while.out
@@ -0,0 +1,6 @@
+before case
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+after case
diff --git a/bin/sh/dotcmd/out/compound_break_case.out b/bin/sh/dotcmd/out/compound_break_case.out
new file mode 100644
index 000000000000..144bcd6d00f4
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_case.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before case
+before break
+after break, return value: 0
+after case
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_compound.out b/bin/sh/dotcmd/out/compound_break_compound.out
new file mode 100644
index 000000000000..3fd7b2f92e2a
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_compound.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+compound start
+before break
+after break, return value: 0
+compound end
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_file.out b/bin/sh/dotcmd/out/compound_break_file.out
new file mode 100644
index 000000000000..5ad5ed396a74
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_file.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before break
+after break, return value: 0
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_for.out b/bin/sh/dotcmd/out/compound_break_for.out
new file mode 100644
index 000000000000..7f03e495bcde
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_for.out
@@ -0,0 +1,7 @@
+compound start
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_func.out b/bin/sh/dotcmd/out/compound_break_func.out
new file mode 100644
index 000000000000..82e86b3c778e
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_func.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before function
+before break
+after break
+after function
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_subshell.out b/bin/sh/dotcmd/out/compound_break_subshell.out
new file mode 100644
index 000000000000..e26e980f7ebf
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_subshell.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+subshell start
+before break
+after break, return value: 0
+subshell end
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_until.out b/bin/sh/dotcmd/out/compound_break_until.out
new file mode 100644
index 000000000000..34dd25adeaa0
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_until.out
@@ -0,0 +1,7 @@
+compound start
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_break_while.out b/bin/sh/dotcmd/out/compound_break_while.out
new file mode 100644
index 000000000000..7019045bc39f
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_break_while.out
@@ -0,0 +1,7 @@
+compound start
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_case.out b/bin/sh/dotcmd/out/compound_continue_case.out
new file mode 100644
index 000000000000..206548ccff38
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_case.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before case
+before continue
+after continue, return value: 0
+after case
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_compound.out b/bin/sh/dotcmd/out/compound_continue_compound.out
new file mode 100644
index 000000000000..a8c7efc159ec
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_compound.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+compound start
+before continue
+after continue, return value: 0
+compound end
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_file.out b/bin/sh/dotcmd/out/compound_continue_file.out
new file mode 100644
index 000000000000..c619ad560f9d
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_file.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before continue
+after continue, return value: 0
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_for.out b/bin/sh/dotcmd/out/compound_continue_for.out
new file mode 100644
index 000000000000..35b092a42fb3
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_for.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_func.out b/bin/sh/dotcmd/out/compound_continue_func.out
new file mode 100644
index 000000000000..198dbd6af513
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_func.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before function
+before continue
+after continue
+after function
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_subshell.out b/bin/sh/dotcmd/out/compound_continue_subshell.out
new file mode 100644
index 000000000000..1ecaa96e422f
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_subshell.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+subshell start
+before continue
+after continue, return value: 0
+subshell end
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_until.out b/bin/sh/dotcmd/out/compound_continue_until.out
new file mode 100644
index 000000000000..4a74a8e8e431
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_until.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_continue_while.out b/bin/sh/dotcmd/out/compound_continue_while.out
new file mode 100644
index 000000000000..b2d939ed538c
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_continue_while.out
@@ -0,0 +1,8 @@
+compound start
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_case.out b/bin/sh/dotcmd/out/compound_return_case.out
new file mode 100644
index 000000000000..995d5b556f42
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_case.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_compound.out b/bin/sh/dotcmd/out/compound_return_compound.out
new file mode 100644
index 000000000000..f6e4858e6f5d
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_compound.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_file.out b/bin/sh/dotcmd/out/compound_return_file.out
new file mode 100644
index 000000000000..84347b28f74d
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_file.out
@@ -0,0 +1,5 @@
+compound start
+before dotcmd
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_for.out b/bin/sh/dotcmd/out/compound_return_for.out
new file mode 100644
index 000000000000..ec234472aa6d
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_for.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_func.out b/bin/sh/dotcmd/out/compound_return_func.out
new file mode 100644
index 000000000000..12798d0e0322
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_func.out
@@ -0,0 +1,7 @@
+compound start
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_subshell.out b/bin/sh/dotcmd/out/compound_return_subshell.out
new file mode 100644
index 000000000000..af0ab785fbb4
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_subshell.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_until.out b/bin/sh/dotcmd/out/compound_return_until.out
new file mode 100644
index 000000000000..a108f502d2c6
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_until.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/compound_return_while.out b/bin/sh/dotcmd/out/compound_return_while.out
new file mode 100644
index 000000000000..ef34c037a9f8
--- /dev/null
+++ b/bin/sh/dotcmd/out/compound_return_while.out
@@ -0,0 +1,6 @@
+compound start
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+compound end
diff --git a/bin/sh/dotcmd/out/file_break_case.out b/bin/sh/dotcmd/out/file_break_case.out
new file mode 100644
index 000000000000..2f34f10c726b
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_case.out
@@ -0,0 +1,6 @@
+before dotcmd
+before case
+before break
+after break, return value: 0
+after case
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_compound.out b/bin/sh/dotcmd/out/file_break_compound.out
new file mode 100644
index 000000000000..0c7300d6a3ee
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_compound.out
@@ -0,0 +1,6 @@
+before dotcmd
+compound start
+before break
+after break, return value: 0
+compound end
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_file.out b/bin/sh/dotcmd/out/file_break_file.out
new file mode 100644
index 000000000000..fb4db197ddac
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_file.out
@@ -0,0 +1,4 @@
+before dotcmd
+before break
+after break, return value: 0
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_for.out b/bin/sh/dotcmd/out/file_break_for.out
new file mode 100644
index 000000000000..66f445287d5b
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_for.out
@@ -0,0 +1,5 @@
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_func.out b/bin/sh/dotcmd/out/file_break_func.out
new file mode 100644
index 000000000000..c5488abadbc5
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_func.out
@@ -0,0 +1,6 @@
+before dotcmd
+before function
+before break
+after break
+after function
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_subshell.out b/bin/sh/dotcmd/out/file_break_subshell.out
new file mode 100644
index 000000000000..47e2394084af
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_subshell.out
@@ -0,0 +1,6 @@
+before dotcmd
+subshell start
+before break
+after break, return value: 0
+subshell end
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_until.out b/bin/sh/dotcmd/out/file_break_until.out
new file mode 100644
index 000000000000..b51ff195bd84
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_until.out
@@ -0,0 +1,5 @@
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_break_while.out b/bin/sh/dotcmd/out/file_break_while.out
new file mode 100644
index 000000000000..0fd3a83ce03d
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_break_while.out
@@ -0,0 +1,5 @@
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_case.out b/bin/sh/dotcmd/out/file_continue_case.out
new file mode 100644
index 000000000000..2cf3be6d3b4e
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_case.out
@@ -0,0 +1,6 @@
+before dotcmd
+before case
+before continue
+after continue, return value: 0
+after case
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_compound.out b/bin/sh/dotcmd/out/file_continue_compound.out
new file mode 100644
index 000000000000..7bec42019aee
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_compound.out
@@ -0,0 +1,6 @@
+before dotcmd
+compound start
+before continue
+after continue, return value: 0
+compound end
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_file.out b/bin/sh/dotcmd/out/file_continue_file.out
new file mode 100644
index 000000000000..2f8806c60b6d
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_file.out
@@ -0,0 +1,4 @@
+before dotcmd
+before continue
+after continue, return value: 0
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_for.out b/bin/sh/dotcmd/out/file_continue_for.out
new file mode 100644
index 000000000000..e8da2390bbbf
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_for.out
@@ -0,0 +1,6 @@
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_func.out b/bin/sh/dotcmd/out/file_continue_func.out
new file mode 100644
index 000000000000..da683c02a158
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_func.out
@@ -0,0 +1,6 @@
+before dotcmd
+before function
+before continue
+after continue
+after function
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_subshell.out b/bin/sh/dotcmd/out/file_continue_subshell.out
new file mode 100644
index 000000000000..388558b060e6
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_subshell.out
@@ -0,0 +1,6 @@
+before dotcmd
+subshell start
+before continue
+after continue, return value: 0
+subshell end
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_until.out b/bin/sh/dotcmd/out/file_continue_until.out
new file mode 100644
index 000000000000..bb0f28134eee
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_until.out
@@ -0,0 +1,6 @@
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_continue_while.out b/bin/sh/dotcmd/out/file_continue_while.out
new file mode 100644
index 000000000000..63338234aa4c
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_continue_while.out
@@ -0,0 +1,6 @@
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_case.out b/bin/sh/dotcmd/out/file_return_case.out
new file mode 100644
index 000000000000..486685242bda
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_case.out
@@ -0,0 +1,4 @@
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_compound.out b/bin/sh/dotcmd/out/file_return_compound.out
new file mode 100644
index 000000000000..6b831451d867
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_compound.out
@@ -0,0 +1,4 @@
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_file.out b/bin/sh/dotcmd/out/file_return_file.out
new file mode 100644
index 000000000000..2d6742310a0f
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_file.out
@@ -0,0 +1,3 @@
+before dotcmd
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_for.out b/bin/sh/dotcmd/out/file_return_for.out
new file mode 100644
index 000000000000..83f8e002950f
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_for.out
@@ -0,0 +1,4 @@
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_func.out b/bin/sh/dotcmd/out/file_return_func.out
new file mode 100644
index 000000000000..a0db2c99cfa8
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_func.out
@@ -0,0 +1,5 @@
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_subshell.out b/bin/sh/dotcmd/out/file_return_subshell.out
new file mode 100644
index 000000000000..83cd0e4ed0b0
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_subshell.out
@@ -0,0 +1,4 @@
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_until.out b/bin/sh/dotcmd/out/file_return_until.out
new file mode 100644
index 000000000000..fdf2449045a1
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_until.out
@@ -0,0 +1,4 @@
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/file_return_while.out b/bin/sh/dotcmd/out/file_return_while.out
new file mode 100644
index 000000000000..a733aa38912b
--- /dev/null
+++ b/bin/sh/dotcmd/out/file_return_while.out
@@ -0,0 +1,4 @@
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
diff --git a/bin/sh/dotcmd/out/for_break_case.out b/bin/sh/dotcmd/out/for_break_case.out
new file mode 100644
index 000000000000..262db24358d4
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_case.out
@@ -0,0 +1,5 @@
+before for
+before dotcmd
+before case
+before break
+after for
diff --git a/bin/sh/dotcmd/out/for_break_compound.out b/bin/sh/dotcmd/out/for_break_compound.out
new file mode 100644
index 000000000000..418a4de73c0c
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_compound.out
@@ -0,0 +1,5 @@
+before for
+before dotcmd
+compound start
+before break
+after for
diff --git a/bin/sh/dotcmd/out/for_break_file.out b/bin/sh/dotcmd/out/for_break_file.out
new file mode 100644
index 000000000000..752c95c9815c
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_file.out
@@ -0,0 +1,4 @@
+before for
+before dotcmd
+before break
+after for
diff --git a/bin/sh/dotcmd/out/for_break_for.out b/bin/sh/dotcmd/out/for_break_for.out
new file mode 100644
index 000000000000..20af6224fc55
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_for.out
@@ -0,0 +1,12 @@
+before for
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_break_func.out b/bin/sh/dotcmd/out/for_break_func.out
new file mode 100644
index 000000000000..fe0cab4fa49b
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_func.out
@@ -0,0 +1,5 @@
+before for
+before dotcmd
+before function
+before break
+after for
diff --git a/bin/sh/dotcmd/out/for_break_subshell.out b/bin/sh/dotcmd/out/for_break_subshell.out
new file mode 100644
index 000000000000..985aab6270c4
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_subshell.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_break_until.out b/bin/sh/dotcmd/out/for_break_until.out
new file mode 100644
index 000000000000..b47c90198f18
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_until.out
@@ -0,0 +1,12 @@
+before for
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_break_while.out b/bin/sh/dotcmd/out/for_break_while.out
new file mode 100644
index 000000000000..deb4cebaece8
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_break_while.out
@@ -0,0 +1,12 @@
+before for
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_case.out b/bin/sh/dotcmd/out/for_continue_case.out
new file mode 100644
index 000000000000..e989063290ea
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_case.out
@@ -0,0 +1,8 @@
+before for
+before dotcmd
+before case
+before continue
+before dotcmd
+before case
+before continue
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_compound.out b/bin/sh/dotcmd/out/for_continue_compound.out
new file mode 100644
index 000000000000..0fd23b628719
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_compound.out
@@ -0,0 +1,8 @@
+before for
+before dotcmd
+compound start
+before continue
+before dotcmd
+compound start
+before continue
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_file.out b/bin/sh/dotcmd/out/for_continue_file.out
new file mode 100644
index 000000000000..286bb88c1ea1
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_file.out
@@ -0,0 +1,6 @@
+before for
+before dotcmd
+before continue
+before dotcmd
+before continue
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_for.out b/bin/sh/dotcmd/out/for_continue_for.out
new file mode 100644
index 000000000000..044d5a35c55e
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_for.out
@@ -0,0 +1,14 @@
+before for
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_func.out b/bin/sh/dotcmd/out/for_continue_func.out
new file mode 100644
index 000000000000..a0cc6cc18fd8
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_func.out
@@ -0,0 +1,8 @@
+before for
+before dotcmd
+before function
+before continue
+before dotcmd
+before function
+before continue
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_subshell.out b/bin/sh/dotcmd/out/for_continue_subshell.out
new file mode 100644
index 000000000000..f1ae7aab16d0
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_subshell.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_until.out b/bin/sh/dotcmd/out/for_continue_until.out
new file mode 100644
index 000000000000..b1c4147a9730
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_until.out
@@ -0,0 +1,14 @@
+before for
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_continue_while.out b/bin/sh/dotcmd/out/for_continue_while.out
new file mode 100644
index 000000000000..f8e5c5d11830
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_continue_while.out
@@ -0,0 +1,14 @@
+before for
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_case.out b/bin/sh/dotcmd/out/for_return_case.out
new file mode 100644
index 000000000000..24b7145a05c4
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_case.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_compound.out b/bin/sh/dotcmd/out/for_return_compound.out
new file mode 100644
index 000000000000..30b4dac3988e
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_compound.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_file.out b/bin/sh/dotcmd/out/for_return_file.out
new file mode 100644
index 000000000000..88555621c77f
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_file.out
@@ -0,0 +1,8 @@
+before for
+before dotcmd
+before return
+after dotcmd, return value: 0
+before dotcmd
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_for.out b/bin/sh/dotcmd/out/for_return_for.out
new file mode 100644
index 000000000000..52a72a9fb0c8
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_for.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_func.out b/bin/sh/dotcmd/out/for_return_func.out
new file mode 100644
index 000000000000..4f0fee21740b
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_func.out
@@ -0,0 +1,12 @@
+before for
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_subshell.out b/bin/sh/dotcmd/out/for_return_subshell.out
new file mode 100644
index 000000000000..4b8f36c1a331
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_subshell.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_until.out b/bin/sh/dotcmd/out/for_return_until.out
new file mode 100644
index 000000000000..3eaf9df84b8b
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_until.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/for_return_while.out b/bin/sh/dotcmd/out/for_return_while.out
new file mode 100644
index 000000000000..8cbad954cdad
--- /dev/null
+++ b/bin/sh/dotcmd/out/for_return_while.out
@@ -0,0 +1,10 @@
+before for
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+after for
diff --git a/bin/sh/dotcmd/out/func_break_case.out b/bin/sh/dotcmd/out/func_break_case.out
new file mode 100644
index 000000000000..7373371e511b
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_case.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before case
+before break
+after break, return value: 0
+after case
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_compound.out b/bin/sh/dotcmd/out/func_break_compound.out
new file mode 100644
index 000000000000..e87b4a2e8e14
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_compound.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+compound start
+before break
+after break, return value: 0
+compound end
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_file.out b/bin/sh/dotcmd/out/func_break_file.out
new file mode 100644
index 000000000000..cf144227aefe
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_file.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before break
+after break, return value: 0
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_for.out b/bin/sh/dotcmd/out/func_break_for.out
new file mode 100644
index 000000000000..c3853488a517
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_for.out
@@ -0,0 +1,7 @@
+before function
+before dotcmd
+before for
+before break
+after for
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_func.out b/bin/sh/dotcmd/out/func_break_func.out
new file mode 100644
index 000000000000..5c1c4c830164
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_func.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before function
+before break
+after break
+after function
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_subshell.out b/bin/sh/dotcmd/out/func_break_subshell.out
new file mode 100644
index 000000000000..affe3e4bdefb
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_subshell.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+subshell start
+before break
+after break, return value: 0
+subshell end
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_until.out b/bin/sh/dotcmd/out/func_break_until.out
new file mode 100644
index 000000000000..b0f942a04fbf
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_until.out
@@ -0,0 +1,7 @@
+before function
+before dotcmd
+before until
+before break
+after until
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_break_while.out b/bin/sh/dotcmd/out/func_break_while.out
new file mode 100644
index 000000000000..d687aa766498
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_break_while.out
@@ -0,0 +1,7 @@
+before function
+before dotcmd
+before while
+before break
+after while
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_case.out b/bin/sh/dotcmd/out/func_continue_case.out
new file mode 100644
index 000000000000..b1ad4be38bfd
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_case.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before case
+before continue
+after continue, return value: 0
+after case
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_compound.out b/bin/sh/dotcmd/out/func_continue_compound.out
new file mode 100644
index 000000000000..d6a5edd9940f
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_compound.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+compound start
+before continue
+after continue, return value: 0
+compound end
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_file.out b/bin/sh/dotcmd/out/func_continue_file.out
new file mode 100644
index 000000000000..f300d6afee79
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_file.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before continue
+after continue, return value: 0
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_for.out b/bin/sh/dotcmd/out/func_continue_for.out
new file mode 100644
index 000000000000..d46095d58d36
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_for.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_func.out b/bin/sh/dotcmd/out/func_continue_func.out
new file mode 100644
index 000000000000..3ff73a2bdaa9
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_func.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before function
+before continue
+after continue
+after function
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_subshell.out b/bin/sh/dotcmd/out/func_continue_subshell.out
new file mode 100644
index 000000000000..fd295aad8542
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_subshell.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+subshell start
+before continue
+after continue, return value: 0
+subshell end
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_until.out b/bin/sh/dotcmd/out/func_continue_until.out
new file mode 100644
index 000000000000..7a6508328e00
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_until.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_continue_while.out b/bin/sh/dotcmd/out/func_continue_while.out
new file mode 100644
index 000000000000..6ecbe8261164
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_continue_while.out
@@ -0,0 +1,8 @@
+before function
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_case.out b/bin/sh/dotcmd/out/func_return_case.out
new file mode 100644
index 000000000000..8f0c0948357a
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_case.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before case
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_compound.out b/bin/sh/dotcmd/out/func_return_compound.out
new file mode 100644
index 000000000000..e3d86704f79d
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_compound.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+compound start
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_file.out b/bin/sh/dotcmd/out/func_return_file.out
new file mode 100644
index 000000000000..95e341525799
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_file.out
@@ -0,0 +1,5 @@
+before function
+before dotcmd
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_for.out b/bin/sh/dotcmd/out/func_return_for.out
new file mode 100644
index 000000000000..511cc39ca34f
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_for.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before for
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_func.out b/bin/sh/dotcmd/out/func_return_func.out
new file mode 100644
index 000000000000..a87d3a780043
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_func.out
@@ -0,0 +1,7 @@
+before function
+before dotcmd
+before function
+before return
+after function
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_subshell.out b/bin/sh/dotcmd/out/func_return_subshell.out
new file mode 100644
index 000000000000..fdb37b20979e
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_subshell.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+subshell start
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_until.out b/bin/sh/dotcmd/out/func_return_until.out
new file mode 100644
index 000000000000..08b45be42f4f
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_until.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before until
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/func_return_while.out b/bin/sh/dotcmd/out/func_return_while.out
new file mode 100644
index 000000000000..27fbcaf88b22
--- /dev/null
+++ b/bin/sh/dotcmd/out/func_return_while.out
@@ -0,0 +1,6 @@
+before function
+before dotcmd
+before while
+before return
+after dotcmd
+after function
diff --git a/bin/sh/dotcmd/out/subshell_break_case.out b/bin/sh/dotcmd/out/subshell_break_case.out
new file mode 100644
index 000000000000..155daea6606d
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_case.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before case
+before break
+after break, return value: 0
+after case
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_compound.out b/bin/sh/dotcmd/out/subshell_break_compound.out
new file mode 100644
index 000000000000..a643ac080d91
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_compound.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+compound start
+before break
+after break, return value: 0
+compound end
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_file.out b/bin/sh/dotcmd/out/subshell_break_file.out
new file mode 100644
index 000000000000..2556d89acbbe
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_file.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before break
+after break, return value: 0
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_for.out b/bin/sh/dotcmd/out/subshell_break_for.out
new file mode 100644
index 000000000000..27040a992adf
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_for.out
@@ -0,0 +1,7 @@
+subshell start
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_func.out b/bin/sh/dotcmd/out/subshell_break_func.out
new file mode 100644
index 000000000000..83ec062eed6a
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_func.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before function
+before break
+after break
+after function
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_subshell.out b/bin/sh/dotcmd/out/subshell_break_subshell.out
new file mode 100644
index 000000000000..8a53ac59e578
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_subshell.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+subshell start
+before break
+after break, return value: 0
+subshell end
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_until.out b/bin/sh/dotcmd/out/subshell_break_until.out
new file mode 100644
index 000000000000..a31fa5bfa332
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_until.out
@@ -0,0 +1,7 @@
+subshell start
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_break_while.out b/bin/sh/dotcmd/out/subshell_break_while.out
new file mode 100644
index 000000000000..42eb970ef81d
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_break_while.out
@@ -0,0 +1,7 @@
+subshell start
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_case.out b/bin/sh/dotcmd/out/subshell_continue_case.out
new file mode 100644
index 000000000000..4d74b7b151e2
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_case.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before case
+before continue
+after continue, return value: 0
+after case
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_compound.out b/bin/sh/dotcmd/out/subshell_continue_compound.out
new file mode 100644
index 000000000000..4328df396efb
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_compound.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+compound start
+before continue
+after continue, return value: 0
+compound end
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_file.out b/bin/sh/dotcmd/out/subshell_continue_file.out
new file mode 100644
index 000000000000..a4a6e4ae0411
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_file.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before continue
+after continue, return value: 0
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_for.out b/bin/sh/dotcmd/out/subshell_continue_for.out
new file mode 100644
index 000000000000..e82988936104
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_for.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_func.out b/bin/sh/dotcmd/out/subshell_continue_func.out
new file mode 100644
index 000000000000..e0ead4c87cb9
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_func.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before function
+before continue
+after continue
+after function
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_subshell.out b/bin/sh/dotcmd/out/subshell_continue_subshell.out
new file mode 100644
index 000000000000..dfcdfb46a662
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_subshell.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+subshell start
+before continue
+after continue, return value: 0
+subshell end
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_until.out b/bin/sh/dotcmd/out/subshell_continue_until.out
new file mode 100644
index 000000000000..66e8f9f269ae
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_until.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_continue_while.out b/bin/sh/dotcmd/out/subshell_continue_while.out
new file mode 100644
index 000000000000..f1c83f43d394
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_continue_while.out
@@ -0,0 +1,8 @@
+subshell start
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_case.out b/bin/sh/dotcmd/out/subshell_return_case.out
new file mode 100644
index 000000000000..008d9396a260
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_case.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_compound.out b/bin/sh/dotcmd/out/subshell_return_compound.out
new file mode 100644
index 000000000000..bdab2314d44b
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_compound.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_file.out b/bin/sh/dotcmd/out/subshell_return_file.out
new file mode 100644
index 000000000000..43d011dfb970
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_file.out
@@ -0,0 +1,5 @@
+subshell start
+before dotcmd
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_for.out b/bin/sh/dotcmd/out/subshell_return_for.out
new file mode 100644
index 000000000000..7cfed898d338
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_for.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_func.out b/bin/sh/dotcmd/out/subshell_return_func.out
new file mode 100644
index 000000000000..b695c53484c8
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_func.out
@@ -0,0 +1,7 @@
+subshell start
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_subshell.out b/bin/sh/dotcmd/out/subshell_return_subshell.out
new file mode 100644
index 000000000000..c5ccf597e61c
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_subshell.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_until.out b/bin/sh/dotcmd/out/subshell_return_until.out
new file mode 100644
index 000000000000..64737ad7341f
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_until.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/subshell_return_while.out b/bin/sh/dotcmd/out/subshell_return_while.out
new file mode 100644
index 000000000000..de520c4493ef
--- /dev/null
+++ b/bin/sh/dotcmd/out/subshell_return_while.out
@@ -0,0 +1,6 @@
+subshell start
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+subshell end
diff --git a/bin/sh/dotcmd/out/until_break_case.out b/bin/sh/dotcmd/out/until_break_case.out
new file mode 100644
index 000000000000..f0483b459129
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_case.out
@@ -0,0 +1,5 @@
+before until
+before dotcmd
+before case
+before break
+after until
diff --git a/bin/sh/dotcmd/out/until_break_compound.out b/bin/sh/dotcmd/out/until_break_compound.out
new file mode 100644
index 000000000000..a5e37ba7ab5d
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_compound.out
@@ -0,0 +1,5 @@
+before until
+before dotcmd
+compound start
+before break
+after until
diff --git a/bin/sh/dotcmd/out/until_break_file.out b/bin/sh/dotcmd/out/until_break_file.out
new file mode 100644
index 000000000000..a2fde4dafe28
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_file.out
@@ -0,0 +1,4 @@
+before until
+before dotcmd
+before break
+after until
diff --git a/bin/sh/dotcmd/out/until_break_for.out b/bin/sh/dotcmd/out/until_break_for.out
new file mode 100644
index 000000000000..8b3faf520a8f
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_for.out
@@ -0,0 +1,12 @@
+before until
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_break_func.out b/bin/sh/dotcmd/out/until_break_func.out
new file mode 100644
index 000000000000..a83ce2b82c0c
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_func.out
@@ -0,0 +1,5 @@
+before until
+before dotcmd
+before function
+before break
+after until
diff --git a/bin/sh/dotcmd/out/until_break_subshell.out b/bin/sh/dotcmd/out/until_break_subshell.out
new file mode 100644
index 000000000000..008d30dfc7d6
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_subshell.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_break_until.out b/bin/sh/dotcmd/out/until_break_until.out
new file mode 100644
index 000000000000..05fb94a46af3
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_until.out
@@ -0,0 +1,12 @@
+before until
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_break_while.out b/bin/sh/dotcmd/out/until_break_while.out
new file mode 100644
index 000000000000..6ae1f9c4225d
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_break_while.out
@@ -0,0 +1,12 @@
+before until
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_case.out b/bin/sh/dotcmd/out/until_continue_case.out
new file mode 100644
index 000000000000..40028fb08139
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_case.out
@@ -0,0 +1,8 @@
+before until
+before dotcmd
+before case
+before continue
+before dotcmd
+before case
+before continue
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_compound.out b/bin/sh/dotcmd/out/until_continue_compound.out
new file mode 100644
index 000000000000..3641e1e3f5c2
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_compound.out
@@ -0,0 +1,8 @@
+before until
+before dotcmd
+compound start
+before continue
+before dotcmd
+compound start
+before continue
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_file.out b/bin/sh/dotcmd/out/until_continue_file.out
new file mode 100644
index 000000000000..c9f5193b740f
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_file.out
@@ -0,0 +1,6 @@
+before until
+before dotcmd
+before continue
+before dotcmd
+before continue
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_for.out b/bin/sh/dotcmd/out/until_continue_for.out
new file mode 100644
index 000000000000..fd582401d026
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_for.out
@@ -0,0 +1,14 @@
+before until
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_func.out b/bin/sh/dotcmd/out/until_continue_func.out
new file mode 100644
index 000000000000..6beb16323068
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_func.out
@@ -0,0 +1,8 @@
+before until
+before dotcmd
+before function
+before continue
+before dotcmd
+before function
+before continue
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_subshell.out b/bin/sh/dotcmd/out/until_continue_subshell.out
new file mode 100644
index 000000000000..534509e7e69d
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_subshell.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_until.out b/bin/sh/dotcmd/out/until_continue_until.out
new file mode 100644
index 000000000000..ddfeb2797a7e
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_until.out
@@ -0,0 +1,14 @@
+before until
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_continue_while.out b/bin/sh/dotcmd/out/until_continue_while.out
new file mode 100644
index 000000000000..5707821eca00
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_continue_while.out
@@ -0,0 +1,14 @@
+before until
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_case.out b/bin/sh/dotcmd/out/until_return_case.out
new file mode 100644
index 000000000000..70dd420505cd
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_case.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_compound.out b/bin/sh/dotcmd/out/until_return_compound.out
new file mode 100644
index 000000000000..145d2c580f07
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_compound.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_file.out b/bin/sh/dotcmd/out/until_return_file.out
new file mode 100644
index 000000000000..5b0adb198c6d
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_file.out
@@ -0,0 +1,8 @@
+before until
+before dotcmd
+before return
+after dotcmd, return value: 0
+before dotcmd
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_for.out b/bin/sh/dotcmd/out/until_return_for.out
new file mode 100644
index 000000000000..b113e8c0552a
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_for.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_func.out b/bin/sh/dotcmd/out/until_return_func.out
new file mode 100644
index 000000000000..1ab16ab70360
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_func.out
@@ -0,0 +1,12 @@
+before until
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_subshell.out b/bin/sh/dotcmd/out/until_return_subshell.out
new file mode 100644
index 000000000000..d44463108242
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_subshell.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_until.out b/bin/sh/dotcmd/out/until_return_until.out
new file mode 100644
index 000000000000..39980179a781
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_until.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/until_return_while.out b/bin/sh/dotcmd/out/until_return_while.out
new file mode 100644
index 000000000000..9b140cf7a0a3
--- /dev/null
+++ b/bin/sh/dotcmd/out/until_return_while.out
@@ -0,0 +1,10 @@
+before until
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+after until
diff --git a/bin/sh/dotcmd/out/while_break_case.out b/bin/sh/dotcmd/out/while_break_case.out
new file mode 100644
index 000000000000..1b0731fcaf38
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_case.out
@@ -0,0 +1,5 @@
+before while
+before dotcmd
+before case
+before break
+after while
diff --git a/bin/sh/dotcmd/out/while_break_compound.out b/bin/sh/dotcmd/out/while_break_compound.out
new file mode 100644
index 000000000000..05c23eb4284c
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_compound.out
@@ -0,0 +1,5 @@
+before while
+before dotcmd
+compound start
+before break
+after while
diff --git a/bin/sh/dotcmd/out/while_break_file.out b/bin/sh/dotcmd/out/while_break_file.out
new file mode 100644
index 000000000000..cb70ae19221e
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_file.out
@@ -0,0 +1,4 @@
+before while
+before dotcmd
+before break
+after while
diff --git a/bin/sh/dotcmd/out/while_break_for.out b/bin/sh/dotcmd/out/while_break_for.out
new file mode 100644
index 000000000000..b94eac165604
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_for.out
@@ -0,0 +1,12 @@
+before while
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before break
+after for
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_break_func.out b/bin/sh/dotcmd/out/while_break_func.out
new file mode 100644
index 000000000000..7d54c1514a67
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_func.out
@@ -0,0 +1,5 @@
+before while
+before dotcmd
+before function
+before break
+after while
diff --git a/bin/sh/dotcmd/out/while_break_subshell.out b/bin/sh/dotcmd/out/while_break_subshell.out
new file mode 100644
index 000000000000..234cd663c2e0
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_subshell.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before break
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_break_until.out b/bin/sh/dotcmd/out/while_break_until.out
new file mode 100644
index 000000000000..f3602302673f
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_until.out
@@ -0,0 +1,12 @@
+before while
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before break
+after until
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_break_while.out b/bin/sh/dotcmd/out/while_break_while.out
new file mode 100644
index 000000000000..451b0a23671b
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_break_while.out
@@ -0,0 +1,12 @@
+before while
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before break
+after while
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_case.out b/bin/sh/dotcmd/out/while_continue_case.out
new file mode 100644
index 000000000000..d7f412c0d554
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_case.out
@@ -0,0 +1,8 @@
+before while
+before dotcmd
+before case
+before continue
+before dotcmd
+before case
+before continue
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_compound.out b/bin/sh/dotcmd/out/while_continue_compound.out
new file mode 100644
index 000000000000..001904764a68
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_compound.out
@@ -0,0 +1,8 @@
+before while
+before dotcmd
+compound start
+before continue
+before dotcmd
+compound start
+before continue
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_file.out b/bin/sh/dotcmd/out/while_continue_file.out
new file mode 100644
index 000000000000..9070dea4528e
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_file.out
@@ -0,0 +1,6 @@
+before while
+before dotcmd
+before continue
+before dotcmd
+before continue
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_for.out b/bin/sh/dotcmd/out/while_continue_for.out
new file mode 100644
index 000000000000..98696ee40190
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_for.out
@@ -0,0 +1,14 @@
+before while
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+before dotcmd
+before for
+before continue
+before continue
+after for
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_func.out b/bin/sh/dotcmd/out/while_continue_func.out
new file mode 100644
index 000000000000..77efc2c9c87a
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_func.out
@@ -0,0 +1,8 @@
+before while
+before dotcmd
+before function
+before continue
+before dotcmd
+before function
+before continue
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_subshell.out b/bin/sh/dotcmd/out/while_continue_subshell.out
new file mode 100644
index 000000000000..b4106a1e2d83
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_subshell.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before continue
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_until.out b/bin/sh/dotcmd/out/while_continue_until.out
new file mode 100644
index 000000000000..7f893a015a6a
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_until.out
@@ -0,0 +1,14 @@
+before while
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+before dotcmd
+before until
+before continue
+before continue
+after until
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_continue_while.out b/bin/sh/dotcmd/out/while_continue_while.out
new file mode 100644
index 000000000000..317be17fadc4
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_continue_while.out
@@ -0,0 +1,14 @@
+before while
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+before dotcmd
+before while
+before continue
+before continue
+after while
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_case.out b/bin/sh/dotcmd/out/while_return_case.out
new file mode 100644
index 000000000000..abb6a4afcfab
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_case.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+before dotcmd
+before case
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_compound.out b/bin/sh/dotcmd/out/while_return_compound.out
new file mode 100644
index 000000000000..b37418b3d34e
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_compound.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+before dotcmd
+compound start
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_file.out b/bin/sh/dotcmd/out/while_return_file.out
new file mode 100644
index 000000000000..1c4791ef7639
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_file.out
@@ -0,0 +1,8 @@
+before while
+before dotcmd
+before return
+after dotcmd, return value: 0
+before dotcmd
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_for.out b/bin/sh/dotcmd/out/while_return_for.out
new file mode 100644
index 000000000000..0569d6fe6707
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_for.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+before dotcmd
+before for
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_func.out b/bin/sh/dotcmd/out/while_return_func.out
new file mode 100644
index 000000000000..cb5a30853a10
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_func.out
@@ -0,0 +1,12 @@
+before while
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+before dotcmd
+before function
+before return
+after function
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_subshell.out b/bin/sh/dotcmd/out/while_return_subshell.out
new file mode 100644
index 000000000000..161a227239bc
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_subshell.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+before dotcmd
+subshell start
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_until.out b/bin/sh/dotcmd/out/while_return_until.out
new file mode 100644
index 000000000000..d84a5f71dca8
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_until.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+before dotcmd
+before until
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/out/while_return_while.out b/bin/sh/dotcmd/out/while_return_while.out
new file mode 100644
index 000000000000..4eeaaa9b5244
--- /dev/null
+++ b/bin/sh/dotcmd/out/while_return_while.out
@@ -0,0 +1,10 @@
+before while
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+before dotcmd
+before while
+before return
+after dotcmd, return value: 0
+after while
diff --git a/bin/sh/dotcmd/scoped_command b/bin/sh/dotcmd/scoped_command
new file mode 100755
index 000000000000..fda4e53a302a
--- /dev/null
+++ b/bin/sh/dotcmd/scoped_command
@@ -0,0 +1,129 @@
+#!/bin/sh
+#
+# $NetBSD: scoped_command,v 1.1 2014/05/31 14:29:06 christos Exp $
+#
+# Copyright (c) 2014 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Jarmo Jaakkola.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+# USAGE:
+# scoped_command scope cmd msg var_suffix
+#
+# Write to stdout a piece of Bourne Shell script with _cmd_ in specific
+# _scope_. The execution of _cmd_ is bracketed by prints of "before _msg_"
+# and "after _msg_, return value ${?}". If the generated script uses
+# variables, __var_suffix_ is appended to their names to allow nesting of
+# scripts generated this way.
+#
+# _scope_ should be one of: case, compound, file, for, func, subshell,
+# until, while.
+# _cmd_ is the command line to execute. Remember proper quoting!
+# _msg_ is text that will be used inside single quotes.
+# _var_suffix_ is a syntactically valid identifier name.
+
+# don't rely on command lists (';')
+cmd="echo 'before ${3}'
+${2}
+echo 'after ${3}, return value:' ${?}"
+
+echo "#!/bin/sh"
+
+[ 'func' = "${1}" ] && cat <<EOF
+func()
+{
+ echo 'before ${3}'
+ \${1}
+ echo 'after ${3}'
+}
+
+echo 'before function'
+func "${2}" "${3}" # don't rely on 'shift'
+echo 'after function'
+EOF
+
+[ 'case' = "${1}" ] && cat <<EOF
+echo 'before case'
+case 'a' in
+ a) ${cmd};;
+esac
+echo 'after case'
+EOF
+
+[ 'file' = "${1}" ] && cat <<EOF
+${cmd}
+EOF
+
+[ 'while' = "${1}" ] && cat <<EOF
+echo 'before while'
+cond_${4}='true true false'
+while \${cond_${4}}
+do
+ cond_${4}="\${cond_${4}#* }"
+ ${cmd}
+done
+echo 'after while'
+EOF
+
+[ 'until' = "${1}" ] && cat <<EOF
+echo 'before until'
+cond_${4}='false false true'
+until \${cond_${4}}
+do
+ cond_${4}="\${cond_${4}#* }"
+ ${cmd}
+done
+echo 'after until'
+EOF
+
+[ 'for' = "${1}" ] && cat <<EOF
+echo 'before for'
+for i_${4} in 1 2
+do
+ ${cmd}
+done
+echo 'after for'
+EOF
+
+[ 'subshell' = "${1}" ] && cat <<EOF
+(
+ echo 'subshell start'
+ ${cmd}
+ echo 'subshell end'
+)
+EOF
+
+[ 'compound' = "${1}" ] && cat <<EOF
+{
+ echo 'compound start'
+ ${cmd};
+ echo 'compound end'
+}
+EOF
+
+exit 0
diff --git a/bin/sh/dotcmd/t_dotcmd.sh b/bin/sh/dotcmd/t_dotcmd.sh
new file mode 100755
index 000000000000..b365b1de4676
--- /dev/null
+++ b/bin/sh/dotcmd/t_dotcmd.sh
@@ -0,0 +1,76 @@
+# $NetBSD: t_dotcmd.sh,v 1.1 2014/05/31 14:29:06 christos Exp $
+#
+# Copyright (c) 2014 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Jarmo Jaakkola.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Test loop and function flow control statements in various scopes in a file
+# sourced by a dotcmd in various scopes. Basically, dotcmd is like #include
+# in C/C++ so, for example, if the dotcmd is in a loop's body, a break in
+# the sourced file can be used to break out of that loop.
+
+cmds='return break continue'
+scopes='case compound file for func subshell until while'
+
+case_ids=''
+
+for dot_scope in ${scopes}
+do
+ for cmd in ${cmds}
+ do
+ for cmd_scope in ${scopes}
+ do
+ case_id="${dot_scope}_${cmd}_${cmd_scope}"
+ case_ids="${case_ids} ${case_id}"
+ atf_test_case "${case_id}"
+ eval "
+${case_id}_head()
+{
+ atf_set 'descr' \\
+ 'dotcmd in ${dot_scope}, file contains ${cmd} in ${cmd_scope}'
+}
+
+${case_id}_body()
+{
+ srcdir=\$(atf_get_srcdir)
+ # for dotcmd to find the sourced files
+ PATH=\"\${PATH}:\${srcdir}\"
+ atf_check -o file:\"\${srcdir}/out/${case_id}.out\" \\
+ \"\${srcdir}/${case_id}\"
+}
+" # end eval
+ done
+ done
+done
+
+atf_init_test_cases()
+{
+ for case_id in ${case_ids}
+ do
+ atf_add_test_case "${case_id}"
+ done
+}
diff --git a/bin/sh/t_compexit.sh b/bin/sh/t_compexit.sh
new file mode 100755
index 000000000000..019b740065b0
--- /dev/null
+++ b/bin/sh/t_compexit.sh
@@ -0,0 +1,63 @@
+# $NetBSD: t_compexit.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# The standard
+# http://www.opengroup.org/onlinepubs/007904975/utilities/set.html
+# says:
+#
+# -e
+#
+# When this option is on, if a simple command fails for any of the
+# reasons listed in Consequences of Shell Errors or returns an exit
+# status value >0, and is not part of the compound list following a
+# while, until, or if keyword, and is not a part of an AND or OR list,
+# and is not a pipeline preceded by the ! reserved word, then the shell
+# shall immediately exit.
+
+crud() {
+ set -e
+ for x in a
+ do
+ BAR="foo"
+ false && echo true
+ echo mumble
+ done
+}
+
+atf_test_case set_e
+set_e_head() {
+ atf_set "descr" "Tests that 'set -e' turns on error detection" \
+ "and that it behaves as defined by the standard"
+}
+set_e_body() {
+ foo=`crud`
+ atf_check_equal 'x$foo' 'xmumble'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case set_e
+}
diff --git a/bin/sh/t_evaltested.sh b/bin/sh/t_evaltested.sh
new file mode 100755
index 000000000000..e40f8bd4b3be
--- /dev/null
+++ b/bin/sh/t_evaltested.sh
@@ -0,0 +1,60 @@
+# $NetBSD: t_evaltested.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2011 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case evaltested
+
+evaltested_head() {
+ atf_set "descr" "Tests that eval in a tested context does not exit"
+}
+
+evaltested_body() {
+ set -e
+cat > helper.sh << EOF
+set -e
+if eval false
+then
+ echo "'eval false' returned true"
+ exit 1
+fi
+echo "passed"
+exit 0
+EOF
+ output="$(/bin/sh helper.sh)"
+ [ $? = 0 ] && return
+
+ if [ -n "$output" ]
+ then
+ atf_fail "$output"
+ else
+ atf_fail "'eval false' exited from a tested context"
+ fi
+
+}
+
+atf_init_test_cases() {
+ atf_add_test_case evaltested
+}
diff --git a/bin/sh/t_exit.sh b/bin/sh/t_exit.sh
new file mode 100755
index 000000000000..62c5869c009c
--- /dev/null
+++ b/bin/sh/t_exit.sh
@@ -0,0 +1,105 @@
+# $NetBSD: t_exit.sh,v 1.3 2012/04/13 06:12:32 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+crud() {
+ test yes = no
+
+ cat <<EOF
+$?
+EOF
+}
+
+atf_test_case background
+background_head() {
+ atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
+ "a command in the background (PR bin/46327)"
+}
+background_body() {
+ atf_check -s exit:0 -o ignore -e ignore -x "true; true & echo $?"
+ atf_check -s exit:0 -o ignore -e ignore -x "false; true & echo $?"
+}
+
+atf_test_case function
+function_head() {
+ atf_set "descr" "Tests that \$? is correctly updated inside" \
+ "a function"
+}
+function_body() {
+ foo=`crud`
+ atf_check_equal 'x$foo' 'x1'
+}
+
+atf_test_case readout
+readout_head() {
+ atf_set "descr" "Tests that \$? is correctly updated in a" \
+ "compound expression"
+}
+readout_body() {
+ atf_check_equal '$( true && ! true | false; echo $? )' '0'
+}
+
+atf_test_case trap_subshell
+trap_subshell_head() {
+ atf_set "descr" "Tests that the trap statement in a subshell" \
+ "works when the subshell exits"
+}
+trap_subshell_body() {
+ atf_check -s eq:0 -o inline:'exiting\n' -x \
+ '( trap "echo exiting" EXIT; /usr/bin/true )'
+}
+
+atf_test_case trap_zero__implicit_exit
+trap_zero__implicit_exit_body() {
+ # PR bin/6764: sh works but ksh does not"
+ echo '( trap "echo exiting" 0 )' >helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/sh helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/ksh helper.sh
+}
+
+atf_test_case trap_zero__explicit_exit
+trap_zero__explicit_exit_body() {
+ echo '( trap "echo exiting" 0; exit )' >helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/sh helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/ksh helper.sh
+}
+
+atf_test_case trap_zero__explicit_return
+trap_zero__explicit_return_body() {
+ echo '( trap "echo exiting" 0; return )' >helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/sh helper.sh
+ atf_check -s eq:0 -o match:exiting -e empty /bin/ksh helper.sh
+}
+
+atf_init_test_cases() {
+ atf_add_test_case background
+ atf_add_test_case function
+ atf_add_test_case readout
+ atf_add_test_case trap_subshell
+ atf_add_test_case trap_zero__implicit_exit
+ atf_add_test_case trap_zero__explicit_exit
+ atf_add_test_case trap_zero__explicit_return
+}
diff --git a/bin/sh/t_expand.sh b/bin/sh/t_expand.sh
new file mode 100755
index 000000000000..eeaad5f7db71
--- /dev/null
+++ b/bin/sh/t_expand.sh
@@ -0,0 +1,142 @@
+# $NetBSD: t_expand.sh,v 1.2 2013/10/06 21:05:50 ast Exp $
+#
+# Copyright (c) 2007, 2009 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# This file tests the functions in expand.c.
+#
+
+delim_argv() {
+ str=
+ while [ $# -gt 0 ]; do
+ if [ -z "${str}" ]; then
+ str=">$1<"
+ else
+ str="${str} >$1<"
+ fi
+ shift
+ done
+ echo ${str}
+}
+
+atf_test_case dollar_at
+dollar_at_head() {
+ atf_set "descr" "Somewhere between 2.0.2 and 3.0 the expansion" \
+ "of the \$@ variable had been broken. Check for" \
+ "this behavior."
+}
+dollar_at_body() {
+ # This one should work everywhere.
+ got=`echo "" "" | sed 's,$,EOL,'`
+ atf_check_equal ' EOL' '$got'
+
+ # This code triggered the bug.
+ set -- "" ""
+ got=`echo "$@" | sed 's,$,EOL,'`
+ atf_check_equal ' EOL' '$got'
+
+ set -- -
+ shift
+ n_arg() { echo $#; }
+ n_args=`n_arg "$@"`
+ atf_check_equal '0' '$n_args'
+}
+
+atf_test_case dollar_at_with_text
+dollar_at_with_text_head() {
+ atf_set "descr" "Test \$@ expansion when it is surrounded by text" \
+ "within the quotes. PR bin/33956."
+}
+dollar_at_with_text_body() {
+ set --
+ atf_check_equal '' "$(delim_argv "$@")"
+ atf_check_equal '>foobar<' "$(delim_argv "foo$@bar")"
+ atf_check_equal '>foo bar<' "$(delim_argv "foo $@ bar")"
+
+ set -- a b c
+ atf_check_equal '>a< >b< >c<' "$(delim_argv "$@")"
+ atf_check_equal '>fooa< >b< >cbar<' "$(delim_argv "foo$@bar")"
+ atf_check_equal '>foo a< >b< >c bar<' "$(delim_argv "foo $@ bar")"
+}
+
+atf_test_case strip
+strip_head() {
+ atf_set "descr" "Checks that the %% operator works and strips" \
+ "the contents of a variable from the given point" \
+ "to the end"
+}
+strip_body() {
+ line='#define bindir "/usr/bin" /* comment */'
+ stripped='#define bindir "/usr/bin" '
+ atf_expect_fail "PR bin/43469"
+ atf_check_equal '$stripped' '${line%%/\**}'
+}
+
+atf_test_case varpattern_backslashes
+varpattern_backslashes_head() {
+ atf_set "descr" "Tests that protecting wildcards with backslashes" \
+ "works in variable patterns."
+}
+varpattern_backslashes_body() {
+ line='/foo/bar/*/baz'
+ stripped='/foo/bar/'
+ atf_check_equal $stripped ${line%%\**}
+}
+
+atf_test_case arithmetic
+arithmetic_head() {
+ atf_set "descr" "POSIX requires shell arithmetic to use signed" \
+ "long or a wider type. We use intmax_t, so at" \
+ "least 64 bits should be available. Make sure" \
+ "this is true."
+}
+arithmetic_body() {
+ atf_check_equal '3' '$((1 + 2))'
+ atf_check_equal '2147483647' '$((0x7fffffff))'
+ atf_check_equal '9223372036854775807' '$(((1 << 63) - 1))'
+}
+
+atf_test_case iteration_on_null_parameter
+iteration_on_null_parameter_head() {
+ atf_set "descr" "Check iteration of \$@ in for loop when set to null;" \
+ "the error \"sh: @: parameter not set\" is incorrect." \
+ "PR bin/48202."
+}
+iteration_on_null_parameter_body() {
+ s1=`/bin/sh -uc 'N=; set -- ${N}; for X; do echo "[$X]"; done' 2>&1`
+ s2=`/bin/sh -uc 'N=; set -- ${N:-}; for X; do echo "[$X]"; done' 2>&1`
+ atf_check_equal '' '$s1'
+ atf_check_equal '[]' '$s2'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case dollar_at
+ atf_add_test_case dollar_at_with_text
+ atf_add_test_case strip
+ atf_add_test_case varpattern_backslashes
+ atf_add_test_case arithmetic
+ atf_add_test_case iteration_on_null_parameter
+}
diff --git a/bin/sh/t_fsplit.sh b/bin/sh/t_fsplit.sh
new file mode 100755
index 000000000000..2c3dbae23dc8
--- /dev/null
+++ b/bin/sh/t_fsplit.sh
@@ -0,0 +1,186 @@
+# $NetBSD: t_fsplit.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# The standard
+# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
+# explains (section 2.6) that Field splitting should be performed on the
+# result of variable expansions.
+# In particular this means that in ${x-word}, 'word' must be expanded as if
+# the "${x-" and "}" were absent from the input line.
+#
+# So: sh -c 'set ${x-a b c}; echo $#' should give 3.
+#
+
+nl='
+'
+
+check()
+{
+ result="$(eval $1)"
+ # Remove newlines
+ oifs="$IFS"
+ IFS="$nl"
+ result="$(echo $result)"
+ IFS="$oifs"
+ if [ "$2" != "$result" ]
+ then
+ atf_fail "expected [$2], found [$result]"
+ fi
+}
+
+atf_test_case for
+for_head() {
+ atf_set "descr" "Checks field splitting in for loops"
+}
+for_body() {
+ unset x
+
+ # Since I managed to break this, leave the test in
+ check 'for f in $x; do echo x${f}y; done' ''
+}
+
+atf_test_case default_val
+default_val_head() {
+ atf_set "descr" "Checks field splitting in variable default values"
+}
+default_val_body() {
+ unset x
+
+ # Check that IFS is applied to text from ${x-...} unless it is inside
+ # any set of "..."
+ check 'set ${x-a b c}; echo $#' 3
+ check 'for i in ${x-a b c}; do echo "z${i}z"; done' 'zaz zbz zcz'
+ check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' 'za bz zcz'
+ check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' 'za b cz zdz'
+ check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' 'za b cz zdz'
+ check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' 'zaz zb cz zdz'
+ check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' 'zaz zbz zcz zdz'
+}
+
+atf_test_case ifs_alpha
+ifs_alpha_head() {
+ atf_set "descr" "Checks that field splitting works with alphabetic" \
+ "characters"
+}
+ifs_alpha_body() {
+ unset x
+
+ # repeat with an alphabetic in IFS
+ check 'IFS=q; set ${x-aqbqc}; echo $#' 3
+ check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' 'zaz zbz zcz'
+ check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' 'zaqbz zcz'
+ check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' 'zaqbqcz zdz'
+ check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' 'zaqbqcz zdz'
+ check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' 'zaz zbqcz zdz'
+}
+
+atf_test_case quote
+quote_head() {
+ atf_set "descr" "Checks that field splitting works with multi-word" \
+ "fields"
+}
+quote_body() {
+ unset x
+
+ # Some quote propagation checks
+ check 'set "${x-a b c}"; echo $#' 1
+ check 'set "${x-"a b" c}"; echo $1' 'a b c'
+ check 'for i in "${x-a b c}"; do echo "z${i}z"; done' 'za b cz'
+}
+
+atf_test_case dollar_at
+dollar_at_head() {
+ atf_set "descr" "Checks that field splitting works when expanding" \
+ "\$@"
+}
+dollar_at_body() {
+ unset x
+
+ # Check we get "$@" right
+ check 'set ""; for i; do echo "z${i}z"; done' 'zz'
+ check 'set ""; for i in "$@"; do echo "z${i}z"; done' 'zz'
+ check 'set "" ""; for i; do echo "z${i}z"; done' 'zz zz'
+ check 'set "" ""; for i in "$@"; do echo "z${i}z"; done' 'zz zz'
+ check 'set "" ""; for i in $@; do echo "z${i}z"; done' ''
+ check 'set "a b" c; for i; do echo "z${i}z"; done' 'za bz zcz'
+ check 'set "a b" c; for i in "$@"; do echo "z${i}z"; done' 'za bz zcz'
+ check 'set "a b" c; for i in $@; do echo "z${i}z"; done' 'zaz zbz zcz'
+ check 'set " a b " c; for i in "$@"; do echo "z${i}z"; done' 'z a b z zcz'
+ check 'set --; for i in x"$@"x; do echo "z${i}z"; done' 'zxxz'
+ check 'set a; for i in x"$@"x; do echo "z${i}z"; done' 'zxaxz'
+ check 'set a b; for i in x"$@"x; do echo "z${i}z"; done' 'zxaz zbxz'
+}
+
+atf_test_case ifs
+ifs_head() {
+ atf_set "descr" "Checks that IFS correctly configures field" \
+ "splitting behavior"
+}
+ifs_body() {
+ unset x
+
+ # Some IFS tests
+ check 't="-- "; IFS=" "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '0'
+ check 't=" x"; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1'
+ check 't=" x "; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1'
+ check 't=axb; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 a:b'
+ check 't="a x b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 a : b'
+ check 't="a xx b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '3 a :: b'
+ check 't="a xx b"; IFS="x "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '3 a::b'
+ # A recent 'clarification' means that a single trailing IFS non-whitespace
+ # doesn't generate an empty parameter
+ check 't="xax"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 :a'
+ check 't="xax "; IFS="x "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 :a'
+ # Verify that IFS isn't being applied where it shouldn't be.
+ check 'IFS="x"; set axb; IFS=":"; r="$*"; IFS=; echo $# $r' '1 axb'
+}
+
+atf_test_case var_length
+var_length_head() {
+ atf_set "descr" "Checks that field splitting works when expanding" \
+ "a variable's length"
+}
+var_length_body() {
+ unset x
+
+ # Check that we apply IFS to ${#var}
+ long=12345678123456781234567812345678
+ long=$long$long$long$long
+ check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' '128 1 8 3'
+ check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2'
+ check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case for
+ atf_add_test_case default_val
+ atf_add_test_case ifs_alpha
+ atf_add_test_case quote
+ atf_add_test_case dollar_at
+ atf_add_test_case ifs
+ atf_add_test_case var_length
+}
diff --git a/bin/sh/t_here.sh b/bin/sh/t_here.sh
new file mode 100755
index 000000000000..250c686aa39a
--- /dev/null
+++ b/bin/sh/t_here.sh
@@ -0,0 +1,73 @@
+# $NetBSD: t_here.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+nl='
+'
+
+check()
+{
+ SVIFS="$IFS"
+ result="$(eval $1)"
+ # Remove newlines
+ oifs="$IFS"
+ IFS="$nl"
+ result="$(echo $result)"
+ IFS="$oifs"
+ if [ "$2" != "$result" ]
+ then
+ atf_fail "expected [$2], found [$result]"
+ fi
+ IFS="$SVIFS"
+}
+
+atf_test_case all
+all_head() {
+ atf_set "descr" "Basic tests for here documents"
+}
+all_body() {
+ y=x
+
+ IFS=
+ check 'x=`cat <<EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text'
+ check 'x=`cat <<\EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text'
+
+ check 'x=`cat <<EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' 'text'
+ check 'x=`cat <<\EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' 'te${y}t'
+ check 'x=`cat <<"EOF"'$nl'te${y}t'${nl}EOF$nl'`; echo $x' 'te${y}t'
+ check 'x=`cat <<'"'EOF'"$nl'te${y}t'${nl}EOF$nl'`; echo $x' 'te${y}t'
+
+ check 'x=`cat <<EOF'$nl'te'"'"'xt'${nl}EOF$nl'`; echo $x' 'te'"'"'xt'
+ check 'x=`cat <<\EOF'$nl'te'"'"'xt'${nl}EOF$nl'`; echo $x' 'te'"'"'xt'
+ check 'x=`cat <<"EOF"'$nl'te'"'"'xt'${nl}EOF$nl'`; echo $x' 'te'"'"'xt'
+
+ check 'x=`cat <<EOF'$nl'te'"'"'${y}t'${nl}EOF$nl'`; echo $x' 'te'"'"'xt'
+ check 'x=`cat <<EOF'$nl'te'"''"'${y}t'${nl}EOF$nl'`; echo $x' 'te'"''"'xt'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case all
+}
diff --git a/bin/sh/t_set_e.sh b/bin/sh/t_set_e.sh
new file mode 100755
index 000000000000..8dfe6e411746
--- /dev/null
+++ b/bin/sh/t_set_e.sh
@@ -0,0 +1,289 @@
+# $NetBSD: t_set_e.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# references:
+# http://www.opengroup.org/onlinepubs/009695399/utilities/set.html
+# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
+
+# the implementation of "sh" to test
+: ${TEST_SH:="sh"}
+
+failwith()
+{
+ case "$SH_FAILS" in
+ "") SH_FAILS=`echo "$1"`;;
+ *) SH_FAILS="$SH_FAILS"`echo; echo "$1"`;;
+ esac
+}
+
+check1()
+{
+ #echo "$TEST_SH -c $1"
+ result=`$TEST_SH -c "$1" 2>/dev/null | tr '\n' ' ' | sed 's/ *$//'`
+ if [ "$result" != "$2" ]; then
+ MSG=`printf "%-56s %-8s %s" "$3" "$result" "$2"`
+ failwith "$MSG"
+ failcount=`expr $failcount + 1`
+ fi
+ count=`expr $count + 1`
+}
+
+# direct check: try the given expression.
+dcheck()
+{
+ check1 "$1" "$2" "$1"
+}
+
+# eval check: indirect through eval.
+# as of this writing, this changes the behavior pretty drastically and
+# is thus important to test. (PR bin/29861)
+echeck()
+{
+ check1 'eval '"'($1)'" "$2" "eval '($1)'"
+}
+
+atf_test_case all
+all_head() {
+ atf_set "descr" "Tests that 'set -e' works correctly"
+}
+all_body() {
+ count=0
+ failcount=0
+
+ # make sure exiting from a subshell behaves as expected
+ dcheck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1'
+ echeck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1'
+
+ # first, check basic functioning.
+ # The ERR shouldn't print; the result of the () should be 1.
+ # Henceforth we'll assume that we don't need to check $?.
+ dcheck '(set -e; false; echo ERR$?); echo -n OK$?' 'OK1'
+ echeck '(set -e; false; echo ERR$?); echo -n OK$?' 'OK1'
+
+ # these cases should be equivalent to the preceding.
+ dcheck '(set -e; /nonexistent; echo ERR); echo OK' 'OK'
+ echeck '(set -e; /nonexistent; echo ERR); echo OK' 'OK'
+ dcheck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK'
+ echeck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK'
+ dcheck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK'
+ echeck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK'
+ dcheck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK'
+ echeck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK'
+
+ # but! with set -e, the false should cause an *immediate* exit.
+ # The return form should not, as such, but there's no way to
+ # distinguish it.
+ dcheck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK'
+ echeck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK'
+
+ # set is not scoped, so these should not exit at all.
+ dcheck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK'
+ echeck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK'
+
+ # according to the standard, only failing *simple* commands
+ # cause an exit under -e. () is not a simple command.
+ # Correct (per POSIX):
+ #dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK'
+ #echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK'
+ # Wrong current behavior:
+ dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK'
+ echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK'
+
+ # make sure an inner nested shell does exit though.
+ dcheck '(set -e; (false; echo ERR)); echo OK' 'OK'
+
+ # The left hand side of an || or && is explicitly tested and
+ # thus should not cause an exit. Furthermore, because a || or
+ # && expression is not a simple command, there should be no
+ # exit even if the overall result is false.
+ dcheck '(set -e; false || true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; false || true; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; false && true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; false && true; echo OK); echo OK' 'OK OK'
+
+ # However, the right hand side is not tested, so a failure
+ # there *should* cause an exit, regardless of whether it
+ # appears inside a non-simple command.
+ #
+ # Note that in at least one place the standard does not
+ # distinguish between the left and right hand sides of
+ # logical operators. It is possible that for strict
+ # compliance these need to not exit; however, if so that
+ # should probably be limited to when some strict-posix setting
+ # is in effect and tested accordingly.
+ #
+ dcheck '(set -e; false || false; echo ERR); echo OK' 'OK'
+ dcheck '(set -e; true && false; echo ERR); echo OK' 'OK'
+ echeck '(set -e; false || false; echo ERR); echo OK' 'OK'
+ echeck '(set -e; true && false; echo ERR); echo OK' 'OK'
+
+ # correct:
+ #dcheck '(set -e; false && false; echo ERR); echo OK' 'OK'
+ #echeck '(set -e; false && false; echo ERR); echo OK' 'OK'
+
+ # wrong current behavior:
+ dcheck '(set -e; false && false; echo ERR); echo OK' 'ERR OK'
+ echeck '(set -e; false && false; echo ERR); echo OK' 'ERR OK'
+
+ # A failure that is not reached because of short-circuit
+ # evaluation should not cause an exit, however.
+ dcheck '(set -e; true || false; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; true || false; echo OK); echo OK' 'OK OK'
+
+ # For completeness, test the other two combinations.
+ dcheck '(set -e; true || true; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; true && true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; true || true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; true && true; echo OK); echo OK' 'OK OK'
+
+ # likewise, none of these should exit.
+ dcheck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK'
+ # problematic :-)
+ #dcheck '(set -e; until false; do :; done; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \
+ 'OK OK'
+ echeck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \
+ 'OK OK'
+
+ # the bang operator tests its argument and thus the argument
+ # should not cause an exit. it is also not a simple command (I
+ # believe) so it also shouldn't exit even if it yields a false
+ # result.
+ dcheck '(set -e; ! false; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; ! true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; ! false; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; ! true; echo OK); echo OK' 'OK OK'
+
+ # combined case with () and &&; the inner expression is false
+ # but does not itself exit, and the () should not cause an
+ # exit even when failing.
+ # correct:
+ #dcheck '(set -e; (false && true); echo OK); echo OK' 'OK OK'
+ #echeck '(set -e; (false && true); echo OK); echo OK' 'OK OK'
+ # wrong current behavior:
+ dcheck '(set -e; (false && true); echo OK); echo OK' 'OK'
+ echeck '(set -e; (false && true); echo OK); echo OK' 'OK'
+
+ # pipelines. only the right-hand end is significant.
+ dcheck '(set -e; false | true; echo OK); echo OK' 'OK OK'
+ echeck '(set -e; false | true; echo OK); echo OK' 'OK OK'
+ dcheck '(set -e; true | false; echo ERR); echo OK' 'OK'
+ echeck '(set -e; true | false; echo ERR); echo OK' 'OK'
+
+ dcheck '(set -e; while true | false; do :; done; echo OK); echo OK' \
+ 'OK OK'
+ dcheck '(set -e; if true | false; then :; fi; echo OK); echo OK' \
+ 'OK OK'
+
+
+ # According to dsl@ in PR bin/32282, () is not defined as a
+ # subshell, only as a grouping operator [and a scope, I guess]
+ # so the nested false ought to cause the whole shell to exit,
+ # not just the subshell. dholland@ would like to see C&V,
+ # because that seems like a bad idea. (Among other things, it
+ # would break all the above test logic, which relies on being
+ # able to isolate set -e behavior inside ().) However, I'm
+ # going to put these tests here to make sure the issue gets
+ # dealt with sometime.
+ #
+ # XXX: the second set has been disabled in the name of making
+ # all tests "pass".
+
+ # 1. error if the whole shell exits (current behavior)
+ dcheck 'echo OK; (set -e; false); echo OK' 'OK OK'
+ echeck 'echo OK; (set -e; false); echo OK' 'OK OK'
+ # 2. error if the whole shell does not exit (dsl's suggested behavior)
+ #dcheck 'echo OK; (set -e; false); echo ERR' 'OK'
+ #echeck 'echo OK; (set -e; false); echo ERR' 'OK'
+
+ # The current behavior of the shell is that it exits out as
+ # far as -e is set and then stops. This is probably a
+ # consequence of it handling () wrong, but it's a somewhat
+ # curious compromise position between 1. and 2. above.
+ dcheck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK'
+ echeck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK'
+
+ # backquote expansion (PR bin/17514)
+
+ # correct
+ #dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK'
+ #dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK'
+ #dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK'
+ #dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK'
+ # wrong current behavior
+ dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK'
+ dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK'
+ dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK'
+ dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK'
+
+ dcheck '(set -e; x=`false`; echo ERR); echo OK' 'OK'
+ dcheck '(set -e; x=$(false); echo ERR); echo OK' 'OK'
+ dcheck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK'
+ dcheck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK'
+
+ # correct
+ #echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK'
+ #echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK'
+ #echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK'
+ #echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK'
+
+ # wrong current behavior
+ echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK'
+ echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK'
+ echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK'
+ echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK'
+
+ echeck '(set -e; x=`false`; echo ERR); echo OK' 'OK'
+ echeck '(set -e; x=$(false); echo ERR); echo OK' 'OK'
+ echeck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK'
+ echeck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK'
+
+ # shift (PR bin/37493)
+ # correct
+ #dcheck '(set -e; shift || true; echo OK); echo OK' 'OK OK'
+ #echeck '(set -e; shift || true; echo OK); echo OK' 'OK OK'
+ # wrong current behavior
+ dcheck '(set -e; shift || true; echo OK); echo OK' 'OK'
+ echeck '(set -e; shift || true; echo OK); echo OK' 'OK'
+
+ # Done.
+
+ if [ "x$SH_FAILS" != x ]; then
+ printf '%-56s %-8s %s\n' "Expression" "Result" "Should be"
+ echo "$SH_FAILS"
+ atf_fail "$failcount of $count failed cases"
+ else
+ atf_pass
+ fi
+}
+
+atf_init_test_cases() {
+ atf_add_test_case all
+}
diff --git a/bin/sh/t_ulimit.sh b/bin/sh/t_ulimit.sh
new file mode 100755
index 000000000000..3e7c0a68e70f
--- /dev/null
+++ b/bin/sh/t_ulimit.sh
@@ -0,0 +1,46 @@
+# $NetBSD: t_ulimit.sh,v 1.1 2012/06/11 18:32:59 njoly Exp $
+#
+# Copyright (c) 2012 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# ulimit builtin test.
+
+atf_test_case limits
+limits_head() {
+ atf_set "descr" "Checks for limits flags"
+}
+limits_body() {
+ atf_check -s eq:0 -o ignore -e empty \
+ /bin/sh -c "ulimit -a"
+ for l in $(ulimit -a | sed 's,^.*(,,;s, .*$,,');
+ do
+ atf_check -s eq:0 -o ignore -e empty \
+ /bin/sh -c "ulimit $l"
+ done
+}
+
+atf_init_test_cases() {
+ atf_add_test_case limits
+}
diff --git a/bin/sh/t_varquote.sh b/bin/sh/t_varquote.sh
new file mode 100755
index 000000000000..17687779637a
--- /dev/null
+++ b/bin/sh/t_varquote.sh
@@ -0,0 +1,81 @@
+# $NetBSD: t_varquote.sh,v 1.2 2012/03/25 18:50:19 christos Exp $
+#
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Variable quoting test.
+
+check() {
+ if [ "$1" != "$2" ]
+ then
+ atf_fail "expected [$2], found [$1]" 1>&2
+ fi
+}
+
+atf_test_case all
+all_head() {
+ atf_set "descr" "Basic checks for variable quoting"
+}
+all_body() {
+ foo='${a:-foo}'
+ check "$foo" '${a:-foo}'
+
+ foo="${a:-foo}"
+ check "$foo" "foo"
+
+ foo=${a:-"'{}'"}
+ check "$foo" "'{}'"
+
+ foo=${a:-${b:-"'{}'"}}
+ check "$foo" "'{}'"
+
+ foo="${a:-"'{}'"}"
+ check "$foo" "'{}'"
+
+ foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}"
+ # " z*"
+ # ${a:- }
+ # ${b:- }
+ # " y*"
+ # ${c:- }
+ # ${d:- }
+ # "x*"
+ check "$foo" "x}y}z}"
+}
+
+atf_test_case nested_quotes_multiword
+nested_quotes_multiword_head() {
+ atf_set "descr" "Tests that having nested quoting in a multi-word" \
+ "string works (PR bin/43597)"
+}
+nested_quotes_multiword_body() {
+ atf_check -s eq:0 -o match:"first-word second-word" -e empty \
+ /bin/sh -c 'echo "${foo:="first-word"} second-word"'
+}
+
+atf_init_test_cases() {
+ atf_add_test_case all
+ atf_add_test_case nested_quotes_multiword
+}
diff --git a/bin/sh/t_wait.sh b/bin/sh/t_wait.sh
new file mode 100755
index 000000000000..99b47df7ad27
--- /dev/null
+++ b/bin/sh/t_wait.sh
@@ -0,0 +1,59 @@
+# $NetBSD: t_wait.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case individual
+individual_head() {
+ atf_set "descr" "Tests that waiting for individual jobs works"
+}
+individual_body() {
+ # atf-sh confuses wait for some reason; work it around by creating
+ # a helper script that executes /bin/sh directly.
+ cat >helper.sh <<EOF
+sleep 3 &
+sleep 1 &
+
+wait %1
+if [ \$? -ne 0 ]; then
+ echo "Waiting of first job failed"
+ exit 1
+fi
+
+wait %2
+if [ \$? -ne 0 ]; then
+ echo "Waiting of second job failed"
+ exit 1
+fi
+
+exit 0
+EOF
+ output=$(/bin/sh helper.sh)
+ [ $? -eq 0 ] || atf_fail "${output}"
+}
+
+atf_init_test_cases() {
+ atf_add_test_case individual
+}
diff --git a/bin/sleep/Makefile b/bin/sleep/Makefile
new file mode 100644
index 000000000000..e6e6b81ffe83
--- /dev/null
+++ b/bin/sleep/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/30 09:27:10 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/sleep
+TESTS_SH= t_sleep
+
+.include <bsd.test.mk>
diff --git a/bin/sleep/t_sleep.sh b/bin/sleep/t_sleep.sh
new file mode 100755
index 000000000000..d79ab6722685
--- /dev/null
+++ b/bin/sleep/t_sleep.sh
@@ -0,0 +1,72 @@
+# $NetBSD: t_sleep.sh,v 1.1 2012/03/30 09:27:10 jruoho Exp $
+#
+# Copyright (c) 2012 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Jukka Ruohonen.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case fraction
+fraction_head() {
+ atf_set "descr" "Test that sleep(1) handles " \
+ "fractions of a second (PR bin/3914)"
+}
+
+fraction_body() {
+
+ atf_check -s exit:0 -o empty -e empty -x "sleep 0.1"
+ atf_check -s exit:0 -o empty -e empty -x "sleep 0.2"
+ atf_check -s exit:0 -o empty -e empty -x "sleep 0.3"
+}
+
+atf_test_case hex
+hex_head() {
+ atf_set "descr" "Test that sleep(1) handles hexadecimal arguments"
+}
+
+hex_body() {
+
+ atf_check -s exit:0 -o empty -e empty -x "sleep 0x01"
+}
+
+atf_test_case nonnumeric
+nonnumeric_head() {
+ atf_set "descr" "Test that sleep(1) errors out with " \
+ "non-numeric argument (PR bin/27140)"
+}
+
+nonnumeric_body() {
+
+ atf_check -s not-exit:0 -o empty -e not-empty -x "sleep xyz"
+ atf_check -s not-exit:0 -o empty -e not-empty -x "sleep x21"
+ atf_check -s not-exit:0 -o empty -e not-empty -x "sleep /3"
+}
+
+atf_init_test_cases() {
+
+ atf_add_test_case fraction
+ atf_add_test_case hex
+ atf_add_test_case nonnumeric
+}
diff --git a/bin/tar/Makefile b/bin/tar/Makefile
new file mode 100644
index 000000000000..377543e4fe6f
--- /dev/null
+++ b/bin/tar/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/bin/tar
+TESTS_SH= t_tar
+
+.include <bsd.test.mk>
diff --git a/bin/tar/t_tar.sh b/bin/tar/t_tar.sh
new file mode 100755
index 000000000000..133d39c1272a
--- /dev/null
+++ b/bin/tar/t_tar.sh
@@ -0,0 +1,51 @@
+# $NetBSD: t_tar.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+#
+# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case append
+append_head() {
+ atf_set "descr" "Ensure that appending a file to an archive" \
+ "produces the same results as if the file" \
+ "had been there during the archive's creation"
+}
+append_body() {
+ touch foo bar
+
+ # store both foo and bar into file1.tar
+ atf_check -s eq:0 -o empty -e empty tar -cf file1.tar foo bar
+
+ # store foo into file2.tar, then append bar to file2.tar
+ atf_check -s eq:0 -o empty -e empty tar -cf file2.tar foo
+ atf_check -s eq:0 -o empty -e empty tar -rf file2.tar bar
+
+ # ensure that file1.tar and file2.tar are equal
+ atf_check -s eq:0 -o empty -e empty cmp file1.tar file2.tar
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case append
+}