Update ^/vendor/NetBSD/tests/dist to a more recent snapshot
Pulled on "Thu Aug 11 18:01:19 PDT 2016"
This commit is contained in:
parent
e1f2d32c0e
commit
c84c9ca1e7
4
dist/Makefile
vendored
4
dist/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.44 2013/02/25 00:33:19 jmmv Exp $
|
||||
# $NetBSD: Makefile,v 1.45 2015/06/22 00:05:23 matt Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@ -9,7 +9,7 @@ TESTSDIR= ${TESTSBASE}
|
||||
TESTS_SUBDIRS= bin dev games include kernel lib libexec net
|
||||
TESTS_SUBDIRS+= sbin sys usr.bin usr.sbin
|
||||
|
||||
. if (${MKRUMP} != "no")
|
||||
. if (${MKRUMP} != "no") && !defined(BSD_MK_COMPAT_FILE)
|
||||
TESTS_SUBDIRS+= fs rump
|
||||
|
||||
. if ${MKKMOD} != "no"
|
||||
|
4
dist/bin/cat/Makefile
vendored
4
dist/bin/cat/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.1 2012/03/27 08:16:33 jruoho Exp $
|
||||
# $NetBSD: Makefile,v 1.2 2016/06/16 01:04:58 sevan Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@ -8,5 +8,7 @@ TESTS_SH= t_cat
|
||||
FILESDIR= ${TESTSDIR}
|
||||
FILES+= d_align.in
|
||||
FILES+= d_align.out
|
||||
FILES+= d_se_output.in
|
||||
FILES+= d_se_output.out
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
2
dist/bin/cat/d_align.in
vendored
2
dist/bin/cat/d_align.in
vendored
@ -1,3 +1,5 @@
|
||||
a b c
|
||||
|
||||
1 2 3
|
||||
|
||||
x y z
|
||||
|
2
dist/bin/cat/d_align.out
vendored
2
dist/bin/cat/d_align.out
vendored
@ -1,3 +1,5 @@
|
||||
1 a b c$
|
||||
$
|
||||
2 1 2 3$
|
||||
$
|
||||
3 x y z$
|
||||
|
3
dist/bin/cat/d_se_output.in
vendored
Normal file
3
dist/bin/cat/d_se_output.in
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
Of course it runs NetBSD
|
||||
|
3
dist/bin/cat/d_se_output.out
vendored
Normal file
3
dist/bin/cat/d_se_output.out
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
$
|
||||
Of course it runs NetBSD$
|
||||
$
|
14
dist/bin/cat/t_cat.sh
vendored
14
dist/bin/cat/t_cat.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_cat.sh,v 1.2 2012/03/27 17:57:02 jruoho Exp $
|
||||
# $NetBSD: t_cat.sh,v 1.3 2016/06/16 01:04:58 sevan Exp $
|
||||
#
|
||||
# Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -52,8 +52,20 @@ nonexistent_body() {
|
||||
-x "cat /some/name/that/does/not/exist"
|
||||
}
|
||||
|
||||
atf_test_case se_output
|
||||
se_output_head() {
|
||||
atf_set "descr" "Test that cat(1) prints a $ sign " \
|
||||
"on blank lines with options '-se' (PR bin/51250)"
|
||||
}
|
||||
|
||||
se_output_body() {
|
||||
atf_check -s ignore -o file:$(atf_get_srcdir)/d_se_output.out \
|
||||
-x "cat -se $(atf_get_srcdir)/d_se_output.in"
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case align
|
||||
atf_add_test_case nonexistent
|
||||
atf_add_test_case se_output
|
||||
}
|
||||
|
12
dist/bin/sh/Makefile
vendored
12
dist/bin/sh/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.4 2014/09/11 18:25:30 dholland Exp $
|
||||
# $NetBSD: Makefile,v 1.11 2016/03/20 22:57:04 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -7,15 +7,21 @@ TESTSDIR = ${TESTSBASE}/bin/sh
|
||||
|
||||
TESTS_SUBDIRS += dotcmd
|
||||
|
||||
TESTS_SH= t_compexit
|
||||
TESTS_SH+= t_arith
|
||||
TESTS_SH+= t_cmdsub
|
||||
TESTS_SH+= t_evaltested
|
||||
TESTS_SH+= t_exit
|
||||
TESTS_SH+= t_expand
|
||||
TESTS_SH+= t_evaltested
|
||||
TESTS_SH+= t_fsplit
|
||||
TESTS_SH+= t_here
|
||||
TESTS_SH+= t_option
|
||||
TESTS_SH+= t_redir
|
||||
TESTS_SH+= t_redircloexec
|
||||
TESTS_SH+= t_set_e
|
||||
TESTS_SH+= t_shift
|
||||
TESTS_SH+= t_ulimit
|
||||
TESTS_SH+= t_varquote
|
||||
TESTS_SH+= t_varval
|
||||
TESTS_SH+= t_wait
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
10
dist/bin/sh/dotcmd/Makefile
vendored
10
dist/bin/sh/dotcmd/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.2 2014/07/27 14:24:17 apb Exp $
|
||||
# $NetBSD: Makefile,v 1.3 2016/03/27 14:57:50 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -7,6 +7,10 @@ TESTSDIR = ${TESTSBASE}/bin/sh/dotcmd
|
||||
|
||||
TESTS_SH = t_dotcmd
|
||||
|
||||
.if !defined(TEST_SH)
|
||||
TEST_SH = ${HOST_SH}
|
||||
.endif
|
||||
|
||||
FILESDIR = ${TESTSDIR}/out
|
||||
|
||||
# Testing scripts: dotcmd in various scopes includes a file with
|
||||
@ -19,7 +23,7 @@ FILESDIR_${cmd}_${cmd_scope} = ${TESTSDIR}
|
||||
FILESBUILD_${cmd}_${cmd_scope} = yes
|
||||
|
||||
${cmd}_${cmd_scope}: scoped_command
|
||||
${HOST_SH} ${.CURDIR}/scoped_command '${cmd_scope}' '${cmd}' '${cmd}' \
|
||||
${TEST_SH} ${.CURDIR}/scoped_command '${cmd_scope}' '${cmd}' '${cmd}' \
|
||||
>'${.TARGET}'
|
||||
|
||||
. for dot_scope in case compound file for func subshell until while
|
||||
@ -31,7 +35,7 @@ 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}' \
|
||||
${TEST_SH} ${.CURDIR}/scoped_command '${dot_scope}' \
|
||||
'. "${cmd}_${cmd_scope}"' 'dotcmd' 'dotcmd' >'${.TARGET}'
|
||||
. endfor
|
||||
. endfor
|
||||
|
25
dist/bin/sh/dotcmd/scoped_command
vendored
25
dist/bin/sh/dotcmd/scoped_command
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: scoped_command,v 1.1 2014/05/31 14:29:06 christos Exp $
|
||||
# $NetBSD: scoped_command,v 1.2 2016/03/27 14:57:50 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -30,6 +30,27 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
: ${TEST_SH:=/bin/sh}
|
||||
|
||||
sane_sh()
|
||||
{
|
||||
set -- ${TEST_SH}
|
||||
case "$#" in
|
||||
(0) set /bin/sh;;
|
||||
(1|2) ;;
|
||||
(*) set "$1";; # Just ignore options if we cannot make them work
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
/*) TEST_SH="$1${2+ }$2";;
|
||||
./*) TEST_SH="${PWD}${1#.}${2+ }$2";;
|
||||
*/*) TEST_SH="${PWD}/$1${2+ }$2";;
|
||||
*) TEST_SH="$( command -v "$1" )${2+ }$2";;
|
||||
esac
|
||||
}
|
||||
|
||||
sane_sh
|
||||
|
||||
set -e
|
||||
|
||||
# USAGE:
|
||||
@ -52,7 +73,7 @@ cmd="echo 'before ${3}'
|
||||
${2}
|
||||
echo 'after ${3}, return value:' ${?}"
|
||||
|
||||
echo "#!/bin/sh"
|
||||
echo "#!${TEST_SH}"
|
||||
|
||||
[ 'func' = "${1}" ] && cat <<EOF
|
||||
func()
|
||||
|
6
dist/bin/sh/dotcmd/t_dotcmd.sh
vendored
6
dist/bin/sh/dotcmd/t_dotcmd.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_dotcmd.sh,v 1.1 2014/05/31 14:29:06 christos Exp $
|
||||
# $NetBSD: t_dotcmd.sh,v 1.2 2016/03/27 14:57:50 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -33,6 +33,10 @@
|
||||
# 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.
|
||||
|
||||
# Note that the standard does not require this, and allows lexically
|
||||
# scoped interpretation of break/continue (and permits dynamic scope
|
||||
# as an optional extension.)
|
||||
|
||||
cmds='return break continue'
|
||||
scopes='case compound file for func subshell until while'
|
||||
|
||||
|
1035
dist/bin/sh/t_arith.sh
vendored
Executable file
1035
dist/bin/sh/t_arith.sh
vendored
Executable file
File diff suppressed because it is too large
Load Diff
783
dist/bin/sh/t_cmdsub.sh
vendored
Executable file
783
dist/bin/sh/t_cmdsub.sh
vendored
Executable file
@ -0,0 +1,783 @@
|
||||
# $NetBSD: t_cmdsub.sh,v 1.4 2016/04/04 12:40:13 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2016 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
#
|
||||
# This file tests command substitutions ( `...` and $( ... ) )
|
||||
#
|
||||
# CAUTION:
|
||||
# Be careful attempting running these tests outside the ATF environment
|
||||
# Some of the tests run "rm *" in the current directory to clean up
|
||||
# An ATF test directory should be empty already, outside ATF, anything
|
||||
|
||||
atf_test_case a_basic_cmdsub
|
||||
a_basic_cmdsub_head() {
|
||||
atf_set "descr" 'Test operation of simple $( ) substitutions'
|
||||
}
|
||||
a_basic_cmdsub_body() {
|
||||
atf_check -s exit:0 -o match:'Result is true today' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo Result is $( true && echo true || echo false ) today'
|
||||
|
||||
atf_check -s exit:0 -o match:'Result is false today' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo Result is $( false && echo true || echo false ) today'
|
||||
|
||||
atf_check -s exit:0 -o match:'aaabbbccc' -e empty \
|
||||
${TEST_SH} -c 'echo aaa$( echo bbb )ccc'
|
||||
atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \
|
||||
${TEST_SH} -c 'echo aaa$( echo bbb ccc )ddd'
|
||||
atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \
|
||||
${TEST_SH} -c 'echo aaa$( echo bbb; echo ccc )ddd'
|
||||
atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \
|
||||
${TEST_SH} -c 'echo "aaa$( echo bbb; echo ccc )ddd"'
|
||||
|
||||
atf_check -s exit:0 -o inline:'some string\n' -e empty \
|
||||
${TEST_SH} -c 'X=$( echo some string ); echo "$X"'
|
||||
atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \
|
||||
${TEST_SH} -c 'X=$( echo "weird; string *" ); echo "$X"'
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
for f in file-1 file-2
|
||||
do
|
||||
cp /dev/null "$f"
|
||||
done
|
||||
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found $( echo * )'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found "$( echo * )"'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found $('" echo '*' )"
|
||||
atf_check -s exit:0 -o match:'Found \*' -e empty \
|
||||
${TEST_SH} -c 'echo Found "$('" echo '*' "')"'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found $('" echo \\* )"
|
||||
atf_check -s exit:0 -o match:'Found \*' -e empty \
|
||||
${TEST_SH} -c 'echo Found "$('" echo \\* )"\"
|
||||
}
|
||||
|
||||
atf_test_case b_basic_backticks
|
||||
b_basic_backticks_head() {
|
||||
atf_set "descr" 'Test operation of old style ` ` substitutions'
|
||||
}
|
||||
b_basic_backticks_body() {
|
||||
atf_check -s exit:0 -o match:'Result is true today' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo Result is `true && echo true || echo false` today'
|
||||
|
||||
atf_check -s exit:0 -o match:'Result is false today' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo Result is `false && echo true || echo false` today'
|
||||
|
||||
atf_check -s exit:0 -o match:'aaabbbccc' -e empty \
|
||||
${TEST_SH} -c 'echo aaa` echo bbb `ccc'
|
||||
atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \
|
||||
${TEST_SH} -c 'echo aaa` echo bbb ccc `ddd'
|
||||
atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \
|
||||
${TEST_SH} -c 'echo aaa` echo bbb; echo ccc `ddd'
|
||||
atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \
|
||||
${TEST_SH} -c 'echo "aaa` echo bbb; echo ccc `ddd"'
|
||||
|
||||
atf_check -s exit:0 -o inline:'some string\n' -e empty \
|
||||
${TEST_SH} -c 'X=` echo some string `; echo "$X"'
|
||||
atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \
|
||||
${TEST_SH} -c 'X=` echo "weird; string *" `; echo "$X"'
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
for f in file-1 file-2
|
||||
do
|
||||
cp /dev/null "$f"
|
||||
done
|
||||
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found ` echo * `'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found "` echo * `"'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found `'" echo '*' "'`'
|
||||
atf_check -s exit:0 -o match:'Found \*' -e empty \
|
||||
${TEST_SH} -c 'echo Found "`'" echo '*' "'`"'
|
||||
atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
|
||||
${TEST_SH} -c 'echo Found `'" echo \\* "'`'
|
||||
atf_check -s exit:0 -o match:'Found \*' -e empty \
|
||||
${TEST_SH} -c 'echo Found "`'" echo \\* "'`"'
|
||||
}
|
||||
|
||||
atf_test_case c_nested_cmdsub
|
||||
c_nested_cmdsub_head() {
|
||||
atf_set "descr" "Test that cmd substitutions can be nested"
|
||||
}
|
||||
c_nested_cmdsub_body() {
|
||||
atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
|
||||
${TEST_SH} -c 'echo __$( echo foo$(echo bar)bletch )__'
|
||||
atf_check -s exit:0 -o match:'_abcde_' -e empty \
|
||||
${TEST_SH} -c 'echo _$(echo a$(echo $(echo b)c$(echo d))e )_'
|
||||
atf_check -s exit:0 -o match:'123454321' -e empty \
|
||||
${TEST_SH} -c 'echo 1$(echo 2$(echo 3$(echo 4$(echo 5)4)3)2)1'
|
||||
}
|
||||
|
||||
atf_test_case d_nested_backticks
|
||||
d_nested_backticks_head() {
|
||||
atf_set "descr" "Tests that old style backtick cmd subs can be nested"
|
||||
}
|
||||
d_nested_backticks_body() {
|
||||
atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
|
||||
${TEST_SH} -c 'echo __` echo foo\`echo bar\`bletch `__'
|
||||
atf_check -s exit:0 -o match:'_abcde_' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo _`echo a\`echo \\\`echo b\\\`c\\\`echo d\\\`\`e `_'
|
||||
atf_check -s exit:0 -o match:'123454321' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo 1`echo 2\`echo 3\\\`echo 4\\\\\\\`echo 5\\\\\\\`4\\\`3\`2`1'
|
||||
}
|
||||
|
||||
atf_test_case e_perverse_mixing
|
||||
e_perverse_mixing_head() {
|
||||
atf_set "descr" \
|
||||
"Checks various mixed new and old style cmd substitutions"
|
||||
}
|
||||
e_perverse_mixing_body() {
|
||||
atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
|
||||
${TEST_SH} -c 'echo __$( echo foo`echo bar`bletch )__'
|
||||
atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
|
||||
${TEST_SH} -c 'echo __` echo foo$(echo bar)bletch `__'
|
||||
atf_check -s exit:0 -o match:'_abcde_' -e empty \
|
||||
${TEST_SH} -c 'echo _$(echo a`echo $(echo b)c$(echo d)`e )_'
|
||||
atf_check -s exit:0 -o match:'_abcde_' -e empty \
|
||||
${TEST_SH} -c 'echo _`echo a$(echo \`echo b\`c\`echo d\`)e `_'
|
||||
atf_check -s exit:0 -o match:'12345654321' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo 1`echo 2$(echo 3\`echo 4\\\`echo 5$(echo 6)5\\\`4\`3)2`1'
|
||||
}
|
||||
|
||||
atf_test_case f_redirect_in_cmdsub
|
||||
f_redirect_in_cmdsub_head() {
|
||||
atf_set "descr" "Checks that redirects work in command substitutions"
|
||||
}
|
||||
f_redirect_in_cmdsub_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f file 2>/dev/null || :
|
||||
atf_check -s exit:0 -o match:'_aa_' -e empty \
|
||||
${TEST_SH} -c 'echo _$( echo a$( echo b > file )a)_'
|
||||
atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file'
|
||||
atf_check -s exit:0 -o match:'_aba_' -e empty \
|
||||
${TEST_SH} -c 'echo _$( echo a$( cat < file )a)_'
|
||||
atf_check -s exit:0 -o match:'_aa_' -e empty \
|
||||
${TEST_SH} -c 'echo _$( echo a$( echo d >> file )a)_'
|
||||
atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file'
|
||||
atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \
|
||||
${TEST_SH} -c 'echo _$( echo a$( echo not error >&2 )a)_'
|
||||
}
|
||||
|
||||
atf_test_case g_redirect_in_backticks
|
||||
g_redirect_in_backticks_head() {
|
||||
atf_set "descr" "Checks that redirects work in old style cmd sub"
|
||||
}
|
||||
g_redirect_in_backticks_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f file 2>/dev/null || :
|
||||
atf_check -s exit:0 -o match:'_aa_' -e empty \
|
||||
${TEST_SH} -c 'echo _` echo a\` echo b > file \`a`_'
|
||||
atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file'
|
||||
atf_check -s exit:0 -o match:'_aba_' -e empty \
|
||||
${TEST_SH} -c 'echo _` echo a\` cat < file \`a`_'
|
||||
atf_check -s exit:0 -o match:'_aa_' -e empty \
|
||||
${TEST_SH} -c 'echo _` echo a\` echo d >> file \`a`_'
|
||||
atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file'
|
||||
atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \
|
||||
${TEST_SH} -c 'echo _` echo a\` echo not error >&2 \`a`_'
|
||||
}
|
||||
|
||||
atf_test_case h_vars_in_cmdsub
|
||||
h_vars_in_cmdsub_head() {
|
||||
atf_set "descr" "Check that variables work in command substitutions"
|
||||
}
|
||||
h_vars_in_cmdsub_body() {
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo __$( echo ${X} )__'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo __$( echo "${X}" )__'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "__$( echo ${X} )__"'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "__$( echo "${X}" )__"'
|
||||
|
||||
atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \
|
||||
${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done'
|
||||
|
||||
atf_check -s exit:0 -o match:'__acd__' -e empty \
|
||||
${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"'
|
||||
atf_check -s exit:0 -o match:'__abcd__' -e empty \
|
||||
${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"'
|
||||
atf_check -s exit:0 -o match:'__XYX__' -e empty \
|
||||
${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"'
|
||||
atf_check -s exit:0 -o match:'__def__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "__$(X=def; echo "${X}" )__"'
|
||||
atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "$X$(X=def; echo ${X} )"; echo $X'
|
||||
}
|
||||
|
||||
atf_test_case i_vars_in_backticks
|
||||
i_vars_in_backticks_head() {
|
||||
atf_set "descr" "Checks that variables work in old style cmd sub"
|
||||
}
|
||||
i_vars_in_backticks_body() {
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo __` echo ${X} `__'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo __` echo "${X}" `__'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "__` echo ${X} `__"'
|
||||
atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "__` echo \"${X}\" `__"'
|
||||
|
||||
atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \
|
||||
${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done'
|
||||
|
||||
atf_check -s exit:0 -o match:'__acd__' -e empty \
|
||||
${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"'
|
||||
atf_check -s exit:0 -o match:'__abcd__' -e empty \
|
||||
${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"'
|
||||
atf_check -s exit:0 -o match:'__XYX__' -e empty \
|
||||
${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"'
|
||||
atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \
|
||||
${TEST_SH} -c 'X=abc; echo "$X`X=def; echo \"${X}\" `";echo $X'
|
||||
|
||||
# The following is nonsense, so is not included ...
|
||||
# atf_check -s exit:0 -o match:'__abc__' -e empty \
|
||||
# oV cV oV cV
|
||||
# ${TEST_SH} -c 'X=abc; echo "__`X=def echo "${X}" `__"'
|
||||
# `start in " ^ " ends, ` not yet
|
||||
}
|
||||
|
||||
atf_test_case j_cmdsub_in_varexpand
|
||||
j_cmdsub_in_varexpand_head() {
|
||||
atf_set "descr" "Checks that command sub can be used in var expansion"
|
||||
}
|
||||
j_cmdsub_in_varexpand_body() {
|
||||
atf_check -s exit:0 -o match:'foo' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X+$(echo foo)}'
|
||||
atf_check -s exit:0 -o match:'set' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X-$(echo foo)}'
|
||||
rm -f bar 2>/dev/null || :
|
||||
atf_check -s exit:0 -o match:'set' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X-$(echo foo > bar)}'
|
||||
test -f bar && atf_fail "bar should not exist, but does"
|
||||
atf_check -s exit:0 -o inline:'\n' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X+$(echo foo > bar)}'
|
||||
test -f bar || atf_fail "bar should exist, but does not"
|
||||
}
|
||||
|
||||
atf_test_case k_backticks_in_varexpand
|
||||
k_backticks_in_varexpand_head() {
|
||||
atf_set "descr" "Checks that old style cmd sub works in var expansion"
|
||||
}
|
||||
k_backticks_in_varexpand_body() {
|
||||
atf_check -s exit:0 -o match:'foo' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X+`echo foo`}'
|
||||
atf_check -s exit:0 -o match:'set' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X-`echo foo`}'
|
||||
rm -f bar 2>/dev/null || :
|
||||
atf_check -s exit:0 -o match:'set' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X-`echo foo > bar`}'
|
||||
test -f bar && atf_fail "bar should not exist, but does"
|
||||
atf_check -s exit:0 -o inline:'\n' -e empty \
|
||||
${TEST_SH} -c 'X=set; echo ${X+`echo foo > bar`}'
|
||||
test -f bar || atf_fail "bar should exist, but does not"
|
||||
}
|
||||
|
||||
atf_test_case l_arithmetic_in_cmdsub
|
||||
l_arithmetic_in_cmdsub_head() {
|
||||
atf_set "descr" "Checks that arithmetic works in cmd substitutions"
|
||||
}
|
||||
l_arithmetic_in_cmdsub_body() {
|
||||
atf_check -s exit:0 -o inline:'1 + 1 = 2\n' -e empty \
|
||||
${TEST_SH} -c 'echo 1 + 1 = $( echo $(( 1 + 1 )) )'
|
||||
atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \
|
||||
${TEST_SH} -c 'X=2; Y=3; echo X \* Y = $( echo $(( X * Y )) )'
|
||||
atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \
|
||||
${TEST_SH} -c 'X=2; Y=3; echo Y % X = $( echo $(( $Y % $X )) )'
|
||||
}
|
||||
|
||||
atf_test_case m_arithmetic_in_backticks
|
||||
m_arithmetic_in_backticks_head() {
|
||||
atf_set "descr" "Checks that arithmetic works in old style cmd sub"
|
||||
}
|
||||
m_arithmetic_in_backticks_body() {
|
||||
atf_check -s exit:0 -o inline:'2 + 3 = 5\n' -e empty \
|
||||
${TEST_SH} -c 'echo 2 + 3 = ` echo $(( 2 + 3 )) `'
|
||||
atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \
|
||||
${TEST_SH} -c 'X=2; Y=3; echo X \* Y = ` echo $(( X * Y )) `'
|
||||
atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \
|
||||
${TEST_SH} -c 'X=2; Y=3; echo Y % X = ` echo $(( $Y % $X )) `'
|
||||
}
|
||||
|
||||
atf_test_case n_cmdsub_in_arithmetic
|
||||
n_cmdsub_in_arithmetic_head() {
|
||||
atf_set "descr" "Tests uses of command substitutions in arithmetic"
|
||||
}
|
||||
n_cmdsub_in_arithmetic_body() {
|
||||
atf_check -s exit:0 -o inline:'7\n' -e empty \
|
||||
${TEST_SH} -c 'echo $(( $( echo 3 ) $( echo + ) $( echo 4 ) ))'
|
||||
atf_check -s exit:0 -o inline:'11\n7\n18\n4\n1\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'for op in + - \* / %
|
||||
do
|
||||
echo $(( $( echo 9 ) $( echo "${op}" ) $( echo 2 ) ))
|
||||
done'
|
||||
}
|
||||
|
||||
atf_test_case o_backticks_in_arithmetic
|
||||
o_backticks_in_arithmetic_head() {
|
||||
atf_set "descr" "Tests old style cmd sub used in arithmetic"
|
||||
}
|
||||
o_backticks_in_arithmetic_body() {
|
||||
atf_check -s exit:0 -o inline:'33\n' -e empty \
|
||||
${TEST_SH} -c 'echo $(( `echo 77` `echo -` `echo 44`))'
|
||||
atf_check -s exit:0 -o inline:'14\n8\n33\n3\n2\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'for op in + - \* / %
|
||||
do
|
||||
echo $((`echo 11``echo "${op}"``echo 3`))
|
||||
done'
|
||||
}
|
||||
|
||||
atf_test_case p_cmdsub_in_heredoc
|
||||
p_cmdsub_in_heredoc_head() {
|
||||
atf_set "descr" "Checks that cmdsubs work inside a here document"
|
||||
}
|
||||
p_cmdsub_in_heredoc_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'line 1+1\nline 2\nline 3\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'cat <<- EOF
|
||||
$( echo line 1 )$( echo +1 )
|
||||
$( echo line 2;echo line 3 )
|
||||
EOF'
|
||||
}
|
||||
|
||||
atf_test_case q_backticks_in_heredoc
|
||||
q_backticks_in_heredoc_head() {
|
||||
atf_set "descr" "Checks that old style cmdsubs work in here docs"
|
||||
}
|
||||
q_backticks_in_heredoc_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'cat <<- EOF
|
||||
`echo Mary ` `echo had a `
|
||||
` echo little; echo lamb `
|
||||
EOF'
|
||||
}
|
||||
|
||||
atf_test_case r_heredoc_in_cmdsub
|
||||
r_heredoc_in_cmdsub_head() {
|
||||
atf_set "descr" "Checks that here docs work inside cmd subs"
|
||||
}
|
||||
r_heredoc_in_cmdsub_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
|
||||
${TEST_SH} -c 'echo "$( cat <<- \EOF
|
||||
Mary had a
|
||||
little
|
||||
lamb
|
||||
EOF
|
||||
)"'
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \
|
||||
${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF
|
||||
Mary had ${N}
|
||||
little
|
||||
lamb$( [ $N -gt 1 ] && echo s )
|
||||
EOF
|
||||
)"; done'
|
||||
|
||||
|
||||
atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \
|
||||
${TEST_SH} -c 'echo "$( cat <<- EOF
|
||||
A Calculation:
|
||||
2 * 7 = $(( 2 * 7 ))
|
||||
EOF
|
||||
)"'
|
||||
}
|
||||
|
||||
atf_test_case s_heredoc_in_backticks
|
||||
s_heredoc_in_backticks_head() {
|
||||
atf_set "descr" "Checks that here docs work inside old style cmd subs"
|
||||
}
|
||||
s_heredoc_in_backticks_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \
|
||||
${TEST_SH} -c 'echo ` cat <<- \EOF
|
||||
Mary had a
|
||||
little
|
||||
lamb
|
||||
EOF
|
||||
`'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \
|
||||
${TEST_SH} -c 'echo "` cat <<- EOF
|
||||
A Calculation:
|
||||
17 / 3 = $(( 17 / 3 ))
|
||||
EOF
|
||||
`"'
|
||||
}
|
||||
|
||||
atf_test_case t_nested_cmdsubs_in_heredoc
|
||||
t_nested_cmdsubs_in_heredoc_head() {
|
||||
atf_set "descr" "Checks nested command substitutions in here docs"
|
||||
}
|
||||
t_nested_cmdsubs_in_heredoc_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo "Hello" > File
|
||||
|
||||
atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
$(cat File) U
|
||||
$( V=$(cat File); echo "${V%lo}p" ) me!
|
||||
EOF'
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo V>V ; echo A>A; echo R>R
|
||||
echo Value>VAR
|
||||
|
||||
atf_check -s exit:0 -o inline:'$2.50\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
$(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2})))
|
||||
EOF'
|
||||
}
|
||||
|
||||
atf_test_case u_nested_backticks_in_heredoc
|
||||
u_nested_backticks_in_heredoc_head() {
|
||||
atf_set "descr" "Checks nested old style cmd subs in here docs"
|
||||
}
|
||||
u_nested_backticks_in_heredoc_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo "Hello" > File
|
||||
|
||||
atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
`cat File` U
|
||||
`V=\`cat File\`; echo "${V%lo}p" ` me!
|
||||
EOF'
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo V>V ; echo A>A; echo R>R
|
||||
echo Value>VAR
|
||||
|
||||
atf_check -s exit:0 -o inline:'$5.20\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
`Value='\''$5.20'\'';eval echo \`eval \\\`cat V\\\`\\\`cat A\\\`\\\`cat R\\\`=\\\'\''\\\$\\\`cat \\\\\\\`cat V\\\\\\\`\\\\\\\`cat A\\\\\\\`\\\\\\\`cat R\\\\\\\`\\\`\\\'\''; eval echo \\\$\\\`set -- *;echo \\\\\${3}\\\\\${1}\\\\\${2}\\\`\``
|
||||
EOF'
|
||||
}
|
||||
|
||||
atf_test_case v_cmdsub_paren_tests
|
||||
v_cmdsub__paren_tests_head() {
|
||||
atf_set "descr" "tests with cmdsubs containing embedded ')'"
|
||||
}
|
||||
v_cmdsub_paren_tests_body() {
|
||||
|
||||
# Tests from:
|
||||
# http://www.in-ulm.de/~mascheck/various/cmd-subst/
|
||||
# (slightly modified.)
|
||||
|
||||
atf_check -s exit:0 -o inline:'A.1\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
case x in x) echo A.1;; esac
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A.2\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
case x in x) echo A.2;; esac # comment
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A.3\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
case x in (x) echo A.3;; esac
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A.4\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
case x in (x) echo A.4;; esac # comment
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A.5\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
case x in (x) echo A.5
|
||||
esac
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'B: quoted )\n' -e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
echo '\''B: quoted )'\''
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'C: comment then closing paren\n' \
|
||||
-e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
echo C: comment then closing paren # )
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -o inline:'D.1: here-doc with )\n' \
|
||||
-e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-\eof
|
||||
D.1: here-doc with )
|
||||
eof
|
||||
)'
|
||||
|
||||
# D.2 is a bogus test.
|
||||
|
||||
atf_check -s exit:0 -o inline:'D.3: here-doc with \()\n' \
|
||||
-e empty ${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-\eof
|
||||
D.3: here-doc with \()
|
||||
eof
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'E: here-doc terminated with a parenthesis ("academic")\n' \
|
||||
${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-\)
|
||||
E: here-doc terminated with a parenthesis ("academic")
|
||||
)
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'F.1: here-doc embed with unbal single, back- or doublequote '\''\n' \
|
||||
${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-"eof"
|
||||
F.1: here-doc embed with unbal single, back- or doublequote '\''
|
||||
eof
|
||||
)'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'F.2: here-doc embed with unbal single, back- or doublequote "\n' \
|
||||
${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-"eof"
|
||||
F.2: here-doc embed with unbal single, back- or doublequote "
|
||||
eof
|
||||
)'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'F.3: here-doc embed with unbal single, back- or doublequote `\n' \
|
||||
${TEST_SH} -c \
|
||||
'echo $(
|
||||
cat <<-"eof"
|
||||
F.3: here-doc embed with unbal single, back- or doublequote `
|
||||
eof
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -e empty -o inline:'G: backslash at end of line\n' \
|
||||
${TEST_SH} -c \
|
||||
'echo $(
|
||||
echo G: backslash at end of line # \
|
||||
)'
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'H: empty command-substitution\n' \
|
||||
${TEST_SH} -c 'echo H: empty command-substitution $( )'
|
||||
}
|
||||
|
||||
atf_test_case w_heredoc_outside_cmdsub
|
||||
w_heredoc_outside_cmdsub_head() {
|
||||
atf_set "descr" "Checks that here docs work inside cmd subs"
|
||||
}
|
||||
w_heredoc_outside_cmdsub_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
|
||||
${TEST_SH} -c 'echo "$( cat <<- \EOF )"
|
||||
Mary had a
|
||||
little
|
||||
lamb
|
||||
EOF
|
||||
'
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \
|
||||
${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF )"
|
||||
Mary had ${N}
|
||||
little
|
||||
lamb$( [ $N -gt 1 ] && echo s )
|
||||
EOF
|
||||
done'
|
||||
|
||||
|
||||
atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \
|
||||
${TEST_SH} -c 'echo "$( cat <<- EOF)"
|
||||
A Calculation:
|
||||
2 * 7 = $(( 2 * 7 ))
|
||||
EOF
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case x_heredoc_outside_backticks
|
||||
x_heredoc_outside_backticks_head() {
|
||||
atf_set "descr" "Checks that here docs work inside old style cmd subs"
|
||||
}
|
||||
x_heredoc_outside_backticks_body() {
|
||||
atf_require_prog cat
|
||||
|
||||
atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \
|
||||
${TEST_SH} -c 'echo ` cat <<- \EOF `
|
||||
Mary had a
|
||||
little
|
||||
lamb
|
||||
EOF
|
||||
'
|
||||
|
||||
atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \
|
||||
${TEST_SH} -c 'echo "` cat <<- EOF `"
|
||||
A Calculation:
|
||||
17 / 3 = $(( 17 / 3 ))
|
||||
EOF
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case t_nested_cmdsubs_in_heredoc
|
||||
t_nested_cmdsubs_in_heredoc_head() {
|
||||
atf_set "descr" "Checks nested command substitutions in here docs"
|
||||
}
|
||||
t_nested_cmdsubs_in_heredoc_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo "Hello" > File
|
||||
|
||||
atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
$(cat File) U
|
||||
$( V=$(cat File); echo "${V%lo}p" ) me!
|
||||
EOF'
|
||||
|
||||
rm -f * 2>/dev/null || :
|
||||
echo V>V ; echo A>A; echo R>R
|
||||
echo Value>VAR
|
||||
|
||||
atf_check -s exit:0 -o inline:'$2.50\n' -e empty \
|
||||
${TEST_SH} -c 'cat <<- EOF
|
||||
$(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2})))
|
||||
EOF'
|
||||
}
|
||||
|
||||
atf_test_case z_absurd_heredoc_cmdsub_combos
|
||||
z_absurd_heredoc_cmdsub_combos_head() {
|
||||
atf_set "descr" "perverse and unusual cmd substitutions & more"
|
||||
}
|
||||
z_absurd_heredoc_cmdsub_combos_body() {
|
||||
|
||||
echo "Help!" > help
|
||||
|
||||
# This version works in NetBSD (& FreeBSD)'s sh (and most others)
|
||||
atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c '
|
||||
cat <<- EOF
|
||||
$(
|
||||
cat <<- STOP
|
||||
$(
|
||||
cat `echo help`
|
||||
)
|
||||
STOP
|
||||
)
|
||||
$(
|
||||
cat <<- END 4<<-TRASH
|
||||
Me $(( 1 + 1 ))
|
||||
END
|
||||
This is unused noise!
|
||||
TRASH
|
||||
)
|
||||
EOF
|
||||
'
|
||||
|
||||
# atf_expect_fail "PR bin/50993 - heredoc parsing done incorrectly"
|
||||
atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c '
|
||||
cat <<- EOF
|
||||
$(
|
||||
cat << STOP
|
||||
$(
|
||||
cat `echo help`
|
||||
)
|
||||
STOP
|
||||
)
|
||||
$(
|
||||
cat <<- END 4<<TRASH
|
||||
Me $(( 1 + 1 ))
|
||||
END
|
||||
This is unused noise!
|
||||
TRASH
|
||||
)
|
||||
EOF
|
||||
'
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case a_basic_cmdsub
|
||||
atf_add_test_case b_basic_backticks
|
||||
atf_add_test_case c_nested_cmdsub
|
||||
atf_add_test_case d_nested_backticks
|
||||
atf_add_test_case e_perverse_mixing
|
||||
atf_add_test_case f_redirect_in_cmdsub
|
||||
atf_add_test_case g_redirect_in_backticks
|
||||
atf_add_test_case h_vars_in_cmdsub
|
||||
atf_add_test_case i_vars_in_backticks
|
||||
atf_add_test_case j_cmdsub_in_varexpand
|
||||
atf_add_test_case k_backticks_in_varexpand
|
||||
atf_add_test_case l_arithmetic_in_cmdsub
|
||||
atf_add_test_case m_arithmetic_in_backticks
|
||||
atf_add_test_case n_cmdsub_in_arithmetic
|
||||
atf_add_test_case o_backticks_in_arithmetic
|
||||
atf_add_test_case p_cmdsub_in_heredoc
|
||||
atf_add_test_case q_backticks_in_heredoc
|
||||
atf_add_test_case r_heredoc_in_cmdsub
|
||||
atf_add_test_case s_heredoc_in_backticks
|
||||
atf_add_test_case t_nested_cmdsubs_in_heredoc
|
||||
atf_add_test_case u_nested_backticks_in_heredoc
|
||||
atf_add_test_case v_cmdsub_paren_tests
|
||||
atf_add_test_case w_heredoc_outside_cmdsub
|
||||
atf_add_test_case x_heredoc_outside_backticks
|
||||
atf_add_test_case z_absurd_heredoc_cmdsub_combos
|
||||
}
|
6
dist/bin/sh/t_evaltested.sh
vendored
6
dist/bin/sh/t_evaltested.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_evaltested.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
|
||||
# $NetBSD: t_evaltested.sh,v 1.2 2016/03/27 14:50:01 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,6 +24,8 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
atf_test_case evaltested
|
||||
|
||||
@ -43,7 +45,7 @@ fi
|
||||
echo "passed"
|
||||
exit 0
|
||||
EOF
|
||||
output="$(/bin/sh helper.sh)"
|
||||
output="$($TEST_SH helper.sh)"
|
||||
[ $? = 0 ] && return
|
||||
|
||||
if [ -n "$output" ]
|
||||
|
120
dist/bin/sh/t_exit.sh
vendored
120
dist/bin/sh/t_exit.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_exit.sh,v 1.3 2012/04/13 06:12:32 jruoho Exp $
|
||||
# $NetBSD: t_exit.sh,v 1.6 2016/05/07 23:51:30 kre Exp $
|
||||
#
|
||||
# Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,74 +24,124 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
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)"
|
||||
"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_check -o match:0 -e empty ${TEST_SH} -c 'true; true & echo $?'
|
||||
# atf_expect_fail "PR bin/46327" (now fixed?)
|
||||
atf_check -o match:0 -e empty ${TEST_SH} -c 'false; true & echo $?'
|
||||
}
|
||||
|
||||
atf_test_case function
|
||||
function_head() {
|
||||
atf_set "descr" "Tests that \$? is correctly updated inside" \
|
||||
"a function"
|
||||
atf_set "descr" "Tests that \$? is correctly updated inside " \
|
||||
"a function"
|
||||
}
|
||||
function_body() {
|
||||
foo=`crud`
|
||||
atf_check_equal 'x$foo' 'x1'
|
||||
atf_check -s exit:0 -o match:STATUS=1-0 -e empty \
|
||||
${TEST_SH} -c '
|
||||
crud() {
|
||||
test yes = no
|
||||
|
||||
cat <<-EOF
|
||||
STATUS=$?
|
||||
EOF
|
||||
}
|
||||
foo=$(crud)
|
||||
echo "${foo}-$?"
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case readout
|
||||
readout_head() {
|
||||
atf_set "descr" "Tests that \$? is correctly updated in a" \
|
||||
"compound expression"
|
||||
atf_set "descr" "Tests that \$? is correctly updated in a " \
|
||||
"compound expression"
|
||||
}
|
||||
readout_body() {
|
||||
atf_check_equal '$( true && ! true | false; echo $? )' '0'
|
||||
atf_check -s exit:0 -o match:0 -e empty \
|
||||
${TEST_SH} -c 'true && ! true | false; echo $?'
|
||||
}
|
||||
|
||||
atf_test_case trap_subshell
|
||||
trap_subshell_head() {
|
||||
atf_set "descr" "Tests that the trap statement in a subshell" \
|
||||
"works when the subshell exits"
|
||||
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_check -s exit:0 -o inline:'exiting\n' -e empty \
|
||||
${TEST_SH} -c '( trap "echo exiting" EXIT; /usr/bin/true )'
|
||||
}
|
||||
|
||||
atf_test_case trap_zero__implicit_exit
|
||||
trap_zero__implicit_exit_head() {
|
||||
atf_set "descr" "Tests that the trap statement in a subshell in a " \
|
||||
"script works when the subshell simply runs out of commands"
|
||||
}
|
||||
trap_zero__implicit_exit_body() {
|
||||
# PR bin/6764: sh works but ksh does not"
|
||||
# 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_check -s exit:0 -o match:exiting -e empty ${TEST_SH} helper.sh
|
||||
# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
|
||||
# atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh
|
||||
}
|
||||
|
||||
atf_test_case trap_zero__explicit_exit
|
||||
trap_zero__explicit_exit_head() {
|
||||
atf_set "descr" "Tests that the trap statement in a subshell in a " \
|
||||
"script works when the subshell executes an 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
|
||||
echo '( trap "echo exiting" 0; exit; echo NO_NO_NO )' >helper.sh
|
||||
atf_check -s exit:0 -o match:exiting -o not-match:NO_NO -e empty \
|
||||
${TEST_SH} helper.sh
|
||||
# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
|
||||
# atf_check -s exit: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_test_case simple_exit
|
||||
simple_exit_head() {
|
||||
atf_set "descr" "Tests that various values for exit status work"
|
||||
}
|
||||
# Note: ATF will not allow tests of exit values > 255, even if they would work
|
||||
simple_exit_body() {
|
||||
for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
|
||||
do
|
||||
atf_check -s exit:$N -o empty -e empty \
|
||||
${TEST_SH} -c "exit $N; echo FOO; echo BAR >&2"
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case subshell_exit
|
||||
subshell_exit_head() {
|
||||
atf_set "descr" "Tests that subshell exit status works and \$? gets it"
|
||||
}
|
||||
# Note: ATF will not allow tests of exit values > 255, even if they would work
|
||||
subshell_exit_body() {
|
||||
for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
|
||||
do
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c "(exit $N); test \$? -eq $N"
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case subshell_background
|
||||
subshell_background_head() {
|
||||
atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
|
||||
"a subshell in the background"
|
||||
}
|
||||
subshell_background_body() {
|
||||
atf_check -o match:0 -e empty \
|
||||
${TEST_SH} -c 'true; (false || true) & echo $?'
|
||||
# atf_expect_fail "PR bin/46327" (now fixed?)
|
||||
atf_check -o match:0 -e empty \
|
||||
${TEST_SH} -c 'false; (false || true) & echo $?'
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
@ -101,5 +151,7 @@ atf_init_test_cases() {
|
||||
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
|
||||
atf_add_test_case simple_exit
|
||||
atf_add_test_case subshell_exit
|
||||
atf_add_test_case subshell_background
|
||||
}
|
||||
|
296
dist/bin/sh/t_expand.sh
vendored
296
dist/bin/sh/t_expand.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_expand.sh,v 1.2 2013/10/06 21:05:50 ast Exp $
|
||||
# $NetBSD: t_expand.sh,v 1.8 2016/04/29 18:29:17 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2007, 2009 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,6 +24,8 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
#
|
||||
# This file tests the functions in expand.c.
|
||||
@ -50,19 +52,15 @@ dollar_at_head() {
|
||||
}
|
||||
dollar_at_body() {
|
||||
# This one should work everywhere.
|
||||
got=`echo "" "" | sed 's,$,EOL,'`
|
||||
atf_check_equal ' EOL' '$got'
|
||||
atf_check -s exit:0 -o inline:' EOL\n' -e empty \
|
||||
${TEST_SH} -c 'echo "" "" | '" sed 's,\$,EOL,'"
|
||||
|
||||
# This code triggered the bug.
|
||||
set -- "" ""
|
||||
got=`echo "$@" | sed 's,$,EOL,'`
|
||||
atf_check_equal ' EOL' '$got'
|
||||
atf_check -s exit:0 -o inline:' EOL\n' -e empty \
|
||||
${TEST_SH} -c 'set -- "" ""; echo "$@" | '" sed 's,\$,EOL,'"
|
||||
|
||||
set -- -
|
||||
shift
|
||||
n_arg() { echo $#; }
|
||||
n_args=`n_arg "$@"`
|
||||
atf_check_equal '0' '$n_args'
|
||||
atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
|
||||
'set -- -; shift; n_arg() { echo $#; }; n_arg "$@"'
|
||||
}
|
||||
|
||||
atf_test_case dollar_at_with_text
|
||||
@ -71,15 +69,61 @@ dollar_at_with_text_head() {
|
||||
"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")"
|
||||
cat <<'EOF' > h-f1
|
||||
|
||||
delim_argv() {
|
||||
str=
|
||||
while [ $# -gt 0 ]; do
|
||||
if [ -z "${str}" ]; then
|
||||
str=">$1<"
|
||||
else
|
||||
str="${str} >$1<"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
echo "${str}"
|
||||
}
|
||||
|
||||
EOF
|
||||
cat <<'EOF' > h-f2
|
||||
|
||||
delim_argv() {
|
||||
str=
|
||||
while [ $# -gt 0 ]; do
|
||||
|
||||
str="${str}${str:+ }>$1<"
|
||||
shift
|
||||
|
||||
done
|
||||
echo "${str}"
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
chmod +x h-f1 h-f2
|
||||
|
||||
for f in 1 2
|
||||
do
|
||||
atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- ; delim_argv "$@"'
|
||||
atf_check -s exit:0 -o inline:'>foobar<\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- ; delim_argv "foo$@bar"'
|
||||
atf_check -s exit:0 -o inline:'>foo bar<\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- ; delim_argv "foo $@ bar"'
|
||||
|
||||
atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- a b c; delim_argv "$@"'
|
||||
atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- a b c; delim_argv "foo$@bar"'
|
||||
atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./h-f${f}; "'set -- a b c; delim_argv "foo $@ bar"'
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case strip
|
||||
@ -91,8 +135,25 @@ strip_head() {
|
||||
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_expect_fail "PR bin/43469" -- now fixed
|
||||
for exp in \
|
||||
'${line%%/\**}' \
|
||||
'${line%%"/*"*}' \
|
||||
'${line%%'"'"'/*'"'"'*}' \
|
||||
'"${line%%/\**}"' \
|
||||
'"${line%%"/*"*}"' \
|
||||
'"${line%%'"'"'/*'"'"'*}"' \
|
||||
'${line%/\**}' \
|
||||
'${line%"/*"*}' \
|
||||
'${line%'"'"'/*'"'"'*}' \
|
||||
'"${line%/\**}"' \
|
||||
'"${line%"/*"*}"' \
|
||||
'"${line%'"'"'/*'"'"'*}"'
|
||||
do
|
||||
atf_check -o inline:":$stripped:\n" -e empty ${TEST_SH} -c \
|
||||
"line='${line}'; echo :${exp}:"
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case varpattern_backslashes
|
||||
@ -103,7 +164,8 @@ varpattern_backslashes_head() {
|
||||
varpattern_backslashes_body() {
|
||||
line='/foo/bar/*/baz'
|
||||
stripped='/foo/bar/'
|
||||
atf_check_equal $stripped ${line%%\**}
|
||||
atf_check -o inline:'/foo/bar/\n' -e empty ${TEST_SH} -c \
|
||||
'line="/foo/bar/*/baz"; echo ${line%%\**}'
|
||||
}
|
||||
|
||||
atf_test_case arithmetic
|
||||
@ -114,9 +176,13 @@ arithmetic_head() {
|
||||
"this is true."
|
||||
}
|
||||
arithmetic_body() {
|
||||
atf_check_equal '3' '$((1 + 2))'
|
||||
atf_check_equal '2147483647' '$((0x7fffffff))'
|
||||
atf_check_equal '9223372036854775807' '$(((1 << 63) - 1))'
|
||||
|
||||
atf_check -o inline:'3' -e empty ${TEST_SH} -c \
|
||||
'printf %s $((1 + 2))'
|
||||
atf_check -o inline:'2147483647' -e empty ${TEST_SH} -c \
|
||||
'printf %s $((0x7fffffff))'
|
||||
atf_check -o inline:'9223372036854775807' -e empty ${TEST_SH} -c \
|
||||
'printf %s $(((1 << 63) - 1))'
|
||||
}
|
||||
|
||||
atf_test_case iteration_on_null_parameter
|
||||
@ -126,10 +192,178 @@ iteration_on_null_parameter_head() {
|
||||
"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_check -o empty -e empty ${TEST_SH} -c \
|
||||
'N=; set -- ${N}; for X; do echo "[$X]"; done'
|
||||
}
|
||||
|
||||
atf_test_case iteration_on_quoted_null_parameter
|
||||
iteration_on_quoted_null_parameter_head() {
|
||||
atf_set "descr" \
|
||||
'Check iteration of "$@" in for loop when set to null;'
|
||||
}
|
||||
iteration_on_quoted_null_parameter_body() {
|
||||
atf_check -o inline:'[]\n' -e empty ${TEST_SH} -c \
|
||||
'N=; set -- "${N}"; for X; do echo "[$X]"; done'
|
||||
}
|
||||
|
||||
atf_test_case iteration_on_null_or_null_parameter
|
||||
iteration_on_null_or_null_parameter_head() {
|
||||
atf_set "descr" \
|
||||
'Check expansion of null parameter as default for another null'
|
||||
}
|
||||
iteration_on_null_or_null_parameter_body() {
|
||||
atf_check -o empty -e empty ${TEST_SH} -c \
|
||||
'N=; E=; set -- ${N:-${E}}; for X; do echo "[$X]"; done'
|
||||
}
|
||||
|
||||
atf_test_case iteration_on_null_or_missing_parameter
|
||||
iteration_on_null_or_missing_parameter_head() {
|
||||
atf_set "descr" \
|
||||
'Check expansion of missing parameter as default for another null'
|
||||
}
|
||||
iteration_on_null_or_missing_parameter_body() {
|
||||
# atf_expect_fail 'PR bin/50834'
|
||||
atf_check -o empty -e empty ${TEST_SH} -c \
|
||||
'N=; set -- ${N:-}; for X; do echo "[$X]"; done'
|
||||
}
|
||||
|
||||
nl='
|
||||
'
|
||||
reset()
|
||||
{
|
||||
TEST_NUM=0
|
||||
TEST_FAILURES=''
|
||||
TEST_FAIL_COUNT=0
|
||||
TEST_ID="$1"
|
||||
}
|
||||
|
||||
check()
|
||||
{
|
||||
fail=false
|
||||
TEMP_FILE=$( mktemp OUT.XXXXXX )
|
||||
TEST_NUM=$(( $TEST_NUM + 1 ))
|
||||
MSG=
|
||||
|
||||
# our local shell (ATF_SHELL) better do quoting correctly...
|
||||
# some of the tests expect us to expand $nl internally...
|
||||
CMD="$1"
|
||||
|
||||
result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )"
|
||||
STATUS=$?
|
||||
|
||||
if [ "${STATUS}" -ne "$3" ]; then
|
||||
MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]"
|
||||
MSG="${MSG} expected exit code $3, got ${STATUS}"
|
||||
|
||||
# don't actually fail just because of wrong exit code
|
||||
# unless we either expected, or received "good"
|
||||
case "$3/${STATUS}" in
|
||||
(*/0|0/*) fail=true;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "$3" -eq 0 ]; then
|
||||
if [ -s "${TEMP_FILE}" ]; then
|
||||
MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]"
|
||||
MSG="${MSG} Messages produced on stderr unexpected..."
|
||||
MSG="${MSG}${nl}$( cat "${TEMP_FILE}" )"
|
||||
fail=true
|
||||
fi
|
||||
else
|
||||
if ! [ -s "${TEMP_FILE}" ]; then
|
||||
MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]"
|
||||
MSG="${MSG} Expected messages on stderr,"
|
||||
MSG="${MSG} nothing produced"
|
||||
fail=true
|
||||
fi
|
||||
fi
|
||||
rm -f "${TEMP_FILE}"
|
||||
|
||||
# Remove newlines (use local shell for this)
|
||||
oifs="$IFS"
|
||||
IFS="$nl"
|
||||
result="$(echo $result)"
|
||||
IFS="$oifs"
|
||||
if [ "$2" != "$result" ]
|
||||
then
|
||||
MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]"
|
||||
MSG="${MSG} Expected output '$2', received '$result'"
|
||||
fail=true
|
||||
fi
|
||||
|
||||
if $fail
|
||||
then
|
||||
MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]"
|
||||
MSG="${MSG} Full command: <<${CMD}>>"
|
||||
fi
|
||||
|
||||
$fail && test -n "$TEST_ID" && {
|
||||
TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+${nl}}"
|
||||
TEST_FAILURES="${TEST_FAILURES}${TEST_ID}[$TEST_NUM]:"
|
||||
TEST_FAILURES="${TEST_FAILURES} Test of '$1' failed.";
|
||||
TEST_FAILURES="${TEST_FAILURES}${nl}${MSG}"
|
||||
TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 ))
|
||||
return 0
|
||||
}
|
||||
$fail && atf_fail "Test[$TEST_NUM] of '$1' failed${nl}${MSG}"
|
||||
return 0
|
||||
}
|
||||
|
||||
results()
|
||||
{
|
||||
test -z "${TEST_ID}" && return 0
|
||||
test -z "${TEST_FAILURES}" && return 0
|
||||
|
||||
echo >&2 "=========================================="
|
||||
echo >&2 "While testing '${TEST_ID}'"
|
||||
echo >&2 " - - - - - - - - - - - - - - - - -"
|
||||
echo >&2 "${TEST_FAILURES}"
|
||||
atf_fail \
|
||||
"Test ${TEST_ID}: $TEST_FAIL_COUNT subtests (of $TEST_NUM) failed - see stderr"
|
||||
}
|
||||
|
||||
atf_test_case shell_params
|
||||
shell_params_head() {
|
||||
atf_set "descr" "Test correct operation of the numeric parameters"
|
||||
}
|
||||
shell_params_body() {
|
||||
atf_require_prog mktemp
|
||||
|
||||
reset shell_params
|
||||
|
||||
check 'set -- a b c; echo "$#: $1 $2 $3"' '3: a b c' 0
|
||||
check 'set -- a b c d e f g h i j k l m; echo "$#: ${1}0 ${10} $10"' \
|
||||
'13: a0 j a0' 0
|
||||
check 'x="$0"; set -- a b; y="$0";
|
||||
[ "x${x}y" = "x${y}y" ] && echo OK || echo x="$x" y="$y"' \
|
||||
'OK' 0
|
||||
check "${TEST_SH} -c 'echo 0=\$0 1=\$1 2=\$2' a b c" '0=a 1=b 2=c' 0
|
||||
|
||||
echo 'echo 0="$0" 1="$1" 2="$2"' > helper.sh
|
||||
check "${TEST_SH} helper.sh a b c" '0=helper.sh 1=a 2=b' 0
|
||||
|
||||
check 'set -- a bb ccc dddd eeeee ffffff ggggggg hhhhhhhh \
|
||||
iiiiiiiii jjjjjjjjjj kkkkkkkkkkk
|
||||
echo "${#}: ${#1} ${#2} ${#3} ${#4} ... ${#9} ${#10} ${#11}"' \
|
||||
'11: 1 2 3 4 ... 9 10 11' 0
|
||||
|
||||
check 'set -- a b c; echo "$#: ${1-A} ${2-B} ${3-C} ${4-D} ${5-E}"' \
|
||||
'3: a b c D E' 0
|
||||
check 'set -- a "" c "" e
|
||||
echo "$#: ${1:-A} ${2:-B} ${3:-C} ${4:-D} ${5:-E}"' \
|
||||
'5: a B c D e' 0
|
||||
check 'set -- a "" c "" e
|
||||
echo "$#: ${1:+A} ${2:+B} ${3:+C} ${4:+D} ${5:+E}"' \
|
||||
'5: A C E' 0
|
||||
check 'set -- "abab*cbb"
|
||||
echo "${1} ${1#a} ${1%b} ${1##ab} ${1%%b} ${1#*\*} ${1%\**}"' \
|
||||
'abab*cbb bab*cbb abab*cb ab*cbb abab*cb cbb abab' 0
|
||||
check 'set -- "abab?cbb"
|
||||
echo "${1}:${1#*a}+${1%b*}-${1##*a}_${1%%b*}%${1#[ab]}=${1%?*}/${1%\?*}"' \
|
||||
'abab?cbb:bab?cbb+abab?cb-b?cbb_a%bab?cbb=abab?cb/abab' 0
|
||||
check 'set -- a "" c "" e; echo "${2:=b}"' '' 1
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
@ -139,4 +373,8 @@ atf_init_test_cases() {
|
||||
atf_add_test_case varpattern_backslashes
|
||||
atf_add_test_case arithmetic
|
||||
atf_add_test_case iteration_on_null_parameter
|
||||
atf_add_test_case iteration_on_quoted_null_parameter
|
||||
atf_add_test_case iteration_on_null_or_null_parameter
|
||||
atf_add_test_case iteration_on_null_or_missing_parameter
|
||||
atf_add_test_case shell_params
|
||||
}
|
||||
|
244
dist/bin/sh/t_fsplit.sh
vendored
244
dist/bin/sh/t_fsplit.sh
vendored
@ -1,6 +1,6 @@
|
||||
# $NetBSD: t_fsplit.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
|
||||
# $NetBSD: t_fsplit.sh,v 1.4 2016/03/27 14:50:01 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
# Copyright (c) 2007-2016 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -33,22 +33,51 @@
|
||||
# the "${x-" and "}" were absent from the input line.
|
||||
#
|
||||
# So: sh -c 'set ${x-a b c}; echo $#' should give 3.
|
||||
# and: sh -c 'set -- ${x-}' echo $#' shold give 0
|
||||
#
|
||||
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
check()
|
||||
{
|
||||
result="$(eval $1)"
|
||||
TEST=$((${TEST} + 1))
|
||||
|
||||
case "$#" in
|
||||
(2) ;;
|
||||
(*) atf_fail "Internal test error, $# args to check test ${TEST}";;
|
||||
esac
|
||||
|
||||
result=$( ${TEST_SH} -c "unset x; $1" )
|
||||
STATUS="$?"
|
||||
|
||||
# Remove newlines
|
||||
oifs="$IFS"
|
||||
IFS="$nl"
|
||||
result="$(echo $result)"
|
||||
IFS="$oifs"
|
||||
|
||||
# trim the test text in case we use it in a message below
|
||||
case "$1" in
|
||||
????????????????*)
|
||||
set -- "$(expr "$1" : '\(............\).*')..." "$2" ;;
|
||||
esac
|
||||
|
||||
if [ "$2" != "$result" ]
|
||||
then
|
||||
atf_fail "expected [$2], found [$result]"
|
||||
if [ "${STATUS}" = "0" ]
|
||||
then
|
||||
atf_fail "Test ${TEST} '$1': expected [$2], found [$result]"
|
||||
else
|
||||
atf_fail \
|
||||
"TEST ${TEST} '$1' failed ($STATUS): expected [$2], found [$result]"
|
||||
fi
|
||||
elif [ "${STATUS}" != 0 ]
|
||||
then
|
||||
atf_fail "TEST ${TEST} '$1' failed ($STATUS)"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -59,6 +88,7 @@ for_head() {
|
||||
for_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# Since I managed to break this, leave the test in
|
||||
check 'for f in $x; do echo x${f}y; done' ''
|
||||
}
|
||||
@ -68,17 +98,121 @@ default_val_head() {
|
||||
atf_set "descr" "Checks field splitting in variable default values"
|
||||
}
|
||||
default_val_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# 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'
|
||||
check 'set -- ${x-a b c}; echo $#' 3
|
||||
|
||||
check 'set -- ${x-"a b" c}; echo $#' 2
|
||||
check 'set -- ${x-a "b c"}; echo $#' 2
|
||||
check 'set -- ${x-"a b c"}; echo $#' 1
|
||||
|
||||
check "set -- \${x-'a b' c}; echo \$#" 2
|
||||
check "set -- \${x-a 'b c'}; echo \$#" 2
|
||||
check "set -- \${x-'a b c'}; echo \$#" 1
|
||||
|
||||
check 'set -- ${x-a\ b c}; echo $#' 2
|
||||
check 'set -- ${x-a b\ c}; echo $#' 2
|
||||
check 'set -- ${x-a\ b\ c}; echo $#' 1
|
||||
|
||||
check 'set -- ${x}; echo $#' 0
|
||||
check 'set -- ${x-}; echo $#' 0
|
||||
check 'set -- ${x-""}; echo $#' 1
|
||||
check 'set -- ""${x}; echo $#' 1
|
||||
check 'set -- ""${x-}; echo $#' 1
|
||||
check 'set -- ""${x-""}; echo $#' 1
|
||||
check 'set -- ${x}""; echo $#' 1
|
||||
check 'set -- ${x-}""; echo $#' 1
|
||||
check 'set -- ${x-""}""; echo $#' 1
|
||||
check 'set -- ""${x}""; echo $#' 1
|
||||
check 'set -- ""${x-}""; echo $#' 1
|
||||
check 'set -- ""${x-""}""; echo $#' 1
|
||||
|
||||
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' \
|
||||
'zaz zbz zcz zdz'
|
||||
|
||||
# I am not sure these two are correct, the rules on quoting word
|
||||
# in ${var-word} are peculiar, and hard to fathom...
|
||||
# They are what the NetBSD shell does, and bash, not the freebsd shell
|
||||
# (as of Mar 1, 2016)
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
atf_test_case replacement_val
|
||||
replacement_val_head() {
|
||||
atf_set "descr" "Checks field splitting in variable replacement values"
|
||||
}
|
||||
replacement_val_body() {
|
||||
TEST=0
|
||||
|
||||
# Check that IFS is applied to text from ${x+...} unless it is inside
|
||||
# any set of "...", or whole expansion is quoted, or both...
|
||||
|
||||
check 'x=BOGUS; set -- ${x+a b c}; echo $#' 3
|
||||
|
||||
check 'x=BOGUS; set -- ${x+"a b" c}; echo $#' 2
|
||||
check 'x=BOGUS; set -- ${x+a "b c"}; echo $#' 2
|
||||
check 'x=BOGUS; set -- ${x+"a b c"}; echo $#' 1
|
||||
|
||||
check "x=BOGUS; set -- \${x+'a b' c}; echo \$#" 2
|
||||
check "x=BOGUS; set -- \${x+a 'b c'}; echo \$#" 2
|
||||
check "x=BOGUS; set -- \${x+'a b c'}; echo \$#" 1
|
||||
|
||||
check 'x=BOGUS; set -- ${x+a\ b c}; echo $#' 2
|
||||
check 'x=BOGUS; set -- ${x+a b\ c}; echo $#' 2
|
||||
check 'x=BOGUS; set -- ${x+a\ b\ c}; echo $#' 1
|
||||
|
||||
check 'x=BOGUS; set -- ${x+}; echo $#' 0
|
||||
check 'x=BOGUS; set -- ${x+""}; echo $#' 1
|
||||
check 'x=BOGUS; set -- ""${x+}; echo $#' 1
|
||||
check 'x=BOGUS; set -- ""${x+""}; echo $#' 1
|
||||
check 'x=BOGUS; set -- ${x+}""; echo $#' 1
|
||||
check 'x=BOGUS; set -- ${x+""}""; echo $#' 1
|
||||
check 'x=BOGUS; set -- ""${x+}""; echo $#' 1
|
||||
check 'x=BOGUS; set -- ""${x+""}""; echo $#' 1
|
||||
|
||||
# verify that the value of $x does not affecty the value of ${x+...}
|
||||
check 'x=BOGUS; set -- ${x+}; echo X$1' X
|
||||
check 'x=BOGUS; set -- ${x+""}; echo X$1' X
|
||||
check 'x=BOGUS; set -- ""${x+}; echo X$1' X
|
||||
check 'x=BOGUS; set -- ""${x+""}; echo X$1' X
|
||||
check 'x=BOGUS; set -- ${x+}""; echo X$1' X
|
||||
check 'x=BOGUS; set -- ${x+""}""; echo X$1' X
|
||||
check 'x=BOGUS; set -- ""${x+}""; echo X$1' X
|
||||
check 'x=BOGUS; set -- ""${x+""}""; echo X$1' X
|
||||
|
||||
check 'x=BOGUS; set -- ${x+}; echo X${1-:}X' X:X
|
||||
check 'x=BOGUS; set -- ${x+""}; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ""${x+}; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ""${x+""}; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ${x+}""; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ${x+""}""; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ""${x+}""; echo X${1-:}X' XX
|
||||
check 'x=BOGUS; set -- ""${x+""}""; echo X${1-:}X' XX
|
||||
|
||||
# and validate that the replacement can be used as expected
|
||||
check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\
|
||||
'zaz zbz zcz'
|
||||
check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\
|
||||
'za bz zcz'
|
||||
check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\
|
||||
'za b cz zdz'
|
||||
check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\
|
||||
'za b cz zdz'
|
||||
check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\
|
||||
'zaz zb cz zdz'
|
||||
check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\
|
||||
'zaz zbz zcz zdz'
|
||||
}
|
||||
|
||||
atf_test_case ifs_alpha
|
||||
@ -89,13 +223,19 @@ ifs_alpha_head() {
|
||||
ifs_alpha_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# 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'
|
||||
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
|
||||
@ -106,6 +246,7 @@ quote_head() {
|
||||
quote_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# Some quote propagation checks
|
||||
check 'set "${x-a b c}"; echo $#' 1
|
||||
check 'set "${x-"a b" c}"; echo $1' 'a b c'
|
||||
@ -120,19 +261,44 @@ dollar_at_head() {
|
||||
dollar_at_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# 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'
|
||||
|
||||
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'
|
||||
|
||||
check 'set --; for i; do echo "z${i}z"; done' ''
|
||||
check 'set --; for i in $@; do echo "z${i}z"; done' ''
|
||||
check 'set --; for i in "$@"; do echo "z${i}z"; done' ''
|
||||
# atf_expect_fail "PR bin/50834"
|
||||
check 'set --; for i in ""$@; do echo "z${i}z"; done' 'zz'
|
||||
# atf_expect_pass
|
||||
check 'set --; for i in $@""; do echo "z${i}z"; done' 'zz'
|
||||
check 'set --; for i in ""$@""; do echo "z${i}z"; done' 'zz'
|
||||
check 'set --; for i in """$@"; do echo "z${i}z"; done' 'zz'
|
||||
check 'set --; for i in "$@"""; 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'
|
||||
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 a b c; for i in "$@$@"; do echo "z${i}z"; done' \
|
||||
'zaz zbz zcaz zbz zcz'
|
||||
check 'set a b c; for i in "$@""$@";do echo "z${i}z"; done' \
|
||||
'zaz zbz zcaz zbz zcz'
|
||||
}
|
||||
|
||||
atf_test_case ifs
|
||||
@ -143,6 +309,7 @@ ifs_head() {
|
||||
ifs_body() {
|
||||
unset x
|
||||
|
||||
TEST=0
|
||||
# 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'
|
||||
@ -165,19 +332,26 @@ var_length_head() {
|
||||
"a variable's length"
|
||||
}
|
||||
var_length_body() {
|
||||
unset x
|
||||
TEST=0
|
||||
|
||||
# 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'
|
||||
export long
|
||||
|
||||
# first test that the test method works...
|
||||
check 'set -u; : ${long}; echo ${#long}' '128'
|
||||
|
||||
# Check that we apply IFS to ${#var}
|
||||
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 replacement_val
|
||||
atf_add_test_case ifs_alpha
|
||||
atf_add_test_case quote
|
||||
atf_add_test_case dollar_at
|
||||
|
536
dist/bin/sh/t_here.sh
vendored
536
dist/bin/sh/t_here.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_here.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
|
||||
# $NetBSD: t_here.sh,v 1.6 2016/03/31 16:21:52 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,50 +24,542 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
reset()
|
||||
{
|
||||
TEST_NUM=0
|
||||
TEST_FAILURES=''
|
||||
TEST_FAIL_COUNT=0
|
||||
TEST_ID="$1"
|
||||
}
|
||||
|
||||
check()
|
||||
{
|
||||
SVIFS="$IFS"
|
||||
result="$(eval $1)"
|
||||
# Remove newlines
|
||||
fail=false
|
||||
TEMP_FILE=$( mktemp OUT.XXXXXX )
|
||||
TEST_NUM=$(( $TEST_NUM + 1 ))
|
||||
|
||||
# our local shell (ATF_SHELL) better do quoting correctly...
|
||||
# some of the tests expect us to expand $nl internally...
|
||||
CMD="nl='${nl}'; $1"
|
||||
|
||||
result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )"
|
||||
STATUS=$?
|
||||
|
||||
if [ "${STATUS}" -ne "$3" ]; then
|
||||
echo >&2 "[$TEST_NUM] expected exit code $3, got ${STATUS}"
|
||||
|
||||
# don't actually fail just because of wrong exit code
|
||||
# unless we either expected, or received "good"
|
||||
case "$3/${STATUS}" in
|
||||
(*/0|0/*) fail=true;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "$3" -eq 0 ]; then
|
||||
if [ -s "${TEMP_FILE}" ]; then
|
||||
echo >&2 \
|
||||
"[$TEST_NUM] Messages produced on stderr unexpected..."
|
||||
cat "${TEMP_FILE}" >&2
|
||||
fail=true
|
||||
fi
|
||||
else
|
||||
if ! [ -s "${TEMP_FILE}" ]; then
|
||||
echo >&2 \
|
||||
"[$TEST_NUM] Expected messages on stderr, nothing produced"
|
||||
fail=true
|
||||
fi
|
||||
fi
|
||||
rm -f "${TEMP_FILE}"
|
||||
|
||||
# Remove newlines (use local shell for this)
|
||||
oifs="$IFS"
|
||||
IFS="$nl"
|
||||
result="$(echo $result)"
|
||||
IFS="$oifs"
|
||||
if [ "$2" != "$result" ]
|
||||
then
|
||||
atf_fail "expected [$2], found [$result]"
|
||||
echo >&2 "[$TEST_NUM] Expected output '$2', received '$result'"
|
||||
fail=true
|
||||
fi
|
||||
IFS="$SVIFS"
|
||||
|
||||
if $fail
|
||||
then
|
||||
echo >&2 "[$TEST_NUM] Full command: <<${CMD}>>"
|
||||
fi
|
||||
|
||||
$fail && test -n "$TEST_ID" && {
|
||||
TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+
|
||||
}${TEST_ID}[$TEST_NUM]: test of '$1' failed";
|
||||
TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 ))
|
||||
return 0
|
||||
}
|
||||
$fail && atf_fail "Test[$TEST_NUM] of '$1' failed"
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case all
|
||||
all_head() {
|
||||
results()
|
||||
{
|
||||
test -z "${TEST_ID}" && return 0
|
||||
test -z "${TEST_FAILURES}" && return 0
|
||||
|
||||
echo >&2 "=========================================="
|
||||
echo >&2 "While testing '${TEST_ID}'"
|
||||
echo >&2 " - - - - - - - - - - - - - - - - -"
|
||||
echo >&2 "${TEST_FAILURES}"
|
||||
atf_fail \
|
||||
"Test ${TEST_ID}: $TEST_FAIL_COUNT subtests (of $TEST_NUM) failed - see stderr"
|
||||
}
|
||||
|
||||
atf_test_case do_simple
|
||||
do_simple_head() {
|
||||
atf_set "descr" "Basic tests for here documents"
|
||||
}
|
||||
all_body() {
|
||||
do_simple_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'
|
||||
reset 'simple'
|
||||
IFS=' '
|
||||
check 'x=`cat <<EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0
|
||||
check 'x=`cat <<\EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0
|
||||
|
||||
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 "y=${y};"'x=`cat <<EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'text' 0
|
||||
check "y=${y};"'x=`cat <<\EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'te${y}t' 0
|
||||
check "y=${y};"'x=`cat <<"EOF"'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'te${y}t' 0
|
||||
check "y=${y};"'x=`cat <<'"'EOF'"$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'te${y}t' 0
|
||||
|
||||
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 that quotes in the here doc survive and cause no problems
|
||||
check "cat <<EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0
|
||||
check "cat <<\EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0
|
||||
check "cat <<'EOF'${nl}te'xt${nl}EOF$nl" "te'xt" 0
|
||||
check "cat <<EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
|
||||
check "cat <<\EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
|
||||
check "cat <<'EOF'${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
|
||||
check "cat <<'EO'F${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
|
||||
|
||||
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'
|
||||
check "y=${y};"'x=`cat <<EOF'$nl'te'"'"'${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'te'"'"'xt' 0
|
||||
check "y=${y};"'x=`cat <<EOF'$nl'te'"''"'${y}t'${nl}EOF$nl'`; echo $x' \
|
||||
'te'"''"'xt' 0
|
||||
|
||||
# note that the blocks of empty space in the following must
|
||||
# be entirely tab characters, no spaces.
|
||||
|
||||
check 'x=`cat <<EOF'"$nl text${nl}EOF$nl"'`; echo "$x"' \
|
||||
' text' 0
|
||||
check 'x=`cat <<-EOF'"$nl text${nl}EOF$nl"'`; echo $x' \
|
||||
'text' 0
|
||||
check 'x=`cat <<-EOF'"${nl}text${nl} EOF$nl"'`; echo $x' \
|
||||
'text' 0
|
||||
check 'x=`cat <<-\EOF'"$nl text${nl} EOF$nl"'`; echo $x' \
|
||||
'text' 0
|
||||
check 'x=`cat <<- "EOF"'"$nl text${nl}EOF$nl"'`; echo $x' \
|
||||
'text' 0
|
||||
check 'x=`cat <<- '"'EOF'${nl}text${nl} EOF$nl"'`; echo $x' \
|
||||
'text' 0
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case end_markers
|
||||
end_markers_head() {
|
||||
atf_set "descr" "Tests for various end markers of here documents"
|
||||
}
|
||||
end_markers_body() {
|
||||
|
||||
reset 'end_markers'
|
||||
for end in EOF 1 \! '$$$' "string " a\\\ a\\\ \ '&' '' ' ' ' ' \
|
||||
--STRING-- . '~~~' ')' '(' '#' '()' '(\)' '(\/)' '--' '\' '{' '}' \
|
||||
VERYVERYVERYVERYLONGLONGLONGin_fact_absurdly_LONG_LONG_HERE_DOCUMENT_TERMINATING_MARKER_THAT_goes_On_forever_and_ever_and_ever...
|
||||
do
|
||||
# check unquoted end markers
|
||||
case "${end}" in
|
||||
('' | *[' ()\$&#*~']* ) ;; # skip unquoted endmark test for these
|
||||
(*) check \
|
||||
'x=$(cat << '"${end}${nl}text${nl}${end}${nl}"'); printf %s "$x"' 'text' 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# and quoted end markers
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end}${nl}"'); printf %s "$x"' 'text' 0
|
||||
|
||||
# and see what happens if we encounter "almost" an end marker
|
||||
case "${#end}" in
|
||||
(0|1) ;; # too short to try truncation tests
|
||||
(*) check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end%?}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end%?}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end#?}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end#?}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end%?}+${nl}${end}${nl}"');printf %s "$x"' \
|
||||
"text ${end%?}+" 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# or something that is a little longer
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end}x${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}x" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}!${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text !${end}" 0
|
||||
|
||||
# or which does not begin at start of line
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl} ${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl} ${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}" 0
|
||||
|
||||
# or end at end of line
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end} ${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end} " 0
|
||||
|
||||
# or something that is correct much of the way, but then...
|
||||
|
||||
case "${#end}" in
|
||||
(0) ;; # cannot test this one
|
||||
(1) check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end}${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}${end}" 0
|
||||
;;
|
||||
(2-7) pfx="${end%?}"
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end}${pfx}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}${pfx}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${pfx}${end}" 0
|
||||
;;
|
||||
(*) pfx=${end%??????}; sfx=${end#??????}
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${end}${sfx}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${end}${sfx}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${end}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${pfx}${end}" 0
|
||||
check \
|
||||
'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${sfx}${nl}${end}${nl}"'); printf %s "$x"' \
|
||||
"text ${pfx}${sfx}" 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Add striptabs tests (in similar way) here one day...
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case incomplete
|
||||
incomplete_head() {
|
||||
atf_set "descr" "Basic tests for incomplete here documents"
|
||||
}
|
||||
incomplete_body() {
|
||||
reset incomplete
|
||||
|
||||
check 'cat <<EOF' '' 2
|
||||
check 'cat <<- EOF' '' 2
|
||||
check 'cat <<\EOF' '' 2
|
||||
check 'cat <<- \EOF' '' 2
|
||||
|
||||
check 'cat <<EOF'"${nl}" '' 2
|
||||
check 'cat <<- EOF'"${nl}" '' 2
|
||||
check 'cat <<'"'EOF'${nl}" '' 2
|
||||
check 'cat <<- "EOF"'"${nl}" '' 2
|
||||
|
||||
check 'cat << EOF'"${nl}${nl}" '' 2
|
||||
check 'cat <<-EOF'"${nl}${nl}" '' 2
|
||||
check 'cat << '"'EOF'${nl}${nl}" '' 2
|
||||
check 'cat <<-"EOF"'"${nl}${nl}" '' 2
|
||||
|
||||
check 'cat << EOF'"${nl}"'line 1'"${nl}" '' 2
|
||||
check 'cat <<-EOF'"${nl}"' line 1'"${nl}" '' 2
|
||||
check 'cat << EOF'"${nl}"'line 1'"${nl}"' line 2'"${nl}" '' 2
|
||||
check 'cat <<-EOF'"${nl}"' line 1'"${nl}"'line 2'"${nl}" '' 2
|
||||
|
||||
check 'cat << EOF'"${nl}line 1${nl}${nl}line3${nl}${nl}5!${nl}" '' 2
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case lineends
|
||||
lineends_head() {
|
||||
atf_set "descr" "Tests for line endings in here documents"
|
||||
}
|
||||
lineends_body() {
|
||||
reset lineends
|
||||
|
||||
# note that "check" removes newlines from stdout before comparing.
|
||||
# (they become blanks, provided there is something before & after)
|
||||
|
||||
check 'cat << \echo'"${nl}"'\'"${nl}echo${nl}echo${nl}" '\' 0
|
||||
check 'cat << echo'"${nl}"'\'"${nl}echo${nl}echo${nl}" 'echo' 0
|
||||
check 'cat << echo'"${nl}"'\\'"${nl}echo${nl}echo${nl}" '\' 0
|
||||
|
||||
check 'X=3; cat << ec\ho'"${nl}"'$X\'"${nl}echo${nl}echo${nl}" \
|
||||
'$X\' 0
|
||||
check 'X=3; cat << echo'"${nl}"'$X'"${nl}echo${nl}echo${nl}" \
|
||||
'3' 0
|
||||
check 'X=3; cat << echo'"${nl}"'$X\'"${nl}echo${nl}echo${nl}" \
|
||||
'' 0
|
||||
check 'X=3; cat << echo'"${nl}"'${X}\'"${nl}echo${nl}echo${nl}" \
|
||||
'3echo' 0
|
||||
check 'X=3; cat << echo'"${nl}"'\$X\'"${nl}echo${nl}echo${nl}" \
|
||||
'$Xecho' 0
|
||||
check 'X=3; cat << echo'"${nl}"'\\$X \'"${nl}echo${nl}echo${nl}" \
|
||||
'\3 echo' 0
|
||||
|
||||
check \
|
||||
'cat << "echo"'"${nl}"'line1\'"${nl}"'line2\'"${nl}echo${nl}echo${nl}" \
|
||||
'line1\ line2\' 0
|
||||
check \
|
||||
'cat << echo'"${nl}"'line1\'"${nl}"'line2\'"${nl}echo${nl}echo${nl}" \
|
||||
'line1line2echo' 0
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case multiple
|
||||
multiple_head() {
|
||||
atf_set "descr" "Tests for multiple here documents on one cmd line"
|
||||
}
|
||||
multiple_body() {
|
||||
reset multiple
|
||||
|
||||
check \
|
||||
"(cat ; cat <&3) <<EOF0 3<<EOF3${nl}STDIN${nl}EOF0${nl}-3-${nl}EOF3${nl}" \
|
||||
'STDIN -3-' 0
|
||||
|
||||
check "(read line; echo \"\$line\"; cat <<EOF1; echo \"\$line\") <<EOF2
|
||||
The File
|
||||
EOF1
|
||||
The Line
|
||||
EOF2
|
||||
" 'The Line The File The Line' 0
|
||||
|
||||
check "(read line; echo \"\$line\"; cat <<EOF; echo \"\$line\") <<EOF
|
||||
The File
|
||||
EOF
|
||||
The Line
|
||||
EOF
|
||||
" 'The Line The File The Line' 0
|
||||
|
||||
check "V=1; W=2; cat <<-1; cat <<2; cat <<- 3; cat <<'4';"' cat <<\5
|
||||
$V
|
||||
$W
|
||||
3
|
||||
4
|
||||
5
|
||||
1
|
||||
2
|
||||
5
|
||||
4*$W+\$V
|
||||
3
|
||||
$W
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
7+$V
|
||||
$W+6
|
||||
5
|
||||
' '1 2 3 4 5 5 4*2+$V $W 1 2 3 7+$V $W+6' 0
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case nested
|
||||
nested_head() {
|
||||
atf_set "descr" "Tests for nested here documents for one cmd"
|
||||
}
|
||||
nested_body() {
|
||||
reset nested
|
||||
|
||||
check \
|
||||
'cat << EOF1'"${nl}"'$(cat << EOF2'"${nl}LINE${nl}EOF2${nl}"')'"${nl}EOF1${nl}"\
|
||||
'LINE' 0
|
||||
|
||||
# This next one fails ... and correctly, so we will omit it (bad test)
|
||||
# Reasoning is that the correct data "$(cat << EOF2)\nLINE\nEOF2\n" is
|
||||
# collected for the outer (EOF1) heredoc, when that is parsed, it looks
|
||||
# like
|
||||
# $(cat <<EOF2)
|
||||
# LINE
|
||||
# EOF2
|
||||
# which looks like a good command - except it is being parsed in "heredoc"
|
||||
# syntax, which means it is enclosed in double quotes, which means that
|
||||
# the newline after the ')' in the first line is not a newline token, but
|
||||
# just a character. The EOF2 heredoc cannot start until after the next
|
||||
# newline token, of which there are none here... LINE and EOF2 are just
|
||||
# more data in the outer EOF1 heredoc for its "cat" command to read & write.
|
||||
#
|
||||
# The previous sub-test works because there the \n comes inside the
|
||||
# $( ), and in there, the outside quoting rules are suspended, and it
|
||||
# all starts again - so that \n is a newline token, and the EOF2 heredoc
|
||||
# is processed.
|
||||
#
|
||||
# check \
|
||||
# 'cat << EOF1'"${nl}"'$(cat << EOF2 )'"${nl}LINE${nl}EOF2${nl}EOF1${nl}" \
|
||||
# 'LINE' 0
|
||||
|
||||
L='cat << EOF1'"${nl}"'LINE1$(cat << EOF2'"${nl}"
|
||||
L="${L}"'LINE2$(cat << EOF3'"${nl}"
|
||||
L="${L}"'LINE3$(cat << EOF4'"${nl}"
|
||||
L="${L}"'LINE4$(cat << EOF5'"${nl}"
|
||||
L="${L}LINE5${nl}EOF5${nl})4${nl}EOF4${nl})3${nl}"
|
||||
L="${L}EOF3${nl})2${nl}EOF2${nl})1${nl}EOF1${nl}"
|
||||
|
||||
# That mess is ...
|
||||
#
|
||||
# cat <<EOF1
|
||||
# LINE1$(cat << EOF2
|
||||
# LINE2$(cat << EOF3
|
||||
# LINE3$(cat << EOF4
|
||||
# LINE4$(cat << EOF5
|
||||
# LINE5
|
||||
# EOF5
|
||||
# )4
|
||||
# EOF4
|
||||
# )3
|
||||
# EOF3
|
||||
# )2
|
||||
# EOF2
|
||||
# )1
|
||||
# EOF1
|
||||
|
||||
check "${L}" 'LINE1LINE2LINE3LINE4LINE54321' 0
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case quoting
|
||||
quoting_head() {
|
||||
atf_set "descr" "Tests for use of quotes inside here documents"
|
||||
}
|
||||
quoting_body() {
|
||||
reset quoting
|
||||
|
||||
check 'X=!; cat <<- E\0F
|
||||
<'\''"'\'' \\$X\$X "'\''" \\>
|
||||
E0F
|
||||
' '<'\''"'\'' \\$X\$X "'\''" \\>' 0
|
||||
|
||||
check 'X=!; cat <<- E0F
|
||||
<'\''"'\'' \\$X\$X "'\''" \\>
|
||||
E0F
|
||||
' '<'\''"'\'' \!$X "'\''" \>' 0
|
||||
|
||||
check 'cat <<- END
|
||||
$( echo "'\''" ) $( echo '\''"'\'' ) $( echo \\ )
|
||||
END
|
||||
' "' \" \\" 0
|
||||
|
||||
check 'X=12345; Y="string1 line1?-line2"; Z=; unset W; cat <<-EOF
|
||||
${#X}${Z:-${Y}}${W+junk}${Y%%l*}${Y#*\?}
|
||||
"$Z"'\''$W'\'' ${Y%" "*} $(( X + 54321 ))
|
||||
EOF
|
||||
' '5string1 line1?-line2string1 -line2 ""'\'\'' string1 66666' 0
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
atf_test_case side_effects
|
||||
side_effects_head() {
|
||||
atf_set "descr" "Tests how side effects in here documents are handled"
|
||||
}
|
||||
side_effects_body() {
|
||||
|
||||
atf_check -s exit:0 -o inline:'2\n1\n' -e empty ${TEST_SH} -c '
|
||||
unset X
|
||||
cat <<-EOF
|
||||
${X=2}
|
||||
EOF
|
||||
echo "${X-1}"
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case vicious
|
||||
vicious_head() {
|
||||
atf_set "descr" "Tests for obscure and obnoxious uses of here docs"
|
||||
}
|
||||
vicious_body() {
|
||||
reset
|
||||
|
||||
cat <<- \END_SCRIPT > script
|
||||
cat <<ONE && cat \
|
||||
<<TWO
|
||||
a
|
||||
ONE
|
||||
b
|
||||
TWO
|
||||
END_SCRIPT
|
||||
|
||||
atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} script
|
||||
|
||||
# This next one is causing discussion currently (late Feb 2016)
|
||||
# amongst stds writers & implementors. Consequently we
|
||||
# will not check what it produces. The eventual result
|
||||
# seems unlikely to be what we currently output, which
|
||||
# is:
|
||||
# A:echo line 1
|
||||
# B:echo line 2)" && prefix DASH_CODE <<DASH_CODE
|
||||
# B:echo line 3
|
||||
# line 4
|
||||
# line 5
|
||||
#
|
||||
# The likely intended output is ...
|
||||
#
|
||||
# A:echo line 3
|
||||
# B:echo line 1
|
||||
# line 2
|
||||
# DASH_CODE:echo line 4)"
|
||||
# DASH_CODE:echo line 5
|
||||
#
|
||||
# The difference is explained by differing opinions on just
|
||||
# when processing of a here doc should start
|
||||
|
||||
cat <<- \END_SCRIPT > script
|
||||
prefix() { sed -e "s/^/$1:/"; }
|
||||
DASH_CODE() { :; }
|
||||
|
||||
prefix A <<XXX && echo "$(prefix B <<XXX
|
||||
echo line 1
|
||||
XXX
|
||||
echo line 2)" && prefix DASH_CODE <<DASH_CODE
|
||||
echo line 3
|
||||
XXX
|
||||
echo line 4)"
|
||||
echo line 5
|
||||
DASH_CODE
|
||||
END_SCRIPT
|
||||
|
||||
# we will just verify that the shell can parse the
|
||||
# script somehow, and doesn't fall over completely...
|
||||
|
||||
atf_check -s exit:0 -o ignore -e empty ${TEST_SH} script
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case all
|
||||
atf_add_test_case do_simple # not worthy of a comment
|
||||
atf_add_test_case end_markers # the mundane, the weird, the bizarre
|
||||
atf_add_test_case incomplete # where the end marker isn't...
|
||||
atf_add_test_case lineends # test weird line endings in heredocs
|
||||
atf_add_test_case multiple # multiple << operators on one cmd
|
||||
atf_add_test_case nested # here docs inside here docs
|
||||
atf_add_test_case quoting # stuff quoted inside
|
||||
atf_add_test_case side_effects # here docs that modify environment
|
||||
atf_add_test_case vicious # evil test from the austin-l list...
|
||||
}
|
||||
|
674
dist/bin/sh/t_option.sh
vendored
Executable file
674
dist/bin/sh/t_option.sh
vendored
Executable file
@ -0,0 +1,674 @@
|
||||
# $NetBSD: t_option.sh,v 1.3 2016/03/08 14:19:28 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2016 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
# The standard
|
||||
# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
|
||||
# says:
|
||||
# ...[lots]
|
||||
|
||||
test_option_on_off()
|
||||
{
|
||||
atf_require_prog tr
|
||||
|
||||
for opt
|
||||
do
|
||||
# t is needed, as inside $()` $- appears to lose
|
||||
# the 'e' option if it happened to already be
|
||||
# set. Must check if that is what should
|
||||
# happen, but that is a different issue.
|
||||
|
||||
test -z "${opt}" && continue
|
||||
|
||||
# if we are playing with more that one option at a
|
||||
# time, the code below requires that we start with no
|
||||
# options set, or it will mis-diagnose the situation
|
||||
CLEAR=''
|
||||
test "${#opt}" -gt 1 &&
|
||||
CLEAR='xx="$-" && xx=$(echo "$xx" | tr -d cs) && test -n "$xx" && set +"$xx";'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
"opt=${opt}"'
|
||||
x() {
|
||||
echo "ERROR: Unable to $1 option $2" >&2
|
||||
exit 1
|
||||
}
|
||||
s() {
|
||||
set -"$1"
|
||||
t="$-"
|
||||
x=$(echo "$t" | tr -d "$1")
|
||||
test "$t" = "$x" && x set "$1"
|
||||
return 0
|
||||
}
|
||||
c() {
|
||||
set +"$1"
|
||||
t="$-"
|
||||
x=$(echo "$t" | tr -d "$1")
|
||||
test "$t" != "$x" && x clear "$1"
|
||||
return 0
|
||||
}
|
||||
'"${CLEAR}"'
|
||||
|
||||
# if we do not do this, -x tracing splatters stderr
|
||||
# for some shells, -v does as well (is that correct?)
|
||||
case "${opt}" in
|
||||
(*[xv]*) exec 2>/dev/null;;
|
||||
esac
|
||||
|
||||
o="$-"
|
||||
x=$(echo "$o" | tr -d "$opt")
|
||||
|
||||
if [ "$o" = "$x" ]; then # option was off
|
||||
s "${opt}"
|
||||
c "${opt}"
|
||||
else
|
||||
c "${opt}"
|
||||
s "${opt}"
|
||||
fi
|
||||
'
|
||||
done
|
||||
}
|
||||
|
||||
test_optional_on_off()
|
||||
{
|
||||
RET=0
|
||||
OPTS=
|
||||
for opt
|
||||
do
|
||||
test "${opt}" = n && continue
|
||||
${TEST_SH} -c "set -${opt}" 2>/dev/null &&
|
||||
OPTS="${OPTS} ${opt}" || RET=1
|
||||
done
|
||||
|
||||
test -n "${OPTS}" && test_option_on_off ${OPTS}
|
||||
|
||||
return "${RET}"
|
||||
}
|
||||
|
||||
atf_test_case set_a
|
||||
set_a_head() {
|
||||
atf_set "descr" "Tests that 'set -a' turns on all var export " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_a_body() {
|
||||
atf_require_prog env
|
||||
atf_require_prog grep
|
||||
|
||||
test_option_on_off a
|
||||
|
||||
# without -a, new variables should not be exported (so grep "fails")
|
||||
atf_check -s exit:1 -o empty -e empty ${TEST_SH} -ce \
|
||||
'unset VAR; set +a; VAR=value; env | grep "^VAR="'
|
||||
|
||||
# with -a, they should be
|
||||
atf_check -s exit:0 -o match:VAR=value -e empty ${TEST_SH} -ce \
|
||||
'unset VAR; set -a; VAR=value; env | grep "^VAR="'
|
||||
}
|
||||
|
||||
atf_test_case set_C
|
||||
set_C_head() {
|
||||
atf_set "descr" "Tests that 'set -C' turns on no clobber mode " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_C_body() {
|
||||
atf_require_prog ls
|
||||
|
||||
test_option_on_off C
|
||||
|
||||
# Check that the environment to use for the tests is sane ...
|
||||
# we assume current dir is a new tempory directory & is empty
|
||||
|
||||
test -z "$(ls)" || atf_skip "Test execution directory not clean"
|
||||
test -c "/dev/null" || atf_skip "Problem with /dev/null"
|
||||
|
||||
echo Dummy_Content > Junk_File
|
||||
echo Precious_Content > Important_File
|
||||
|
||||
# Check that we can redirect onto file when -C is not set
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'
|
||||
D=$(ls -l Junk_File) || exit 1
|
||||
set +C
|
||||
echo "Overwrite it now" > Junk_File
|
||||
A=$(ls -l Junk_File) || exit 1
|
||||
test "${A}" != "${D}"
|
||||
'
|
||||
|
||||
# Check that we cannot redirect onto file when -C is set
|
||||
atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'
|
||||
D=$(ls -l Important_File) || exit 1
|
||||
set -C
|
||||
echo "Fail to Overwrite it now" > Important_File
|
||||
A=$(ls -l Important_File) || exit 1
|
||||
test "${A}" = "${D}"
|
||||
'
|
||||
|
||||
# Check that we can append to file, even when -C is set
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'
|
||||
D=$(ls -l Junk_File) || exit 1
|
||||
set -C
|
||||
echo "Append to it now" >> Junk_File
|
||||
A=$(ls -l Junk_File) || exit 1
|
||||
test "${A}" != "${D}"
|
||||
'
|
||||
|
||||
# Check that we abort on attempt to redirect onto file when -Ce is set
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'
|
||||
set -Ce
|
||||
echo "Fail to Overwrite it now" > Important_File
|
||||
echo "Should not reach this point"
|
||||
'
|
||||
|
||||
# Last check that we can override -C for when we really need to
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'
|
||||
D=$(ls -l Junk_File) || exit 1
|
||||
set -C
|
||||
echo "Change the poor bugger again" >| Junk_File
|
||||
A=$(ls -l Junk_File) || exit 1
|
||||
test "${A}" != "${D}"
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case set_e
|
||||
set_e_head() {
|
||||
atf_set "descr" "Tests that 'set -e' turns on error detection " \
|
||||
"and that a simple case behaves as defined by the standard"
|
||||
}
|
||||
set_e_body() {
|
||||
test_option_on_off e
|
||||
|
||||
# Check that -e does nothing if no commands fail
|
||||
atf_check -s exit:0 -o match:I_am_OK -e empty \
|
||||
${TEST_SH} -c \
|
||||
'false; printf "%s" I_am; set -e; true; printf "%s\n" _OK'
|
||||
|
||||
# and that it (silently, but with exit status) aborts if cmd fails
|
||||
atf_check -s not-exit:0 -o match:I_am -o not-match:Broken -e empty \
|
||||
${TEST_SH} -c \
|
||||
'false; printf "%s" I_am; set -e; false; printf "%s\n" _Broken'
|
||||
|
||||
# same, except -e this time is on from the beginning
|
||||
atf_check -s not-exit:0 -o match:I_am -o not-match:Broken -e empty \
|
||||
${TEST_SH} -ec 'printf "%s" I_am; false; printf "%s\n" _Broken'
|
||||
|
||||
# More checking of -e in other places, there is lots to deal with.
|
||||
}
|
||||
|
||||
atf_test_case set_f
|
||||
set_f_head() {
|
||||
atf_set "descr" "Tests that 'set -f' turns off pathname expansion " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_f_body() {
|
||||
atf_require_prog ls
|
||||
|
||||
test_option_on_off f
|
||||
|
||||
# Check that the environment to use for the tests is sane ...
|
||||
# we assume current dir is a new tempory directory & is empty
|
||||
|
||||
test -z "$(ls)" || atf_skip "Test execution directory not clean"
|
||||
|
||||
# we will assume that atf will clean up this junk directory
|
||||
# when we are done. But for testing pathname expansion
|
||||
# we need files
|
||||
|
||||
for f in a b c d e f aa ab ac ad ae aaa aab aac aad aba abc bbb ccc
|
||||
do
|
||||
echo "$f" > "$f"
|
||||
done
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -ec \
|
||||
'X=$(echo b*); Y=$(echo b*); test "${X}" != "a*";
|
||||
test "${X}" = "${Y}"'
|
||||
|
||||
# now test expansion is different when -f is set
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -ec \
|
||||
'X=$(echo b*); Y=$(set -f; echo b*); test "${X}" != "${Y}"'
|
||||
}
|
||||
|
||||
atf_test_case set_n
|
||||
set_n_head() {
|
||||
atf_set "descr" "Tests that 'set -n' supresses command execution " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_n_body() {
|
||||
# pointless to test this, if it turns on, it stays on...
|
||||
# test_option_on_off n
|
||||
# so just allow the tests below to verify it can be turned on
|
||||
|
||||
# nothing should be executed, hence no output...
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -enc 'echo ABANDON HOPE; echo ALL YE; echo ...'
|
||||
|
||||
# this is true even when the "commands" do not exist
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -enc 'ERR; FAIL; ABANDON HOPE'
|
||||
|
||||
# but if there is a syntax error, it should be detected (w or w/o -e)
|
||||
atf_check -s not-exit:0 -o empty -e not-empty \
|
||||
${TEST_SH} -enc 'echo JUMP; for frogs swim; echo in puddles'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty \
|
||||
${TEST_SH} -nc 'echo ABANDON HOPE; echo "ALL YE; echo ...'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty \
|
||||
${TEST_SH} -enc 'echo ABANDON HOPE;; echo ALL YE; echo ...'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty \
|
||||
${TEST_SH} -nc 'do YOU ABANDON HOPE; for all eternity?'
|
||||
|
||||
# now test enabling -n in the middle of a script
|
||||
# note that once turned on, it cannot be turned off again.
|
||||
#
|
||||
# omit more complex cases, as those can send some shells
|
||||
# into infinite loops, and believe it or not, that might be OK!
|
||||
|
||||
atf_check -s exit:0 -o match:first -o not-match:second -e empty \
|
||||
${TEST_SH} -c 'echo first; set -n; echo second'
|
||||
atf_check -s exit:0 -o match:first -o not-match:third -e empty \
|
||||
${TEST_SH} -c 'echo first; set -n; echo second; set +n; echo third'
|
||||
atf_check -s exit:0 -o inline:'a\nb\n' -e empty \
|
||||
${TEST_SH} -c 'for x in a b c d
|
||||
do
|
||||
case "$x" in
|
||||
a);; b);; c) set -n;; d);;
|
||||
esac
|
||||
printf "%s\n" "$x"
|
||||
done'
|
||||
|
||||
# This last one is a bit more complex to explain, so I will not try
|
||||
|
||||
# First, we need to know what signal number is used for SIGUSR1 on
|
||||
# the local (testing) system (signal number is $(( $XIT - 128 )) )
|
||||
|
||||
# this will take slightly over 1 second elapsed time (the sleep 1)
|
||||
# The "10" for the first sleep just needs to be something big enough
|
||||
# that the rest of the commands have time to complete, even on
|
||||
# very slow testing systems. 10 should be enough. Otherwise irrelevant
|
||||
|
||||
# The shell will usually blather to stderr about the sleep 10 being
|
||||
# killed, but it affects nothing, so just allow it to cry.
|
||||
|
||||
(sleep 10 & sleep 1; kill -USR1 $!; wait $!)
|
||||
XIT="$?"
|
||||
|
||||
# The exit value should be an integer > 128 and < 256 (often 158)
|
||||
# If it is not just skip the test
|
||||
|
||||
# If we do run the test, it should take (slightly over) either 1 or 2
|
||||
# seconds to complete, depending upon the shell being tested.
|
||||
|
||||
case "${XIT}" in
|
||||
( 129 | 1[3-9][0-9] | 2[0-4][0-9] | 25[0-5] )
|
||||
|
||||
# The script below should exit with the same code - no output
|
||||
|
||||
# Or that is the result that seems best explanable.
|
||||
# "set -n" in uses like this is not exactly well defined...
|
||||
|
||||
# This script comes from a member of the austin group
|
||||
# (they author changes to the posix shell spec - and more.)
|
||||
# The author is also an (occasional?) NetBSD user.
|
||||
atf_check -s exit:${XIT} -o empty -e empty ${TEST_SH} -c '
|
||||
trap "set -n" USR1
|
||||
{ sleep 1; kill -USR1 $$; sleep 1; } &
|
||||
false
|
||||
wait && echo t || echo f
|
||||
wait
|
||||
echo foo
|
||||
'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
atf_test_case set_u
|
||||
set_u_head() {
|
||||
atf_set "descr" "Tests that 'set -u' turns on unset var detection " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_u_body() {
|
||||
test_option_on_off u
|
||||
|
||||
# first make sure it is OK to unset an unset variable
|
||||
atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \
|
||||
'unset _UNSET_VARIABLE_; echo OK'
|
||||
# even if -u is set
|
||||
atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -cue \
|
||||
'unset _UNSET_VARIABLE_; echo OK'
|
||||
|
||||
# and that without -u accessing an unset variable is harmless
|
||||
atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \
|
||||
'unset X; echo ${X}; echo OK'
|
||||
# and that the unset variable test expansion works properly
|
||||
atf_check -s exit:0 -o match:OKOK -e empty ${TEST_SH} -ce \
|
||||
'unset X; printf "%s" ${X-OK}; echo OK'
|
||||
|
||||
# Next test that with -u set, the shell aborts on access to unset var
|
||||
# do not use -e, want to make sure it is -u that causes abort
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \
|
||||
'unset X; set -u; echo ${X}; echo ERR'
|
||||
# quoting should make no difference...
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \
|
||||
'unset X; set -u; echo "${X}"; echo ERR'
|
||||
|
||||
# Now a bunch of accesses to unset vars, with -u, in ways that are OK
|
||||
atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \
|
||||
'unset X; set -u; echo ${X-GOOD}; echo OK'
|
||||
atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \
|
||||
'unset X; set -u; echo ${X-OK}'
|
||||
atf_check -s exit:0 -o not-match:ERR -o match:OK -e empty \
|
||||
${TEST_SH} -ce 'unset X; set -u; echo ${X+ERR}; echo OK'
|
||||
|
||||
# and some more ways that are not OK
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \
|
||||
'unset X; set -u; echo ${X#foo}; echo ERR'
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \
|
||||
'unset X; set -u; echo ${X%%bar}; echo ERR'
|
||||
|
||||
# lastly, just while we are checking unset vars, test aborts w/o -u
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \
|
||||
'unset X; echo ${X?}; echo ERR'
|
||||
atf_check -s not-exit:0 -o not-match:ERR -e match:X_NOT_SET \
|
||||
${TEST_SH} -c 'unset X; echo ${X?X_NOT_SET}; echo ERR'
|
||||
}
|
||||
|
||||
atf_test_case set_v
|
||||
set_v_head() {
|
||||
atf_set "descr" "Tests that 'set -v' turns on input read echoing " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_v_body() {
|
||||
test_option_on_off v
|
||||
|
||||
# check that -v does nothing if no later input line is read
|
||||
atf_check -s exit:0 \
|
||||
-o match:OKOK -o not-match:echo -o not-match:printf \
|
||||
-e empty \
|
||||
${TEST_SH} -ec 'printf "%s" OK; set -v; echo OK; exit 0'
|
||||
|
||||
# but that it does when there are multiple lines
|
||||
cat <<- 'EOF' |
|
||||
set -v
|
||||
printf %s OK
|
||||
echo OK
|
||||
exit 0
|
||||
EOF
|
||||
atf_check -s exit:0 \
|
||||
-o match:OKOK -o not-match:echo -o not-match:printf \
|
||||
-e match:printf -e match:OK -e match:echo \
|
||||
-e not-match:set ${TEST_SH}
|
||||
|
||||
# and that it can be disabled again
|
||||
cat <<- 'EOF' |
|
||||
set -v
|
||||
printf %s OK
|
||||
set +v
|
||||
echo OK
|
||||
exit 0
|
||||
EOF
|
||||
atf_check -s exit:0 \
|
||||
-o match:OKOK -o not-match:echo -o not-match:printf \
|
||||
-e match:printf -e match:OK -e not-match:echo \
|
||||
${TEST_SH}
|
||||
|
||||
# and lastly, that shell keywords do get output when "read"
|
||||
cat <<- 'EOF' |
|
||||
set -v
|
||||
for i in 111 222 333
|
||||
do
|
||||
printf %s $i
|
||||
done
|
||||
exit 0
|
||||
EOF
|
||||
atf_check -s exit:0 \
|
||||
-o match:111222333 -o not-match:printf \
|
||||
-o not-match:for -o not-match:do -o not-match:done \
|
||||
-e match:printf -e match:111 -e not-match:111222 \
|
||||
-e match:for -e match:do -e match:done \
|
||||
${TEST_SH}
|
||||
}
|
||||
|
||||
atf_test_case set_x
|
||||
set_x_head() {
|
||||
atf_set "descr" "Tests that 'set -x' turns on command exec logging " \
|
||||
"and that it behaves as defined by the standard"
|
||||
}
|
||||
set_x_body() {
|
||||
test_option_on_off x
|
||||
|
||||
# check that cmd output appears after -x is enabled
|
||||
atf_check -s exit:0 \
|
||||
-o match:OKOK -o not-match:echo -o not-match:printf \
|
||||
-e not-match:printf -e match:OK -e match:echo \
|
||||
${TEST_SH} -ec 'printf "%s" OK; set -x; echo OK; exit 0'
|
||||
|
||||
# and that it stops again afer -x is disabled
|
||||
atf_check -s exit:0 \
|
||||
-o match:OKOK -o not-match:echo -o not-match:printf \
|
||||
-e match:printf -e match:OK -e not-match:echo \
|
||||
${TEST_SH} -ec 'set -x; printf "%s" OK; set +x; echo OK; exit 0'
|
||||
|
||||
# also check that PS4 is output correctly
|
||||
atf_check -s exit:0 \
|
||||
-o match:OK -o not-match:echo \
|
||||
-e match:OK -e match:Run:echo \
|
||||
${TEST_SH} -ec 'PS4=Run:; set -x; echo OK; exit 0'
|
||||
|
||||
return 0
|
||||
|
||||
# This one seems controversial... I suspect it is NetBSD's sh
|
||||
# that is wrong to not output "for" "while" "if" ... etc
|
||||
|
||||
# and lastly, that shell keywords do not get output when "executed"
|
||||
atf_check -s exit:0 \
|
||||
-o match:111222333 -o not-match:printf \
|
||||
-o not-match:for \
|
||||
-e match:printf -e match:111 -e not-match:111222 \
|
||||
-e not-match:for -e not-match:do -e not-match:done \
|
||||
${TEST_SH} -ec \
|
||||
'set -x; for i in 111 222 333; do printf "%s" $i; done; echo; exit 0'
|
||||
}
|
||||
|
||||
opt_test_setup()
|
||||
{
|
||||
test -n "$1" || { echo >&2 "Internal error"; exit 1; }
|
||||
|
||||
cat > "$1" << 'END_OF_FUNCTIONS'
|
||||
local_opt_check()
|
||||
{
|
||||
local -
|
||||
}
|
||||
|
||||
instr()
|
||||
{
|
||||
expr "$2" : "\(.*$1\)" >/dev/null
|
||||
}
|
||||
|
||||
save_opts()
|
||||
{
|
||||
local -
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
instr e "$-" && instr u "$-" && return 0
|
||||
echo ERR
|
||||
}
|
||||
|
||||
fiddle_opts()
|
||||
{
|
||||
set -e
|
||||
set -u
|
||||
|
||||
instr e "$-" && instr u "$-" && return 0
|
||||
echo ERR
|
||||
}
|
||||
|
||||
local_test()
|
||||
{
|
||||
set +eu
|
||||
|
||||
save_opts
|
||||
instr '[eu]' "$-" || printf %s "OK"
|
||||
|
||||
fiddle_opts
|
||||
instr e "$-" && instr u "$-" && printf %s "OK"
|
||||
|
||||
set +eu
|
||||
}
|
||||
END_OF_FUNCTIONS
|
||||
}
|
||||
|
||||
atf_test_case restore_local_opts
|
||||
restore_local_opts_head() {
|
||||
atf_set "descr" "Tests that 'local -' saves and restores options. " \
|
||||
"Note that "local" is a local shell addition"
|
||||
}
|
||||
restore_local_opts_body() {
|
||||
atf_require_prog cat
|
||||
atf_require_prog expr
|
||||
|
||||
FN="test-funcs.$$"
|
||||
opt_test_setup "${FN}" || atf_skip "Cannot setup test environment"
|
||||
|
||||
${TEST_SH} -ec ". './${FN}'; local_opt_check" 2>/dev/null ||
|
||||
atf_skip "sh extension 'local -' not supported by ${TEST_SH}"
|
||||
|
||||
atf_check -s exit:0 -o match:OKOK -o not-match:ERR -e empty \
|
||||
${TEST_SH} -ec ". './${FN}'; local_test"
|
||||
}
|
||||
|
||||
atf_test_case vi_emacs_VE_toggle
|
||||
vi_emacs_VE_toggle_head() {
|
||||
atf_set "descr" "Tests enabling vi disables emacs (and v.v - but why?)"\
|
||||
" Note that -V and -E are local shell additions"
|
||||
}
|
||||
vi_emacs_VE_toggle_body() {
|
||||
|
||||
test_optional_on_off V E ||
|
||||
atf_skip "One or both V & E opts unsupported by ${TEST_SH}"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '
|
||||
q() {
|
||||
eval "case \"$-\" in
|
||||
(*${2}*) return 1;;
|
||||
(*${1}*) return 0;;
|
||||
esac"
|
||||
return 1
|
||||
}
|
||||
x() {
|
||||
echo >&2 "Option set or toggle failure:" \
|
||||
" on=$1 off=$2 set=$-"
|
||||
exit 1
|
||||
}
|
||||
set -V; q V E || x V E
|
||||
set -E; q E V || x E V
|
||||
set -V; q V E || x V E
|
||||
set +EV; q "" "[VE]" || x "" VE
|
||||
exit 0
|
||||
'
|
||||
}
|
||||
|
||||
atf_test_case xx_bogus
|
||||
xx_bogus_head() {
|
||||
atf_set "descr" "Tests that attempting to set a nonsense option fails."
|
||||
}
|
||||
xx_bogus_body() {
|
||||
# Biggest problem here is picking a "nonsense option" that is
|
||||
# not implemented by any shell, anywhere. Hopefully this will do.
|
||||
|
||||
# 'set' is a special builtin, so a conforming shell should exit
|
||||
# on an arg error, and the ERR should not be printed.
|
||||
atf_check -s not-exit:0 -o empty -e not-empty \
|
||||
${TEST_SH} -c 'set -% ; echo ERR'
|
||||
}
|
||||
|
||||
atf_test_case Option_switching
|
||||
Option_switching_head() {
|
||||
atf_set "descr" "options can be enabled and disabled"
|
||||
}
|
||||
Option_switching_body() {
|
||||
|
||||
# Cannot test -m, setting it causes test shell to fail...
|
||||
# (test shell gets SIGKILL!) Wonder why ... something related to atf
|
||||
# That is, it works if just run as "sh -c 'echo $-; set -m; echo $-'"
|
||||
|
||||
# Don't bother testing toggling -n, once on, it stays on...
|
||||
# (and because the test fn refuses to allow us to try)
|
||||
|
||||
# Cannot test -o or -c here, or the extension -s
|
||||
# they can only be used, not switched
|
||||
|
||||
# these are the posix options, that all shells should implement
|
||||
test_option_on_off a b C e f h u v x # m
|
||||
|
||||
# and these are extensions that might not exist (non-fatal to test)
|
||||
# -i and -s (and -c) are posix options, but are not required to
|
||||
# be accessable via the "set" command, just the command line.
|
||||
# We allow for -i to work with set, as that makes some sense,
|
||||
# -c and -s do not.
|
||||
test_optional_on_off E i I p q V || true
|
||||
|
||||
# Also test (some) option combinations ...
|
||||
# only testing posix options here, because it is easier...
|
||||
test_option_on_off aeu vx Ca aCefux
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
# tests are run in order sort of names produces, so choose names wisely
|
||||
|
||||
# this one tests turning on/off all the mandatory. and extra flags
|
||||
atf_add_test_case Option_switching
|
||||
# and this tests the NetBSD "local -" functionality in functions.
|
||||
atf_add_test_case restore_local_opts
|
||||
|
||||
# no tests for -m (no idea how to do that one)
|
||||
# -I (no easy way to generate the EOF it ignores)
|
||||
# -i (not sure how to test that one at the minute)
|
||||
# -p (because we aren't going to run tests setuid)
|
||||
# -V/-E (too much effort, and a real test would be huge)
|
||||
# -c (because almost all the other tests test it anyway)
|
||||
# -q (because, for now, I am lazy)
|
||||
# -s (coming soon, hopefully)
|
||||
# -o (really +o: again, hopefully soon)
|
||||
# -o longname (again, just laziness, don't wait...)
|
||||
# -h/-b (because NetBSD doesn't implement them)
|
||||
atf_add_test_case set_a
|
||||
atf_add_test_case set_C
|
||||
atf_add_test_case set_e
|
||||
atf_add_test_case set_f
|
||||
atf_add_test_case set_n
|
||||
atf_add_test_case set_u
|
||||
atf_add_test_case set_v
|
||||
atf_add_test_case set_x
|
||||
|
||||
atf_add_test_case vi_emacs_VE_toggle
|
||||
atf_add_test_case xx_bogus
|
||||
}
|
903
dist/bin/sh/t_redir.sh
vendored
Executable file
903
dist/bin/sh/t_redir.sh
vendored
Executable file
@ -0,0 +1,903 @@
|
||||
# $NetBSD: t_redir.sh,v 1.9 2016/05/14 00:33:02 kre Exp $
|
||||
#
|
||||
# Copyright (c) 2016 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
# Any failures in this first test means it is not worth bothering looking
|
||||
# for causes of failures in any other tests, make this one work first.
|
||||
|
||||
# Problems with this test usually mean inadequate ATF_SHELL used for testing.
|
||||
# (though if all pass but the last, it might be a TEST_SH problem.)
|
||||
|
||||
atf_test_case basic_test_method_test
|
||||
basic_test_method_test_head()
|
||||
{
|
||||
atf_set "descr" "Tests that test method works as expected"
|
||||
}
|
||||
basic_test_method_test_body()
|
||||
{
|
||||
cat <<- 'DONE' |
|
||||
DONE
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH}
|
||||
cat <<- 'DONE' |
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:0 -e empty ${TEST_SH} -c 'wc -l'
|
||||
|
||||
cat <<- 'DONE' |
|
||||
echo hello
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:hello -e empty ${TEST_SH}
|
||||
cat <<- 'DONE' |
|
||||
echo hello
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:1 -e empty ${TEST_SH} -c 'wc -l'
|
||||
|
||||
cat <<- 'DONE' |
|
||||
echo hello\
|
||||
world
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:helloworld -e empty ${TEST_SH}
|
||||
cat <<- 'DONE' |
|
||||
echo hello\
|
||||
world
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:2 -e empty ${TEST_SH} -c 'wc -l'
|
||||
|
||||
printf '%s\n%s\n%s\n' Line1 Line2 Line3 > File
|
||||
atf_check -s exit:0 -o inline:'Line1\nLine2\nLine3\n' -e empty \
|
||||
${TEST_SH} -c 'cat File'
|
||||
|
||||
cat <<- 'DONE' |
|
||||
set -- X "" '' Y
|
||||
echo ARGS="${#}"
|
||||
echo '' -$1- -$2- -$3- -$4-
|
||||
cat <<EOF
|
||||
X=$1
|
||||
EOF
|
||||
cat <<\EOF
|
||||
Y=$4
|
||||
EOF
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:ARGS=4 -o match:'-X- -- -- -Y-' \
|
||||
-o match:X=X -o match:'Y=\$4' -e empty ${TEST_SH}
|
||||
}
|
||||
|
||||
atf_test_case do_input_redirections
|
||||
do_input_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Tests that simple input redirection works"
|
||||
}
|
||||
do_input_redirections_body()
|
||||
{
|
||||
printf '%s\n%s\n%s\nEND\n' 'First Line' 'Second Line' 'Line 3' >File
|
||||
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c 'cat < File'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c 'cat <File'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c 'cat< File'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c 'cat < "File"'
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c '< File cat'
|
||||
|
||||
ln File wc
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH} -c '< wc cat'
|
||||
|
||||
mv wc cat
|
||||
atf_check -s exit:0 -e empty -o match:4 \
|
||||
${TEST_SH} -c '< cat wc'
|
||||
|
||||
|
||||
cat <<- 'EOF' |
|
||||
for l in 1 2 3; do
|
||||
read line < File
|
||||
echo "$line"
|
||||
done
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nFirst Line\nFirst Line\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
for l in 1 2 3; do
|
||||
read line
|
||||
echo "$line"
|
||||
done <File
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
for l in 1 2 3; do
|
||||
read line < File
|
||||
echo "$line"
|
||||
done <File
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nFirst Line\nFirst Line\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
line=
|
||||
while [ "$line" != END ]; do
|
||||
read line || exit 1
|
||||
echo "$line"
|
||||
done <File
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
while :; do
|
||||
read line || exit 0
|
||||
echo "$line"
|
||||
done <File
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
l=''
|
||||
while read line < File
|
||||
do
|
||||
echo "$line"
|
||||
l="${l}x"
|
||||
[ ${#l} -ge 3 ] && break
|
||||
done
|
||||
echo DONE
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nFirst Line\nFirst Line\nDONE\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
while read line
|
||||
do
|
||||
echo "$line"
|
||||
done <File
|
||||
echo DONE
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nEND\nDONE\n' \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
l=''
|
||||
while read line
|
||||
do
|
||||
echo "$line"
|
||||
l="${l}x"
|
||||
[ ${#l} -ge 3 ] && break
|
||||
done <File
|
||||
echo DONE
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line\nSecond Line\nLine 3\nDONE\n' ${TEST_SH}
|
||||
|
||||
cat <<- 'EOF' |
|
||||
l=''
|
||||
while read line1 <File
|
||||
do
|
||||
read line2
|
||||
echo "$line1":"$line2"
|
||||
l="${l}x"
|
||||
[ ${#l} -ge 2 ] && break
|
||||
done <File
|
||||
echo DONE
|
||||
EOF
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:'First Line:First Line\nFirst Line:Second Line\nDONE\n' \
|
||||
${TEST_SH}
|
||||
}
|
||||
|
||||
atf_test_case do_output_redirections
|
||||
do_output_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Test Output redirections"
|
||||
}
|
||||
do_output_redirections_body()
|
||||
{
|
||||
nl='
|
||||
'
|
||||
T=0
|
||||
i() { T=$(expr "$T" + 1); }
|
||||
|
||||
rm -f Output 2>/dev/null || :
|
||||
test -f Output && atf_fail "Unable to remove Output file"
|
||||
#1
|
||||
i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '> Output'
|
||||
test -f Output || atf_fail "#$T: Did not make Output file"
|
||||
#2
|
||||
rm -f Output 2>/dev/null || :
|
||||
i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>> Output'
|
||||
test -f Output || atf_fail "#$T: Did not make Output file"
|
||||
#3
|
||||
rm -f Output 2>/dev/null || :
|
||||
i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>| Output'
|
||||
test -f Output || atf_fail "#$T: Did not make Output file"
|
||||
|
||||
#4
|
||||
rm -f Output 2>/dev/null || :
|
||||
i
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello >Output'
|
||||
test -s Output || atf_fail "#$T: Did not make non-empty Output file"
|
||||
test "$(cat Output)" = "Hello" ||
|
||||
atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
|
||||
#5
|
||||
i
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello>!Output'
|
||||
test -s Output || atf_fail "#$T: Did not make non-empty Output file"
|
||||
test "$(cat Output)" = "Hello" ||
|
||||
atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
|
||||
#6
|
||||
i
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Bye >>Output'
|
||||
test -s Output || atf_fail "#$T: Removed Output file"
|
||||
test "$(cat Output)" = "Hello${nl}Bye" || atf_fail \
|
||||
"#$T: Incorrect Output: Should be 'Hello\\nBye' is '$(cat Output)'"
|
||||
#7
|
||||
i; atf_check -s exit:0 -o inline:'line 1\nline 2\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
'echo line 1 > Output; echo line 2 >> Output; cat Output'
|
||||
test "$(cat Output)" = "line 1${nl}line 2" || atf_fail \
|
||||
"#$T: Incorrect Output: Should be 'line 1\\nline 2' is '$(cat Output)'"
|
||||
#8
|
||||
i; atf_check -s exit:0 -o inline:'line 2\n' -e empty \
|
||||
${TEST_SH} -c 'echo line 1 > Output; echo line 2'
|
||||
test "$(cat Output)" = "line 1" || atf_fail \
|
||||
"#$T: Incorrect Output: Should be 'line 1' is '$(cat Output)'"
|
||||
#9
|
||||
i; atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c '(echo line 1; echo line 2 > Out2) > Out1'
|
||||
test "$(cat Out1)" = "line 1" || atf_fail \
|
||||
"#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
|
||||
test "$(cat Out2)" = "line 2" || atf_fail \
|
||||
"#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
|
||||
#10
|
||||
i; atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c '{ echo line 1; echo line 2 > Out2;} > Out1'
|
||||
test "$(cat Out1)" = "line 1" || atf_fail \
|
||||
"#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
|
||||
test "$(cat Out2)" = "line 2" || atf_fail \
|
||||
"#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
|
||||
#11
|
||||
i; rm -f Out1 Out2 2>/dev/null || :
|
||||
cat <<- 'EOF' |
|
||||
for arg in 'line 1' 'line 2' 'line 3'
|
||||
do
|
||||
echo "$arg"
|
||||
echo "$arg" > Out1
|
||||
done > Out2
|
||||
EOF
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH}
|
||||
test "$(cat Out1)" = "line 3" || atf_fail \
|
||||
"#$T: Incorrect Out1: Should be 'line 3' is '$(cat Out1)'"
|
||||
test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
|
||||
"#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
|
||||
#12
|
||||
i; rm -f Out1 Out2 2>/dev/null || :
|
||||
cat <<- 'EOF' |
|
||||
for arg in 'line 1' 'line 2' 'line 3'
|
||||
do
|
||||
echo "$arg"
|
||||
echo "$arg" >> Out1
|
||||
done > Out2
|
||||
EOF
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH}
|
||||
test "$(cat Out1)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
|
||||
"#$T: Incorrect Out1: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out1)'"
|
||||
test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
|
||||
"#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
|
||||
}
|
||||
|
||||
atf_test_case fd_redirections
|
||||
fd_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Tests redirections to/from specific descriptors"
|
||||
}
|
||||
fd_redirections_body()
|
||||
{
|
||||
atf_require_prog /bin/echo
|
||||
|
||||
cat <<- 'DONE' > helper.sh
|
||||
f() {
|
||||
/bin/echo nothing "$1" >& "$1"
|
||||
}
|
||||
for n
|
||||
do
|
||||
eval "f $n $n"'> file-$n'
|
||||
done
|
||||
DONE
|
||||
cat <<- 'DONE' > reread.sh
|
||||
f() {
|
||||
(read -r var; echo "${var}") <&"$1"
|
||||
}
|
||||
for n
|
||||
do
|
||||
x=$( eval "f $n $n"'< file-$n' )
|
||||
test "${x}" = "nothing $n" || echo "$n"
|
||||
done
|
||||
DONE
|
||||
|
||||
validate()
|
||||
{
|
||||
for n
|
||||
do
|
||||
test -e "file-$n" || atf_fail "file-$n not created"
|
||||
C=$(cat file-"$n")
|
||||
test "$C" = "nothing $n" ||
|
||||
atf_fail "file-$n contains '$C' not 'nothing $n'"
|
||||
done
|
||||
}
|
||||
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} helper.sh 1 2 3 4 5 6 7 8 9
|
||||
validate 1 2 3 4 5 6 7 8 9
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} reread.sh 3 4 5 6 7 8 9
|
||||
|
||||
L=$(ulimit -n)
|
||||
if [ "$L" -ge 30 ]
|
||||
then
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} helper.sh 10 15 19 20 25 29
|
||||
validate 10 15 19 20 25 29
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} reread.sh 10 15 19 20 25 29
|
||||
fi
|
||||
if [ "$L" -ge 100 ]
|
||||
then
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} helper.sh 32 33 49 50 51 63 64 65 77 88 99
|
||||
validate 32 33 49 50 51 63 64 65 77 88 99
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} reread.sh 32 33 49 50 51 63 64 65 77 88 99
|
||||
fi
|
||||
if [ "$L" -ge 500 ]
|
||||
then
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} helper.sh 100 101 199 200 222 333 444 499
|
||||
validate 100 101 199 200 222 333 444 499
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} reread.sh 100 101 199 200 222 333 444 499
|
||||
fi
|
||||
if [ "$L" -gt 1005 ]
|
||||
then
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005
|
||||
validate 1000 1001 1002 1003 1004 1005
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} reread.sh 1000 1001 1002 1003 1004 1005
|
||||
fi
|
||||
}
|
||||
|
||||
atf_test_case local_redirections
|
||||
local_redirections_head()
|
||||
{
|
||||
atf_set "descr" \
|
||||
"Tests that exec can reassign file descriptors in the shell itself"
|
||||
}
|
||||
local_redirections_body()
|
||||
{
|
||||
cat <<- 'DONE' > helper.sh
|
||||
for f
|
||||
do
|
||||
eval "exec $f"'> file-$f'
|
||||
done
|
||||
|
||||
for f
|
||||
do
|
||||
printf '%s\n' "Hello $f" >&"$f"
|
||||
done
|
||||
|
||||
for f
|
||||
do
|
||||
eval "exec $f"'>&-'
|
||||
done
|
||||
|
||||
for f
|
||||
do
|
||||
eval "exec $f"'< file-$f'
|
||||
done
|
||||
|
||||
for f
|
||||
do
|
||||
exec <& "$f"
|
||||
read -r var || echo >&2 "No data in file-$f"
|
||||
read -r x && echo >&2 "Too much data in file-${f}: $x"
|
||||
test "${var}" = "Hello $f" ||
|
||||
echo >&2 "file-$f contains '${var}' not 'Hello $f'"
|
||||
done
|
||||
DONE
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} helper.sh 3 4 5 6 7 8 9
|
||||
|
||||
L=$(ulimit -n)
|
||||
if [ "$L" -ge 30 ]
|
||||
then
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} helper.sh 10 11 13 15 16 19 20 28 29
|
||||
fi
|
||||
if [ "$L" -ge 100 ]
|
||||
then
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} helper.sh 30 31 32 63 64 65 77 88 99
|
||||
fi
|
||||
if [ "$L" -ge 500 ]
|
||||
then
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} helper.sh 100 101 111 199 200 201 222 333 499
|
||||
fi
|
||||
if [ "$L" -ge 1005 ]
|
||||
then
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005
|
||||
fi
|
||||
}
|
||||
|
||||
atf_test_case named_fd_redirections
|
||||
named_fd_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Tests redirections to /dev/stdout (etc)"
|
||||
|
||||
}
|
||||
named_fd_redirections_body()
|
||||
{
|
||||
if test -c /dev/stdout
|
||||
then
|
||||
atf_check -s exit:0 -o inline:'OK\n' -e empty \
|
||||
${TEST_SH} -c 'echo OK >/dev/stdout'
|
||||
atf_check -s exit:0 -o inline:'OK\n' -e empty \
|
||||
${TEST_SH} -c '/bin/echo OK >/dev/stdout'
|
||||
fi
|
||||
|
||||
if test -c /dev/stdin
|
||||
then
|
||||
atf_require_prog cat
|
||||
|
||||
echo GOOD | atf_check -s exit:0 -o inline:'GOOD\n' -e empty \
|
||||
${TEST_SH} -c 'read var </dev/stdin; echo $var'
|
||||
echo GOOD | atf_check -s exit:0 -o inline:'GOOD\n' -e empty \
|
||||
${TEST_SH} -c 'cat </dev/stdin'
|
||||
fi
|
||||
|
||||
if test -c /dev/stderr
|
||||
then
|
||||
atf_check -s exit:0 -e inline:'OK\n' -o empty \
|
||||
${TEST_SH} -c 'echo OK 2>/dev/stderr >&2'
|
||||
atf_check -s exit:0 -e inline:'OK\n' -o empty \
|
||||
${TEST_SH} -c '/bin/echo OK 2>/dev/stderr >&2'
|
||||
fi
|
||||
|
||||
if test -c /dev/fd/8 && test -c /dev/fd/9
|
||||
then
|
||||
atf_check -s exit:0 -o inline:'EIGHT\n' -e empty \
|
||||
${TEST_SH} -c 'printf "%s\n" EIGHT 8>&1 >/dev/fd/8 |
|
||||
cat 9<&0 </dev/fd/9'
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case redir_in_case
|
||||
redir_in_case_head()
|
||||
{
|
||||
atf_set "descr" "Tests that sh(1) allows just redirections " \
|
||||
"in case statements. (PR bin/48631)"
|
||||
}
|
||||
redir_in_case_body()
|
||||
{
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c 'case x in (whatever) >foo;; esac'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c 'case x in (whatever) >foo 2>&1;; esac'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c 'case x in (whatever) >foo 2>&1 </dev/null;; esac'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty \
|
||||
${TEST_SH} -c 'case x in (whatever) >${somewhere};; esac'
|
||||
}
|
||||
|
||||
atf_test_case incorrect_redirections
|
||||
incorrect_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Tests that sh(1) correctly ignores non-redirections"
|
||||
}
|
||||
incorrect_redirections_body() {
|
||||
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo>'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'read foo<'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo<>'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x > '"$nl"
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'read x < '"$nl"
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x <> '"$nl"
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x >< anything'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x >>< anything'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x >|< anything'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'echo x > ; read x < /dev/null || echo bad'
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
'read x < & echo y > /dev/null; wait && echo bad'
|
||||
|
||||
rm -f Output 2>/dev/null || :
|
||||
atf_check -s exit:0 -e empty -o inline:'A Line > Output\n' \
|
||||
${TEST_SH} -c 'echo A Line \> Output'
|
||||
test -f Output && atf_file "File 'Output' appeared and should not have"
|
||||
|
||||
rm -f Output 2>/dev/null || :
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} -c 'echo A Line \>> Output'
|
||||
test -f Output || atf_file "File 'Output' not created when it should"
|
||||
test "$(cat Output)" = 'A Line >' || atf_fail \
|
||||
"Output file contains '$(cat Output)' instead of '"'A Line >'\'
|
||||
|
||||
rm -f Output \> 2>/dev/null || :
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
${TEST_SH} -c 'echo A Line >\> Output'
|
||||
test -f Output && atf_file "File 'Output' appeared and should not have"
|
||||
test -f '>' || atf_file "File '>' not created when it should"
|
||||
test "$(cat '>')" = 'A Line Output' || atf_fail \
|
||||
"Output file ('>') contains '$(cat '>')' instead of 'A Line Output'"
|
||||
}
|
||||
|
||||
# Many more tests in t_here, so here we have just rudimentary checks
|
||||
atf_test_case redir_here_doc
|
||||
redir_here_doc_head()
|
||||
{
|
||||
atf_set "descr" "Tests that sh(1) correctly processes 'here' doc " \
|
||||
"input redirections"
|
||||
}
|
||||
redir_here_doc_body()
|
||||
{
|
||||
# nb: the printf is not executed, it is data
|
||||
cat <<- 'DONE' |
|
||||
cat <<EOF
|
||||
printf '%s\n' 'hello\n'
|
||||
EOF
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:printf -o match:'hello\\n' \
|
||||
-e empty ${TEST_SH}
|
||||
}
|
||||
|
||||
atf_test_case subshell_redirections
|
||||
subshell_redirections_head()
|
||||
{
|
||||
atf_set "descr" "Tests redirection interactions between shell and " \
|
||||
"its sub-shell(s)"
|
||||
}
|
||||
subshell_redirections_body()
|
||||
{
|
||||
atf_require_prog cat
|
||||
|
||||
LIM=$(ulimit -n)
|
||||
|
||||
cat <<- 'DONE' |
|
||||
exec 6>output-file
|
||||
|
||||
( printf "hello\n" >&6 )
|
||||
|
||||
exec 8<output-file
|
||||
|
||||
( read hello <&8 ; test hello = "$hello" || echo >&2 Hello )
|
||||
|
||||
( printf "bye-bye\n" >&6 )
|
||||
|
||||
( exec 8<&- )
|
||||
read bye <&8 || echo >&2 "Closed?"
|
||||
echo Bye="$bye"
|
||||
DONE
|
||||
atf_check -s exit:0 -o match:Bye=bye-bye -e empty \
|
||||
${TEST_SH}
|
||||
|
||||
cat <<- 'DONE' |
|
||||
for arg in one-4 two-24 three-14
|
||||
do
|
||||
fd=${arg#*-}
|
||||
file=${arg%-*}
|
||||
eval "exec ${fd}>${file}"
|
||||
done
|
||||
|
||||
for arg in one-5 two-7 three-19
|
||||
do
|
||||
fd=${arg#*-}
|
||||
file=${arg%-*}
|
||||
eval "exec ${fd}<${file}"
|
||||
done
|
||||
|
||||
(
|
||||
echo line-1 >&4
|
||||
echo line-2 >&24
|
||||
echo line-3 >&14
|
||||
echo go
|
||||
) | (
|
||||
read go
|
||||
read x <&5
|
||||
read y <&7
|
||||
read z <&19
|
||||
|
||||
printf "%s\n" "${x}" "${y}" "${z}"
|
||||
)
|
||||
DONE
|
||||
atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \
|
||||
-e empty ${TEST_SH}
|
||||
|
||||
cat <<- 'DONE' |
|
||||
for arg in one-4-5 two-6-7 three-8-9 four-11-10 five-3-12
|
||||
do
|
||||
ofd=${arg##*-}
|
||||
file=${arg%-*}
|
||||
ifd=${file#*-}
|
||||
file=${file%-*}
|
||||
eval "exec ${ofd}>${file}"
|
||||
eval "exec ${ifd}<${file}"
|
||||
done
|
||||
|
||||
( ( ( echo line-1 >& 13 ) 13>&12 ) 12>&5 ) >stdout 2>errout
|
||||
( ( ( echo line-2 >& 4) 13>&12 ) 4>&7 ) >>stdout 2>>errout
|
||||
( ( ( echo line-3 >& 6) 8>&1 6>&11 >&12) 11>&9 >&7 ) >>stdout
|
||||
|
||||
( ( ( cat <&13 >&12 ) 13<&8 12>&10 ) 10>&1 8<&6 ) 6<&4
|
||||
( ( ( cat <&4 ) <&4 6<&8 8<&11 )
|
||||
<&4 4<&6 6<&8 8<&11 ) <&4 4<&6 6<&8 8<&11 11<&3
|
||||
( ( ( cat <&7 >&1 ) 7<&6 >&10 ) 10>&2 6<&8 ) 2>&1
|
||||
DONE
|
||||
atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \
|
||||
-e empty ${TEST_SH}
|
||||
}
|
||||
|
||||
atf_test_case ulimit_redirection_interaction
|
||||
ulimit_redirection_interaction_head()
|
||||
{
|
||||
atf_set "descr" "Tests interactions between redirect and ulimit -n "
|
||||
}
|
||||
ulimit_redirection_interaction_body()
|
||||
{
|
||||
atf_require_prog ls
|
||||
|
||||
cat <<- 'DONE' > helper.sh
|
||||
oLIM=$(ulimit -n)
|
||||
HRD=$(ulimit -H -n)
|
||||
test "${oLIM}" -lt "${HRD}" && ulimit -n "${HRD}"
|
||||
LIM=$(ulimit -n)
|
||||
|
||||
FDs=
|
||||
LFD=-1
|
||||
while [ ${LIM} -gt 16 ]
|
||||
do
|
||||
FD=$(( ${LIM} - 1 ))
|
||||
if [ "${FD}" -eq "${LFD}" ]; then
|
||||
echo >&2 "Infinite loop... (busted $(( )) ??)"
|
||||
exit 1
|
||||
fi
|
||||
LFD="${FD}"
|
||||
|
||||
eval "exec ${FD}"'> /dev/null'
|
||||
FDs="${FD}${FDs:+ }${FDs}"
|
||||
|
||||
(
|
||||
FD=$(( ${LIM} + 1 ))
|
||||
eval "exec ${FD}"'> /dev/null'
|
||||
echo "Reached unreachable command"
|
||||
) 2>/dev/null && echo >&2 "Opened beyond limit!"
|
||||
|
||||
(eval 'ls 2>&1 3>&1 4>&1 5>&1 '"${FD}"'>&1') >&"${FD}"
|
||||
|
||||
LIM=$(( ${LIM} / 2 ))
|
||||
ulimit -S -n "${LIM}"
|
||||
done
|
||||
|
||||
# Even though ulimit has been reduced, open fds should work
|
||||
for FD in ${FDs}
|
||||
do
|
||||
echo ${FD} in ${FDs} >&"${FD}" || exit 1
|
||||
done
|
||||
|
||||
ulimit -S -n "${oLIM}"
|
||||
|
||||
# maybe more later...
|
||||
|
||||
DONE
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} helper.sh
|
||||
}
|
||||
|
||||
atf_test_case validate_fn_redirects
|
||||
validate_fn_redirects_head()
|
||||
{
|
||||
# These test cases inspired by PR bin/48875 and the sh
|
||||
# changes that were required to fix it.
|
||||
|
||||
atf_set "descr" "Tests various redirections applied to functions " \
|
||||
"See PR bin/48875"
|
||||
}
|
||||
validate_fn_redirects_body()
|
||||
{
|
||||
cat <<- 'DONE' > f-def
|
||||
f() {
|
||||
printf '%s\n' In-Func
|
||||
}
|
||||
DONE
|
||||
|
||||
atf_check -s exit:0 -o inline:'In-Func\nsuccess1\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f ; printf '%s\n' success1"
|
||||
atf_check -s exit:0 -o inline:'success2\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f >/dev/null; printf '%s\n' success2"
|
||||
atf_check -s exit:0 -o inline:'success3\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f >&- ; printf '%s\n' success3"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nsuccess4\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f & wait; printf '%s\n' success4"
|
||||
atf_check -s exit:0 -o inline:'success5\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f >&- & wait; printf '%s\n' success5"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess6\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; f;f; printf '%s\n' success6"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess7\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; { f;f;}; printf '%s\n' success7"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess8\n' -e empty \
|
||||
${TEST_SH} -c ". ./f-def; { f;f;}& wait; printf '%s\n' success8"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nsuccess9\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./f-def; { f>/dev/null;f;}& wait; printf '%s\n' success9"
|
||||
atf_check -s exit:0 -o inline:'In-Func\nsuccess10\n' -e empty \
|
||||
${TEST_SH} -c \
|
||||
". ./f-def; { f;f>/dev/null;}& wait; printf '%s\n' success10"
|
||||
|
||||
# This one tests the issue etcupdate had with the original 48875 fix
|
||||
atf_check -s exit:0 -o inline:'Func a\nFunc b\nFunc c\n' -e empty \
|
||||
${TEST_SH} -c '
|
||||
f() {
|
||||
echo Func "$1"
|
||||
}
|
||||
exec 3<&0 4>&1
|
||||
( echo x-a; echo y-b; echo z-c ) |
|
||||
while read A
|
||||
do
|
||||
B=${A#?-}
|
||||
f "$B" <&3 >&4
|
||||
done >&2'
|
||||
|
||||
# And this tests a similar condition with that same fix
|
||||
cat <<- 'DONE' >Script
|
||||
f() {
|
||||
printf '%s' " hello $1"
|
||||
}
|
||||
exec 3>&1
|
||||
echo $( for i in a b c
|
||||
do printf '%s' @$i; f $i >&3; done >foo
|
||||
)
|
||||
printf '%s\n' foo=$(cat foo)
|
||||
DONE
|
||||
atf_check -s exit:0 -e empty \
|
||||
-o inline:' hello a hello b hello c\nfoo=@a@b@c\n' \
|
||||
${TEST_SH} Script
|
||||
|
||||
# Tests with sh reading stdin, which is not quite the same internal
|
||||
# mechanism.
|
||||
echo ". ./f-def || echo >&2 FAIL
|
||||
f
|
||||
printf '%s\n' stdin1
|
||||
"| atf_check -s exit:0 -o inline:'In-Func\nstdin1\n' -e empty ${TEST_SH}
|
||||
|
||||
echo '
|
||||
. ./f-def || echo >&2 FAIL
|
||||
f >&-
|
||||
printf "%s\n" stdin2
|
||||
' | atf_check -s exit:0 -o inline:'stdin2\n' -e empty ${TEST_SH}
|
||||
|
||||
cat <<- 'DONE' > fgh.def
|
||||
f() {
|
||||
echo -n f >&3
|
||||
sleep 4
|
||||
echo -n F >&3
|
||||
}
|
||||
g() {
|
||||
echo -n g >&3
|
||||
sleep 2
|
||||
echo -n G >&3
|
||||
}
|
||||
h() {
|
||||
echo -n h >&3
|
||||
}
|
||||
DONE
|
||||
|
||||
atf_check -s exit:0 -o inline:'fFgGh' -e empty \
|
||||
${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
|
||||
exec 3>&1
|
||||
f; g; h'
|
||||
|
||||
atf_check -s exit:0 -o inline:'fghGF' -e empty \
|
||||
${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
|
||||
exec 3>&1
|
||||
f & sleep 1; g & sleep 1; h; wait'
|
||||
|
||||
atf_check -s exit:0 -o inline:'fFgGhX Y\n' -e empty \
|
||||
${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
|
||||
exec 3>&1
|
||||
echo X $( f ; g ; h ) Y'
|
||||
|
||||
# This one is the real test for PR bin/48875. If the
|
||||
# cmdsub does not complete before f g (and h) exit,
|
||||
# then the 'F' & 'G' will precede 'X Y' in the output.
|
||||
# If the cmdsub finishes while f & g are still running,
|
||||
# then the X Y will appear before the F and G.
|
||||
# The trailing "sleep 3" is just so we catch all the
|
||||
# output (otherwise atf_check will be finished while
|
||||
# f & g are still sleeping).
|
||||
|
||||
atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty \
|
||||
${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
|
||||
exec 3>&1
|
||||
echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y
|
||||
sleep 3
|
||||
exec 4>&1 || echo FD_FAIL
|
||||
'
|
||||
|
||||
# Do the test again to verify it also all works reading stdin
|
||||
# (which is a slightly different path through the shell)
|
||||
echo '
|
||||
. ./fgh.def || echo >&2 FAIL
|
||||
exec 3>&1
|
||||
echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y
|
||||
sleep 3
|
||||
exec 4>&1 || echo FD_FAIL
|
||||
' | atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty ${TEST_SH}
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case basic_test_method_test
|
||||
atf_add_test_case do_input_redirections
|
||||
atf_add_test_case do_output_redirections
|
||||
atf_add_test_case fd_redirections
|
||||
atf_add_test_case local_redirections
|
||||
atf_add_test_case incorrect_redirections
|
||||
atf_add_test_case named_fd_redirections
|
||||
atf_add_test_case redir_here_doc
|
||||
atf_add_test_case redir_in_case
|
||||
atf_add_test_case subshell_redirections
|
||||
atf_add_test_case ulimit_redirection_interaction
|
||||
atf_add_test_case validate_fn_redirects
|
||||
}
|
178
dist/bin/sh/t_redircloexec.sh
vendored
Executable file
178
dist/bin/sh/t_redircloexec.sh
vendored
Executable file
@ -0,0 +1,178 @@
|
||||
# $NetBSD: t_redircloexec.sh,v 1.3 2016/05/15 15:44:43 kre Exp $
|
||||
#
|
||||
# Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to The NetBSD Foundation
|
||||
# by Christos Zoulas.
|
||||
#
|
||||
# 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
mkhelper() {
|
||||
name=$1
|
||||
fd=$2
|
||||
shift 2
|
||||
|
||||
echo "$@" > ./"${name}1"
|
||||
echo "echo ${name}2" ">&${fd}" > ./"${name}2"
|
||||
}
|
||||
|
||||
runhelper() {
|
||||
${TEST_SH} "./${1}1"
|
||||
}
|
||||
|
||||
cleanhelper() {
|
||||
# not really needed, atf cleans up...
|
||||
rm -f ./"${1}1" ./"${1}2" out
|
||||
}
|
||||
|
||||
atf_test_case exec_redir_closed
|
||||
exec_redir_closed_head() {
|
||||
atf_set "descr" "Tests that redirections created by exec are closed on exec"
|
||||
}
|
||||
exec_redir_closed_body() {
|
||||
|
||||
mkhelper exec 6 \
|
||||
"exec 6> out; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-"
|
||||
|
||||
atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} ./exec1
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -e ./exec1
|
||||
|
||||
mkhelper exec 9 \
|
||||
"exec 9> out; echo exec1 >&9; ${TEST_SH} exec2"
|
||||
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} ./exec1
|
||||
|
||||
mkhelper exec 8 \
|
||||
"exec 8> out; printf OK; echo exec1 >&8;" \
|
||||
"printf OK; ${TEST_SH} exec2; printf ERR"
|
||||
|
||||
atf_check -s not-exit:0 -o match:OKOK -o not-match:ERR -e not-empty \
|
||||
${TEST_SH} -e ./exec1
|
||||
|
||||
mkhelper exec 7 \
|
||||
"exec 7> out; printf OK; echo exec1 >&7;" \
|
||||
"printf OK; ${TEST_SH} exec2 || printf ERR"
|
||||
|
||||
atf_check -s exit:0 -o match:OKOKERR -e not-empty \
|
||||
${TEST_SH} ./exec1
|
||||
|
||||
cleanhelper exec
|
||||
}
|
||||
|
||||
atf_test_case exec_redir_open
|
||||
exec_redir_open_head() {
|
||||
atf_set "descr" "Tests that redirections created by exec can remain open"
|
||||
}
|
||||
exec_redir_open_body() {
|
||||
|
||||
mkhelper exec 6 \
|
||||
"exec 6> out 6>&6; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -e ./exec1
|
||||
|
||||
mkhelper exec 9 \
|
||||
"exec 9> out ; echo exec1 >&9; ${TEST_SH} exec2 9>&9"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1
|
||||
|
||||
mkhelper exec 8 \
|
||||
"exec 8> out; printf OK; exec 8>&8; echo exec1 >&8;" \
|
||||
"printf OK; ${TEST_SH} exec2; printf OK"
|
||||
|
||||
atf_check -s exit:0 -o match:OKOKOK -e empty \
|
||||
${TEST_SH} -e ./exec1
|
||||
|
||||
mkhelper exec 7 \
|
||||
"exec 7> out; printf OK; echo exec1 >&7;" \
|
||||
"printf OK; ${TEST_SH} 7>&7 exec2; printf OK"
|
||||
|
||||
atf_check -s exit:0 -o match:OKOKOK -e empty \
|
||||
${TEST_SH} -e ./exec1
|
||||
|
||||
cleanhelper exec
|
||||
}
|
||||
|
||||
atf_test_case loop_redir_open
|
||||
loop_redir_open_head() {
|
||||
atf_set "descr" "Tests that redirections in loops don't close on exec"
|
||||
}
|
||||
loop_redir_open_body() {
|
||||
mkhelper for 3 "for x in x; do ${TEST_SH} ./for2; done 3>out"
|
||||
atf_check -s exit:0 \
|
||||
-o empty \
|
||||
-e empty \
|
||||
${TEST_SH} ./for1
|
||||
cleanhelper for
|
||||
}
|
||||
|
||||
atf_test_case compound_redir_open
|
||||
compound_redir_open_head() {
|
||||
atf_set "descr" "Tests that redirections in compound statements don't close on exec"
|
||||
}
|
||||
compound_redir_open_body() {
|
||||
mkhelper comp 3 "{ ${TEST_SH} ./comp2; } 3>out"
|
||||
atf_check -s exit:0 \
|
||||
-o empty \
|
||||
-e empty \
|
||||
${TEST_SH} ./comp1
|
||||
cleanhelper comp
|
||||
}
|
||||
|
||||
atf_test_case simple_redir_open
|
||||
simple_redir_open_head() {
|
||||
atf_set "descr" "Tests that redirections in simple commands don't close on exec"
|
||||
}
|
||||
simple_redir_open_body() {
|
||||
mkhelper simp 4 "${TEST_SH} ./simp2 4>out"
|
||||
atf_check -s exit:0 \
|
||||
-o empty \
|
||||
-e empty \
|
||||
${TEST_SH} ./simp1
|
||||
cleanhelper simp
|
||||
}
|
||||
|
||||
atf_test_case subshell_redir_open
|
||||
subshell_redir_open_head() {
|
||||
atf_set "descr" "Tests that redirections on subshells don't close on exec"
|
||||
}
|
||||
subshell_redir_open_body() {
|
||||
mkhelper comp 5 "( ${TEST_SH} ./comp2; ${TEST_SH} ./comp2 ) 5>out"
|
||||
atf_check -s exit:0 \
|
||||
-o empty \
|
||||
-e empty \
|
||||
${TEST_SH} ./comp1
|
||||
cleanhelper comp
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case exec_redir_closed
|
||||
atf_add_test_case exec_redir_open
|
||||
atf_add_test_case loop_redir_open
|
||||
atf_add_test_case compound_redir_open
|
||||
atf_add_test_case simple_redir_open
|
||||
atf_add_test_case subshell_redir_open
|
||||
}
|
42
dist/bin/sh/t_set_e.sh
vendored
42
dist/bin/sh/t_set_e.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_set_e.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
|
||||
# $NetBSD: t_set_e.sh,v 1.4 2016/03/31 16:22:27 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -30,7 +30,7 @@
|
||||
# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
|
||||
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="sh"}
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
failwith()
|
||||
{
|
||||
@ -63,7 +63,7 @@ dcheck()
|
||||
# is thus important to test. (PR bin/29861)
|
||||
echeck()
|
||||
{
|
||||
check1 'eval '"'($1)'" "$2" "eval '($1)'"
|
||||
check1 'eval '"'( $1 )'" "$2" "eval '($1)'"
|
||||
}
|
||||
|
||||
atf_test_case all
|
||||
@ -81,8 +81,8 @@ all_body() {
|
||||
# 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'
|
||||
dcheck '(set -e; false; echo ERR$?); echo OK$?' 'OK1'
|
||||
echeck '(set -e; false; echo ERR$?); echo OK$?' 'OK1'
|
||||
|
||||
# these cases should be equivalent to the preceding.
|
||||
dcheck '(set -e; /nonexistent; echo ERR); echo OK' 'OK'
|
||||
@ -205,6 +205,9 @@ all_body() {
|
||||
|
||||
# According to dsl@ in PR bin/32282, () is not defined as a
|
||||
# subshell, only as a grouping operator [and a scope, I guess]
|
||||
|
||||
# (This is incorrect. () is definitely a sub-shell)
|
||||
|
||||
# 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
|
||||
@ -215,8 +218,10 @@ all_body() {
|
||||
#
|
||||
# XXX: the second set has been disabled in the name of making
|
||||
# all tests "pass".
|
||||
#
|
||||
# As they should be, they are utter nonsense.
|
||||
|
||||
# 1. error if the whole shell exits (current behavior)
|
||||
# 1. error if the whole shell exits (current correct 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)
|
||||
@ -232,29 +237,32 @@ all_body() {
|
||||
|
||||
# backquote expansion (PR bin/17514)
|
||||
|
||||
# correct
|
||||
# (in-)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
|
||||
# Not-wrong current behavior
|
||||
# the exit status of ommand substitution is ignored in most cases
|
||||
# None of these should be causing the shell to exit.
|
||||
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'
|
||||
|
||||
# This is testing one case (the case?) where the exit status is used
|
||||
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
|
||||
# correct (really just commented out incorrect nonsense)
|
||||
#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
|
||||
# not-wrong current behavior (as above)
|
||||
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'
|
||||
@ -267,11 +275,19 @@ all_body() {
|
||||
|
||||
# shift (PR bin/37493)
|
||||
# correct
|
||||
# Actually, both ways are correct, both are permitted
|
||||
#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'
|
||||
# (not-) wrong current behavior
|
||||
#dcheck '(set -e; shift || true; echo OK); echo OK' 'OK'
|
||||
#echeck '(set -e; shift || true; echo OK); echo OK' 'OK'
|
||||
|
||||
# what is wrong is this test assuming one behaviour or the other
|
||||
# (and incidentally this has nothing whatever to do with "-e",
|
||||
# the test should really be moved elsewhere...)
|
||||
# But for now, leave it here, and correct it:
|
||||
dcheck '(set -e; shift && echo OK); echo OK' 'OK'
|
||||
echeck '(set -e; shift && echo OK); echo OK' 'OK'
|
||||
|
||||
# Done.
|
||||
|
||||
|
181
dist/bin/sh/t_shift.sh
vendored
Executable file
181
dist/bin/sh/t_shift.sh
vendored
Executable file
@ -0,0 +1,181 @@
|
||||
# $NetBSD: t_shift.sh,v 1.2 2016/05/17 09:05:14 kre Exp $
|
||||
#
|
||||
# Copyright (c) 2016 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
atf_test_case basic_shift_test
|
||||
basic_shift_test_head() {
|
||||
atf_set "descr" "Test correct operation of valid shifts"
|
||||
}
|
||||
basic_shift_test_body() {
|
||||
|
||||
for a in \
|
||||
"one-arg::0:one-arg" \
|
||||
"one-arg:1:0:one-arg" \
|
||||
"one-arg:0:1 one-arg" \
|
||||
"a b c::2 b c:a" \
|
||||
"a b c:1:2 b c:a" \
|
||||
"a b c:2:1 c:a:b" \
|
||||
"a b c:3:0:a:b:c" \
|
||||
"a b c:0:3 a b c" \
|
||||
"a b c d e f g h i j k l m n o p:1:15 b c d e f g h i j k l m n o p"\
|
||||
"a b c d e f g h i j k l m n o p:9:7 j k l m n o p:a:b:c:g:h:i" \
|
||||
"a b c d e f g h i j k l m n o p:13:3 n o p:a:b:c:d:k:l:m" \
|
||||
"a b c d e f g h i j k l m n o p:16:0:a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p"
|
||||
do
|
||||
oIFS="${IFS}"
|
||||
IFS=:; set -- $a
|
||||
IFS="${oIFS}"
|
||||
|
||||
init="$1"; n="$2"; res="$3"; shift 3
|
||||
|
||||
not=
|
||||
for b
|
||||
do
|
||||
not="${not} -o not-match:$b"
|
||||
done
|
||||
|
||||
atf_check -s exit:0 -o "match:${res}" ${not} -e empty \
|
||||
${TEST_SH} -c "set -- ${init}; shift $n;"' echo "$# $*"'
|
||||
done
|
||||
|
||||
atf_check -s exit:0 -o match:complete -o not-match:ERR -e empty \
|
||||
${TEST_SH} -c \
|
||||
'set -- a b c d e;while [ $# -gt 0 ];do shift||echo ERR;done;echo complete'
|
||||
}
|
||||
|
||||
atf_test_case excessive_shift
|
||||
excessive_shift_head() {
|
||||
atf_set "descr" "Test acceptable operation of shift too many"
|
||||
}
|
||||
# In:
|
||||
#
|
||||
# http://pubs.opengroup.org/onlinepubs/9699919799
|
||||
# /utilities/V3_chap02.html#tag_18_26_01
|
||||
#
|
||||
# (that URL should be one line, with the /util... immediately after ...9799)
|
||||
#
|
||||
# POSIX says of shift (in the "EXIT STATUS" paragraph):
|
||||
#
|
||||
# If the n operand is invalid or is greater than "$#", this may be considered
|
||||
# a syntax error and a non-interactive shell may exit; if the shell does not
|
||||
# exit in this case, a non-zero exit status shall be returned.
|
||||
# Otherwise, zero shall be returned.
|
||||
#
|
||||
# NetBSD's sh treats it as an error and exits (if non-interactive, as here),
|
||||
# other shells do not.
|
||||
#
|
||||
# Either behaviour is acceptable - so the test allows for both
|
||||
# (and checks that if the shell does not exit, "shift" returns status != 0)
|
||||
|
||||
excessive_shift_body() {
|
||||
for a in \
|
||||
"one-arg:2" \
|
||||
"one-arg:4" \
|
||||
"one-arg:13" \
|
||||
"one two:3" \
|
||||
"one two:7" \
|
||||
"one two three four five:6" \
|
||||
"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:16" \
|
||||
"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:17" \
|
||||
"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:30" \
|
||||
"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:9999"
|
||||
do
|
||||
oIFS="${IFS}"
|
||||
IFS=:; set -- $a
|
||||
IFS="${oIFS}"
|
||||
|
||||
atf_check -s not-exit:0 -o match:OK -o not-match:ERR \
|
||||
-e ignore ${TEST_SH} -c \
|
||||
"set -- $1 ;"'echo OK:$#-'"$2;shift $2 && echo ERR"
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case function_shift
|
||||
function_shift_head() {
|
||||
atf_set "descr" "Test that shift in a function does not affect outside"
|
||||
}
|
||||
function_shift_body() {
|
||||
: # later...
|
||||
}
|
||||
|
||||
atf_test_case non_numeric_shift
|
||||
non_numeric_shift_head() {
|
||||
atf_set "descr" "Test that non-numeric args to shift are detected"
|
||||
}
|
||||
|
||||
# from the DESCRIPTION section at the URL mentioned with the excessive_shift
|
||||
# test:
|
||||
#
|
||||
# The value n shall be an unsigned decimal integer ...
|
||||
#
|
||||
# That is not hex (octal will be treated as if it were decimal, a leading 0
|
||||
# will simply be ignored - we test for this by giving an "octal" value that
|
||||
# would be OK if parsed as octal, but not if parsed (correctly) as decimal)
|
||||
#
|
||||
# Obviously total trash like roman numerals or alphabetic strings are out.
|
||||
#
|
||||
# Also no signed values (no + or -) and not a string that looks kind of like
|
||||
# a number, but only if you're generous
|
||||
#
|
||||
# But as the EXIT STATUS section quoted above says, with an invalid 'n'
|
||||
# the shell has the option of exiting, or returning status != 0, so
|
||||
# again this test allows both.
|
||||
|
||||
non_numeric_shift_body() {
|
||||
|
||||
# there are 9 args set, 010 is 8 if parsed octal, 10 decimal
|
||||
for a in a I 0x12 010 5V -1 ' ' '' +1 ' 1'
|
||||
do
|
||||
atf_check -s not-exit:0 -o empty -e ignore ${TEST_SH} -c \
|
||||
"set -- a b c d e f g h i; shift '$a' && echo ERROR"
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case too_many_args
|
||||
too_many_args_head() {
|
||||
# See PR bin/50896
|
||||
atf_set "descr" "Test that sh detects invalid extraneous args to shift"
|
||||
}
|
||||
# This is a syntax error, a non-interactive shell (us) must exit $? != 0
|
||||
too_many_args_body() {
|
||||
# This tests the bug in PR bin/50896 is fixed
|
||||
|
||||
for a in "1 1" "1 0" "1 2 3" "1 foo" "1 --" "-- 1"
|
||||
do
|
||||
atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
|
||||
" set -- a b c d; shift ${a} ; echo FAILED "
|
||||
done
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case basic_shift_test
|
||||
atf_add_test_case excessive_shift
|
||||
atf_add_test_case function_shift
|
||||
atf_add_test_case non_numeric_shift
|
||||
atf_add_test_case too_many_args
|
||||
}
|
23
dist/bin/sh/t_ulimit.sh
vendored
23
dist/bin/sh/t_ulimit.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_ulimit.sh,v 1.1 2012/06/11 18:32:59 njoly Exp $
|
||||
# $NetBSD: t_ulimit.sh,v 1.3 2016/03/27 14:50:01 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,6 +24,8 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
# ulimit builtin test.
|
||||
|
||||
@ -31,13 +33,22 @@ atf_test_case limits
|
||||
limits_head() {
|
||||
atf_set "descr" "Checks for limits flags"
|
||||
}
|
||||
|
||||
get_ulimits() {
|
||||
local limits=$(${TEST_SH} -c 'ulimit -a' |
|
||||
sed -e 's/.*\(-[A-Za-z0-9]\)[^A-Za-z0-9].*/\1/' | sort -u)
|
||||
if [ -z "$limits" ]; then
|
||||
# grr ksh
|
||||
limits="-a -b -c -d -f -l -m -n -p -r -s -t -v"
|
||||
fi
|
||||
echo "$limits"
|
||||
}
|
||||
|
||||
limits_body() {
|
||||
atf_check -s eq:0 -o ignore -e empty \
|
||||
/bin/sh -c "ulimit -a"
|
||||
for l in $(ulimit -a | sed 's,^.*(,,;s, .*$,,');
|
||||
atf_check -s eq:0 -o ignore -e empty ${TEST_SH} -c "ulimit -a"
|
||||
for l in $(get_ulimits)
|
||||
do
|
||||
atf_check -s eq:0 -o ignore -e empty \
|
||||
/bin/sh -c "ulimit $l"
|
||||
atf_check -s eq:0 -o ignore -e empty ${TEST_SH} -c "ulimit $l"
|
||||
done
|
||||
}
|
||||
|
||||
|
95
dist/bin/sh/t_varquote.sh
vendored
95
dist/bin/sh/t_varquote.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_varquote.sh,v 1.2 2012/03/25 18:50:19 christos Exp $
|
||||
# $NetBSD: t_varquote.sh,v 1.5 2016/03/27 14:50:01 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,6 +24,8 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
# Variable quoting test.
|
||||
|
||||
@ -39,30 +41,70 @@ 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"
|
||||
cat <<-'EOF' > script.sh
|
||||
T=0
|
||||
check() {
|
||||
T=$((${T} + 1))
|
||||
|
||||
foo=${a:-"'{}'"}
|
||||
check "$foo" "'{}'"
|
||||
if [ "$1" != "$2" ]
|
||||
then
|
||||
printf '%s\n' "T${T}: expected [$2], found [$1]"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
foo=${a:-${b:-"'{}'"}}
|
||||
check "$foo" "'{}'"
|
||||
#1
|
||||
foo='${a:-foo}'
|
||||
check "$foo" '${a:-foo}'
|
||||
#2
|
||||
foo="${a:-foo}"
|
||||
check "$foo" "foo"
|
||||
#3
|
||||
foo=${a:-"'{}'"}
|
||||
check "$foo" "'{}'"
|
||||
#4
|
||||
foo=${a:-${b:-"'{}'"}}
|
||||
check "$foo" "'{}'"
|
||||
#5
|
||||
# ${ } The ' are inside ".." so are literal (not quotes).
|
||||
foo="${a-'}'}"
|
||||
check "$foo" "''}"
|
||||
#6
|
||||
# The rules for quoting in ${var-word} expressions are somewhat
|
||||
# weird, in the following there is not one quoted string being
|
||||
# assigned to foo (with internally quoted sub-strings), rather
|
||||
# it is a mixed quoted/unquoted string, with parts that are
|
||||
# quoted, separated by 2 unquoted sections...
|
||||
# qqqqqqqqqq uuuuuuuuuu qq uuuu qqqq
|
||||
foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}"
|
||||
# " z*"
|
||||
# ${a:- }
|
||||
# ${b:- }
|
||||
# " y*"
|
||||
# ${c:- }
|
||||
# ${d:- }
|
||||
# "x*"
|
||||
check "$foo" "x}y}z}"
|
||||
#7
|
||||
# And believe it or not, this is the one that gives
|
||||
# most problems, with 3 different observed outputs...
|
||||
# qqqqq qq q is one interpretation
|
||||
# qqqqq QQQQ q is another (most common)
|
||||
# (the third is syntax error...)
|
||||
foo="${a:-"'{}'"}"
|
||||
check "$foo" "'{}'"
|
||||
|
||||
foo="${a:-"'{}'"}"
|
||||
check "$foo" "'{}'"
|
||||
EOF
|
||||
|
||||
foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}"
|
||||
# " z*"
|
||||
# ${a:- }
|
||||
# ${b:- }
|
||||
# " y*"
|
||||
# ${c:- }
|
||||
# ${d:- }
|
||||
# "x*"
|
||||
check "$foo" "x}y}z}"
|
||||
OUT=$( ${TEST_SH} script.sh 2>&1 )
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
atf_fail "${OUT}"
|
||||
elif [ -n "${OUT}" ]
|
||||
then
|
||||
atf_fail "script.sh unexpectedly said: ${OUT}"
|
||||
fi
|
||||
}
|
||||
|
||||
atf_test_case nested_quotes_multiword
|
||||
@ -72,10 +114,21 @@ nested_quotes_multiword_head() {
|
||||
}
|
||||
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"'
|
||||
${TEST_SH} -c 'echo "${foo:="first-word"} second-word"'
|
||||
}
|
||||
|
||||
atf_test_case default_assignment_with_arith
|
||||
default_assignment_with_arith_head() {
|
||||
atf_set "descr" "Tests default variable assignment with arithmetic" \
|
||||
"string works (PR bin/50827)"
|
||||
}
|
||||
default_assignment_with_arith_body() {
|
||||
atf_check -s eq:0 -o empty -e empty ${TEST_SH} -c ': "${x=$((1))}"'
|
||||
atf_check -s eq:0 -o match:1 -e empty ${TEST_SH} -c 'echo "${x=$((1))}"'
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case all
|
||||
atf_add_test_case nested_quotes_multiword
|
||||
atf_add_test_case default_assignment_with_arith
|
||||
}
|
||||
|
251
dist/bin/sh/t_varval.sh
vendored
Executable file
251
dist/bin/sh/t_varval.sh
vendored
Executable file
@ -0,0 +1,251 @@
|
||||
# $NetBSD: t_varval.sh,v 1.1 2016/03/16 15:49:19 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2016 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 "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
# Test all kinds of weird values in various ways to use shell $... expansions
|
||||
|
||||
oneline()
|
||||
{
|
||||
q="'"
|
||||
test $# -eq 4 && q=""
|
||||
|
||||
v=$( printf '\\%3.3o' $(( $2 & 0xFF )) )
|
||||
printf "%s" "$1"
|
||||
if [ $2 != 39 ]; then
|
||||
printf "%sprefix${v}suffix%s" "$q" "$q"
|
||||
elif [ $# -ne 4 ]; then
|
||||
printf %s prefix\"\'\"suffix
|
||||
else
|
||||
printf %s prefix\'suffix
|
||||
fi
|
||||
printf "%s\n" "$3"
|
||||
}
|
||||
|
||||
mkdata() {
|
||||
quote= pfx=
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
--) shift; break;;
|
||||
-q) quote=no; shift; continue;;
|
||||
esac
|
||||
|
||||
pfx="${pfx}${pfx:+ }${1}"
|
||||
shift
|
||||
done
|
||||
|
||||
sfx=
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
sfx="${sfx}${sfx:+ }${1}"
|
||||
shift
|
||||
done
|
||||
|
||||
i=1 # '\0' is not expected to work, anywhere...
|
||||
while [ $i -lt 256 ]
|
||||
do
|
||||
oneline "${pfx}" "$i" "${sfx}" $quote
|
||||
i=$(( $i + 1 ))
|
||||
done
|
||||
}
|
||||
|
||||
atf_test_case aaa
|
||||
aaa_head() {
|
||||
atf_set "descr" "Check that this test has a hope of working. " \
|
||||
"Just give up on these tests if the aaa test fails".
|
||||
}
|
||||
aaa_body() {
|
||||
oneline "echo " 9 '' |
|
||||
atf_check -s exit:0 -o inline:'prefix\tsuffix\n' -e empty \
|
||||
${TEST_SH}
|
||||
|
||||
oneline "VAR=" 65 '; echo "${#VAR}:${VAR}"' |
|
||||
atf_check -s exit:0 -o inline:'13:prefixAsuffix\n' -e empty \
|
||||
${TEST_SH}
|
||||
|
||||
oneline "VAR=" 1 '; echo "${#VAR}:${VAR}"' |
|
||||
atf_check -s exit:0 -o inline:'13:prefixsuffix\n' -e empty \
|
||||
${TEST_SH}
|
||||
|
||||
oneline "VAR=" 10 '; echo "${#VAR}:${VAR}"' |
|
||||
atf_check -s exit:0 -o inline:'13:prefix\nsuffix\n' -e empty \
|
||||
${TEST_SH}
|
||||
|
||||
rm -f prefix* 2>/dev/null || :
|
||||
oneline "echo hello >" 45 "" |
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH}
|
||||
test -f "prefix-suffix" ||
|
||||
atf_fail "failed to create prefix-suffix (45)"
|
||||
test -s "prefix-suffix" ||
|
||||
atf_fail "no data in prefix-suffix (45)"
|
||||
test "$(cat prefix-suffix)" = "hello" ||
|
||||
atf_fail "incorrect data in prefix-suffix (45)"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case assignment
|
||||
assignment_head() {
|
||||
atf_set "descr" "Check that all chars can be assigned to vars"
|
||||
}
|
||||
assignment_body() {
|
||||
atf_require_prog grep
|
||||
atf_require_prog rm
|
||||
|
||||
rm -f results || :
|
||||
mkdata "VAR=" -- '; echo ${#VAR}' |
|
||||
atf_check -s exit:0 -o save:results -e empty ${TEST_SH}
|
||||
test -z $( grep -v "^13$" results ) ||
|
||||
atf_fail "Incorrect lengths: $(grep -nv '^13$' results)"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case cmdline
|
||||
cmdline_head() {
|
||||
atf_set "descr" "Check vars containing all chars can be used"
|
||||
}
|
||||
cmdline_body() {
|
||||
atf_require_prog rm
|
||||
atf_require_prog wc
|
||||
|
||||
rm -f results || :
|
||||
mkdata "VAR=" -- '; echo "${VAR}"' |
|
||||
atf_check -s exit:0 -o save:results -e empty ${TEST_SH}
|
||||
|
||||
# 256 because one output line contains a \n ...
|
||||
test $( wc -l < results ) -eq 256 ||
|
||||
atf_fail "incorrect line count in results"
|
||||
test $(wc -c < results) -eq $(( 255 * 14 )) ||
|
||||
atf_fail "incorrect character count in results"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case redirect
|
||||
redirect_head() {
|
||||
atf_set "descr" "Check vars containing all chars can be used"
|
||||
}
|
||||
redirect_body() {
|
||||
atf_require_prog ls
|
||||
atf_require_prog wc
|
||||
atf_require_prog rm
|
||||
atf_require_prog mkdir
|
||||
atf_require_prog rmdir
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
rm -f prefix* suffix || :
|
||||
|
||||
mkdir prefix # one of the files will be prefix/suffix
|
||||
mkdata "VAR=" -- '; echo "${VAR}" > "${VAR}"' |
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH}
|
||||
|
||||
test -f "prefix/suffix" ||
|
||||
atf_fail "Failed to create file in subdirectory"
|
||||
test $( wc -l < "prefix/suffix" ) -eq 1 ||
|
||||
atf_fail "Not exactly one line in prefix/suffix file"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty rm "prefix/suffix"
|
||||
atf_check -s exit:0 -o empty -e empty rmdir "prefix"
|
||||
|
||||
test -f "prefix${nl}suffix" ||
|
||||
atf_fail "Failed to create file with newline in its name"
|
||||
test $( wc -l < "prefix${nl}suffix" ) -eq 2 ||
|
||||
atf_fail "NewLine file did not contain embedded newline"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty rm "prefix${nl}suffix"
|
||||
|
||||
# Now there should be 253 files left...
|
||||
test $( ls | wc -l ) -eq 253 ||
|
||||
atf_fail \
|
||||
"Did not create all expected files: wanted: 253, found ($( ls | wc -l ))"
|
||||
|
||||
# and each of them should have a name that is 13 chars long (+ \n)
|
||||
test $( ls | wc -c ) -eq $(( 253 * 14 )) ||
|
||||
atf_fail "File names do not appear to be as expected"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_test_case read
|
||||
read_head() {
|
||||
atf_set "descr" "Check vars containing all chars can be used"
|
||||
}
|
||||
read_body() {
|
||||
atf_require_prog ls
|
||||
atf_require_prog wc
|
||||
atf_require_prog rm
|
||||
atf_require_prog mkdir
|
||||
atf_require_prog rmdir
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
rm -f prefix* suffix || :
|
||||
|
||||
mkdir prefix # one of the files will be prefix/suffix
|
||||
mkdata -q |
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '
|
||||
while read -r VAR
|
||||
do
|
||||
# skip the mess made by embedded newline
|
||||
case "${VAR}" in
|
||||
(prefix | suffix) continue;;
|
||||
esac
|
||||
echo "${VAR}" > "${VAR}"
|
||||
done'
|
||||
|
||||
test -f "prefix/suffix" ||
|
||||
atf_fail "Failed to create file in subdirectory"
|
||||
test $( wc -l < "prefix/suffix" ) -eq 1 ||
|
||||
atf_fail "Not exactly one line in prefix/suffix file"
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty rm "prefix/suffix"
|
||||
atf_check -s exit:0 -o empty -e empty rmdir "prefix"
|
||||
|
||||
# Now there should be 253 files left...
|
||||
test $( ls | wc -l ) -eq 253 ||
|
||||
atf_fail \
|
||||
"Did not create all expected files: wanted: 253, found ($( ls | wc -l ))"
|
||||
|
||||
# and each of them should have a name that is 13 chars long (+ \n)
|
||||
test $( ls | wc -c ) -eq $(( 253 * 14 )) ||
|
||||
atf_fail "File names do not appear to be as expected"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case aaa
|
||||
atf_add_test_case assignment
|
||||
atf_add_test_case cmdline
|
||||
atf_add_test_case redirect
|
||||
atf_add_test_case read
|
||||
}
|
168
dist/bin/sh/t_wait.sh
vendored
168
dist/bin/sh/t_wait.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_wait.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
|
||||
# $NetBSD: t_wait.sh,v 1.8 2016/03/31 16:22:54 christos Exp $
|
||||
#
|
||||
# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -24,36 +24,172 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# the implementation of "sh" to test
|
||||
: ${TEST_SH:="/bin/sh"}
|
||||
|
||||
atf_test_case basic_wait
|
||||
basic_wait_head() {
|
||||
atf_set "descr" "Tests simple uses of wait"
|
||||
}
|
||||
basic_wait_body() {
|
||||
atf_require_prog sleep
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'(echo nothing >/dev/null) & wait'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'(exit 3) & wait $!; S=$?; test $S -eq 3 || {
|
||||
echo "status: $S"; exit 1; }'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'sleep 3 & sleep 2 & sleep 1 & wait'
|
||||
|
||||
atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
|
||||
'sleep 3 & (exit 2) & sleep 1 & wait'
|
||||
}
|
||||
|
||||
atf_test_case individual
|
||||
individual_head() {
|
||||
atf_set "descr" "Tests that waiting for individual jobs works"
|
||||
atf_set "descr" "Tests that waiting for individual processes 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 &
|
||||
atf_require_prog sleep
|
||||
|
||||
wait %1
|
||||
if [ \$? -ne 0 ]; then
|
||||
echo "Waiting of first job failed"
|
||||
cat >individualhelper.sh <<\EOF
|
||||
sleep 3 & P1=$!
|
||||
sleep 1 & P2=$!
|
||||
|
||||
wait ${P1}
|
||||
S=$?
|
||||
if [ $S -ne 0 ]; then
|
||||
echo "Waiting for first process failed: $S"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait %2
|
||||
if [ \$? -ne 0 ]; then
|
||||
echo "Waiting of second job failed"
|
||||
wait ${P2}
|
||||
S=$?
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Waiting for second process failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
output=$(/bin/sh helper.sh)
|
||||
output=$(${TEST_SH} individualhelper.sh 2>&1)
|
||||
[ $? -eq 0 ] || atf_fail "${output}"
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case individual
|
||||
atf_test_case jobs
|
||||
jobs_head() {
|
||||
atf_set "descr" "Tests that waiting for individual jobs works"
|
||||
}
|
||||
jobs_body() {
|
||||
# atf-sh confuses wait for some reason; work it around by creating
|
||||
# a helper script that executes /bin/sh directly.
|
||||
|
||||
if ! ${TEST_SH} -c 'sleep 1 & wait %1' 2>/dev/null
|
||||
then
|
||||
atf_skip "No job control support in this shell"
|
||||
fi
|
||||
|
||||
cat >individualhelper.sh <<\EOF
|
||||
sleep 3 &
|
||||
sleep 1 &
|
||||
|
||||
wait %1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Waiting for first job failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait %2
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Waiting for second job failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
output=$(${TEST_SH} individualhelper.sh 2>&1)
|
||||
[ $? -eq 0 ] || atf_fail "${output}"
|
||||
|
||||
cat >individualhelper.sh <<\EOF
|
||||
{ sleep 3; exit 3; } &
|
||||
{ sleep 1; exit 7; } &
|
||||
|
||||
wait %1
|
||||
S=$?
|
||||
if [ $S -ne 3 ]; then
|
||||
echo "Waiting for first job failed - status: $S != 3 (expected)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait %2
|
||||
S=$?
|
||||
if [ $S -ne 7 ]; then
|
||||
echo "Waiting for second job failed - status: $S != 7 (expected)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
output=$(${TEST_SH} individualhelper.sh 2>&1)
|
||||
[ $? -eq 0 ] || atf_fail "${output}"
|
||||
}
|
||||
|
||||
atf_test_case kill
|
||||
kill_head() {
|
||||
atf_set "descr" "Tests that killing the shell while in wait calls trap"
|
||||
}
|
||||
kill_body() {
|
||||
atf_require_prog sleep
|
||||
atf_require_prog kill
|
||||
|
||||
s=killhelper.sh
|
||||
z=killhelper.$$
|
||||
pid=
|
||||
|
||||
# waiting for a specific process that is not a child
|
||||
# should return exit status of 127 according to the spec
|
||||
# This test is here before the next, to avoid that one
|
||||
# entering an infinite loop should the shell have a bug here.
|
||||
|
||||
atf_check -s exit:127 -o empty -e ignore ${TEST_SH} -c 'wait 1'
|
||||
|
||||
cat > "${s}" <<'EOF'
|
||||
|
||||
trap "echo SIGHUP" 1
|
||||
(sleep 5; exit 3) &
|
||||
sl=$!
|
||||
wait
|
||||
S=$?
|
||||
echo $S
|
||||
LS=9999
|
||||
while [ $S -ne 0 ] && [ $S != 127 ]; do
|
||||
wait $sl; S=$?; echo $S
|
||||
test $S = $LS && { echo "wait repeats..."; exit 2; }
|
||||
LS=$S
|
||||
done
|
||||
EOF
|
||||
|
||||
${TEST_SH} $s > $z &
|
||||
pid=$!
|
||||
sleep 1
|
||||
|
||||
kill -HUP "${pid}"
|
||||
wait
|
||||
|
||||
output="$(cat $z | tr '\n' ' ')"
|
||||
|
||||
if [ "$output" != "SIGHUP 129 3 127 " ]; then
|
||||
atf_fail "${output} != 'SIGHUP 129 3 127 '"
|
||||
fi
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case basic_wait
|
||||
atf_add_test_case individual
|
||||
atf_add_test_case jobs
|
||||
atf_add_test_case kill
|
||||
}
|
||||
|
10
dist/crypto/opencrypto/t_opencrypto.sh
vendored
10
dist/crypto/opencrypto/t_opencrypto.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_opencrypto.sh,v 1.4 2014/01/18 15:15:16 pgoyette Exp $
|
||||
# $NetBSD: t_opencrypto.sh,v 1.6 2015/12/26 07:10:03 pgoyette Exp $
|
||||
#
|
||||
# Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -80,7 +80,11 @@ arc4_body() {
|
||||
}
|
||||
|
||||
arc4_cleanup() {
|
||||
common_cleanup
|
||||
# No cleanup required since test is skipped. Trying to run rump.halt
|
||||
# at this point fails, causing the ATF environment to erroneously
|
||||
# report a failed test!
|
||||
#
|
||||
# common_cleanup
|
||||
}
|
||||
|
||||
atf_test_case camellia cleanup
|
||||
@ -98,7 +102,7 @@ camellia_cleanup() {
|
||||
|
||||
atf_test_case cbcdes cleanup
|
||||
cbcdes_head() {
|
||||
common_head "Test ARC4 crypto"
|
||||
common_head "Test DES_CBC crypto"
|
||||
}
|
||||
|
||||
cbcdes_body() {
|
||||
|
8
dist/dev/Makefile
vendored
8
dist/dev/Makefile
vendored
@ -1,13 +1,13 @@
|
||||
# $NetBSD: Makefile,v 1.8 2012/08/08 13:57:05 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.11 2016/07/29 06:13:39 pgoyette Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/dev
|
||||
|
||||
TESTS_SUBDIRS+= cgd raidframe
|
||||
.if (${MKRUMP} != "no")
|
||||
TESTS_SUBDIRS+= audio md scsipi sysmon
|
||||
TESTS_SUBDIRS+= cgd fss raidframe
|
||||
.if (${MKRUMP} != "no") && !defined(BSD_MK_COMPAT_FILE)
|
||||
TESTS_SUBDIRS+= audio md scsipi sysmon usb
|
||||
.endif
|
||||
|
||||
|
||||
|
3
dist/dev/audio/Makefile
vendored
3
dist/dev/audio/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.4 2012/12/02 18:39:53 pgoyette Exp $
|
||||
# $NetBSD: Makefile,v 1.5 2016/01/23 21:22:48 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -13,6 +13,7 @@ MKMAN=no
|
||||
|
||||
PROGS= h_pad
|
||||
|
||||
CPPFLAGS+= -D_KERNTYPES
|
||||
LDADD+= -lrumpdev_pad -lrumpdev_audio -lrumpdev -lrumpvfs
|
||||
LDADD+= -lrump
|
||||
LDADD+= -lrumpuser
|
||||
|
2027
dist/dev/audio/t_pad_output.bz2.uue
vendored
2027
dist/dev/audio/t_pad_output.bz2.uue
vendored
File diff suppressed because it is too large
Load Diff
3
dist/dev/dm/Makefile
vendored
3
dist/dev/dm/Makefile
vendored
@ -1,5 +1,5 @@
|
||||
|
||||
# $NetBSD: Makefile,v 1.2 2012/12/02 18:39:53 pgoyette Exp $
|
||||
# $NetBSD: Makefile,v 1.3 2016/01/23 21:22:48 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -14,6 +14,7 @@ MKMAN=no
|
||||
|
||||
PROGS= h_dm
|
||||
|
||||
CPPFLAGS+=-D_KERNTYPES
|
||||
LDADD+= -lprop -lutil
|
||||
LDADD+= -lrumpdev_disk -lrumpdev_dm
|
||||
LDADD+= -lrumpdev -lrumpvfs
|
||||
|
4
dist/dev/dm/h_dm.c
vendored
4
dist/dev/dm/h_dm.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: h_dm.c,v 1.1 2010/10/06 11:24:55 haad Exp $ */
|
||||
/* $NetBSD: h_dm.c,v 1.2 2016/01/23 21:18:27 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
||||
@ -83,6 +83,7 @@ dm_test_versions(void) {
|
||||
dict_out = prop_dictionary_internalize(prefp.pref_plist);
|
||||
|
||||
xml = prop_dictionary_externalize(dict_out);
|
||||
__USE(xml);
|
||||
|
||||
rump_sys_close(fd);
|
||||
|
||||
@ -122,6 +123,7 @@ dm_test_targets(void) {
|
||||
dict_out = prop_dictionary_internalize(prefp.pref_plist);
|
||||
|
||||
xml = prop_dictionary_externalize(dict_out);
|
||||
__USE(xml);
|
||||
|
||||
rump_sys_close(fd);
|
||||
|
||||
|
3
dist/dev/fss/CVS/Entries
vendored
Normal file
3
dist/dev/fss/CVS/Entries
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/Makefile/1.2/Wed Aug 3 23:53:50 2016//D2016.08.12.00.58.30
|
||||
/t_fss.sh/1.2/Fri Jul 29 20:27:37 2016//D2016.08.12.00.58.30
|
||||
D
|
1
dist/dev/fss/CVS/Repository
vendored
Normal file
1
dist/dev/fss/CVS/Repository
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/tests/dev/fss
|
1
dist/dev/fss/CVS/Root
vendored
Normal file
1
dist/dev/fss/CVS/Root
vendored
Normal file
@ -0,0 +1 @@
|
||||
anoncvs@anoncvs.NetBSD.org:/cvsroot
|
1
dist/dev/fss/CVS/Tag
vendored
Normal file
1
dist/dev/fss/CVS/Tag
vendored
Normal file
@ -0,0 +1 @@
|
||||
D2016.08.12.00.58.30
|
10
dist/dev/fss/Makefile
vendored
Normal file
10
dist/dev/fss/Makefile
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.2 2016/08/03 23:53:50 pgoyette Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/dev/fss
|
||||
|
||||
TESTS_SH= t_fss
|
||||
|
||||
.include <bsd.test.mk>
|
84
dist/dev/fss/t_fss.sh
vendored
Executable file
84
dist/dev/fss/t_fss.sh
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
# $NetBSD: t_fss.sh,v 1.2 2016/07/29 20:27:37 pgoyette Exp $
|
||||
#
|
||||
# Copyright (c) 2006, 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Verify basic operation of fss(4) file system snapshot device
|
||||
#
|
||||
|
||||
orig_data="Original data"
|
||||
repl_data="Replacement data"
|
||||
|
||||
atf_test_case basic cleanup
|
||||
basic_body() {
|
||||
|
||||
# create of mount-points for the file system and snapshot
|
||||
|
||||
mkdir ./m1
|
||||
mkdir ./m2
|
||||
|
||||
# create a small 4MB file, treat it as a disk, init a file-system on it,
|
||||
# and mount it
|
||||
|
||||
dd if=/dev/zero of=./image bs=32k count=64
|
||||
vndconfig -c vnd0 ./image
|
||||
newfs /dev/vnd0a
|
||||
mount /dev/vnd0a ./m1
|
||||
|
||||
echo "${orig_data}" > ./m1/text
|
||||
|
||||
# configure and mount a snapshot of the file system
|
||||
|
||||
fssconfig -c fss0 ./m1 ./backup
|
||||
mount -o rdonly /dev/fss0 ./m2
|
||||
|
||||
# Modify the data on the underlying file system
|
||||
|
||||
echo "${repl_data}" > ./m1/text || abort
|
||||
|
||||
# Verify that original data is still visible in the snapshot
|
||||
|
||||
read test_data < ./m2/text
|
||||
atf_check_equal "${orig_data}" "${test_data}"
|
||||
|
||||
# Unmount our temporary stuff
|
||||
|
||||
umount /dev/fss0 || true
|
||||
fssconfig -u fss0 || true
|
||||
umount /dev/vnd0a || true
|
||||
vndconfig -u vnd0 || true
|
||||
}
|
||||
|
||||
basic_cleanup() {
|
||||
umount /dev/vnd0a || true
|
||||
fssconfig -u fss0 || true
|
||||
umount /dev/fss0 || true
|
||||
vndconfig -u vnd0 || true
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case basic
|
||||
}
|
6
dist/dev/md/Makefile
vendored
6
dist/dev/md/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.4 2014/06/09 18:22:05 he Exp $
|
||||
# $NetBSD: Makefile,v 1.6 2016/01/23 21:22:48 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -13,10 +13,10 @@ MKMAN=no
|
||||
|
||||
PROGS= h_mdserv
|
||||
|
||||
CPPFLAGS+= -D_KERNTYPES
|
||||
LDADD+= -lrumpdev_md -lrumpdev_disk -lrumpdev -lrumpvfs
|
||||
LDADD+= -lrump
|
||||
LDADD+= -lrumpkern_sysproxy -lrump
|
||||
LDADD+= -lrumpuser
|
||||
LDADD+= -lrump
|
||||
LDADD+= -lpthread
|
||||
|
||||
WARNS= 4
|
||||
|
4
dist/dev/scsipi/Makefile
vendored
4
dist/dev/scsipi/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.6 2014/06/10 04:28:39 he Exp $
|
||||
# $NetBSD: Makefile,v 1.7 2016/01/23 21:22:48 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -7,7 +7,7 @@ TESTSDIR= ${TESTSBASE}/dev/scsipi
|
||||
|
||||
TESTS_C= t_cd
|
||||
|
||||
CPPFLAGS+= -I${.CURDIR}/libscsitest
|
||||
CPPFLAGS+= -I${.CURDIR}/libscsitest -D_KERNTYPES
|
||||
|
||||
# kernel component required by test
|
||||
SUBDIR= libscsitest
|
||||
|
3
dist/dev/sysmon/Makefile
vendored
3
dist/dev/sysmon/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.3 2014/06/10 04:28:39 he Exp $
|
||||
# $NetBSD: Makefile,v 1.4 2016/01/23 21:22:48 christos Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -7,6 +7,7 @@ TESTSDIR= ${TESTSBASE}/dev/sysmon
|
||||
|
||||
TESTS_C= t_swwdog
|
||||
|
||||
CPPFLAGS+= -D_KERNTYPES
|
||||
LDADD+= -lrumpdev_sysmon -lrumpdev -lrumpvfs
|
||||
LDADD+= -lrump
|
||||
LDADD+= -lrumpuser
|
||||
|
12
dist/dev/sysmon/t_swsensor.sh
vendored
12
dist/dev/sysmon/t_swsensor.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_swsensor.sh,v 1.7 2013/04/14 16:07:46 martin Exp $
|
||||
# $NetBSD: t_swsensor.sh,v 1.9 2015/04/23 23:23:28 pgoyette Exp $
|
||||
|
||||
get_sensor_info() {
|
||||
rump.envstat -x | \
|
||||
@ -6,7 +6,13 @@ get_sensor_info() {
|
||||
}
|
||||
|
||||
get_sensor_key() {
|
||||
get_sensor_info | grep -A1 $1 | grep integer | sed -e 's;<[/a-z]*>;;g'
|
||||
local v
|
||||
v=$(get_sensor_info | grep -A1 $1 | grep integer | \
|
||||
sed -e 's;<[/a-z]*>;;g')
|
||||
if [ -z "$v" ] ; then
|
||||
v="key_$1_not_found"
|
||||
fi
|
||||
echo $v
|
||||
}
|
||||
|
||||
get_powerd_event_count() {
|
||||
@ -60,7 +66,7 @@ start_rump() {
|
||||
|
||||
common_head() {
|
||||
atf_set descr "$1"
|
||||
atf_set timeout 60
|
||||
atf_set timeout 120
|
||||
atf_set require.progs rump.powerd rump.envstat rump.modload \
|
||||
rump.halt rump.sysctl rump_server \
|
||||
sed grep awk \
|
||||
|
3
dist/dev/sysmon/t_swwdog.c
vendored
3
dist/dev/sysmon/t_swwdog.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_swwdog.c,v 1.5 2011/06/26 12:14:59 christos Exp $ */
|
||||
/* $NetBSD: t_swwdog.c,v 1.6 2015/04/23 04:49:37 pgoyette Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
||||
@ -121,6 +121,7 @@ testbody(int max)
|
||||
_exit(2);
|
||||
}
|
||||
/* fail */
|
||||
printf("no watchdog registered!\n");
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
|
4
dist/dev/usb/CVS/Entries
vendored
Normal file
4
dist/dev/usb/CVS/Entries
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/Makefile/1.3/Fri Jan 8 17:27:48 2016//D2016.08.12.00.58.30
|
||||
/t_hid.c/1.8/Thu May 5 17:40:26 2016//D2016.08.12.00.58.30
|
||||
D/libhid////
|
||||
D/t_hid////
|
1
dist/dev/usb/CVS/Repository
vendored
Normal file
1
dist/dev/usb/CVS/Repository
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/tests/dev/usb
|
1
dist/dev/usb/CVS/Root
vendored
Normal file
1
dist/dev/usb/CVS/Root
vendored
Normal file
@ -0,0 +1 @@
|
||||
anoncvs@anoncvs.NetBSD.org:/cvsroot
|
1
dist/dev/usb/CVS/Tag
vendored
Normal file
1
dist/dev/usb/CVS/Tag
vendored
Normal file
@ -0,0 +1 @@
|
||||
D2016.08.12.00.58.30
|
12
dist/dev/usb/Makefile
vendored
Normal file
12
dist/dev/usb/Makefile
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# $NetBSD: Makefile,v 1.3 2016/01/08 17:27:48 jakllsch Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= libhid .WAIT
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/dev/usb
|
||||
|
||||
TESTS_SUBDIRS= t_hid
|
||||
|
||||
.include <bsd.test.mk>
|
2
dist/dev/usb/libhid/CVS/Entries
vendored
Normal file
2
dist/dev/usb/libhid/CVS/Entries
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/Makefile/1.1/Tue Jan 5 17:22:39 2016//D2016.08.12.00.58.30
|
||||
D
|
1
dist/dev/usb/libhid/CVS/Repository
vendored
Normal file
1
dist/dev/usb/libhid/CVS/Repository
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/tests/dev/usb/libhid
|
1
dist/dev/usb/libhid/CVS/Root
vendored
Normal file
1
dist/dev/usb/libhid/CVS/Root
vendored
Normal file
@ -0,0 +1 @@
|
||||
anoncvs@anoncvs.NetBSD.org:/cvsroot
|
1
dist/dev/usb/libhid/CVS/Tag
vendored
Normal file
1
dist/dev/usb/libhid/CVS/Tag
vendored
Normal file
@ -0,0 +1 @@
|
||||
D2016.08.12.00.58.30
|
16
dist/dev/usb/libhid/Makefile
vendored
Normal file
16
dist/dev/usb/libhid/Makefile
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# $NetBSD: Makefile,v 1.1 2016/01/05 17:22:39 jakllsch Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
RUMPTOP= ${NETBSDSRCDIR}/sys/rump
|
||||
.PATH: ${.CURDIR}/../../../../sys/dev/usb
|
||||
|
||||
LIB= rumpdev_hid
|
||||
LIBISPRIVATE= #defined
|
||||
|
||||
SRCS= hid.c
|
||||
|
||||
.include "${RUMPTOP}/Makefile.rump"
|
||||
.include <bsd.lib.mk>
|
||||
.include <bsd.klinks.mk>
|
267
dist/dev/usb/t_hid.c
vendored
Normal file
267
dist/dev/usb/t_hid.c
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
/* $NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Jonathan A. Kollasch
|
||||
* 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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/cdefs.h>
|
||||
__RCSID("$NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $");
|
||||
|
||||
#include <machine/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <atf-c.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
|
||||
#define hid_start_parse rumpns_hid_start_parse
|
||||
#define hid_end_parse rumpns_hid_end_parse
|
||||
#define hid_get_item rumpns_hid_get_item
|
||||
#define hid_locate rumpns_hid_locate
|
||||
#define hid_report_size rumpns_hid_report_size
|
||||
#define hid_get_data rumpns_hid_get_data
|
||||
#define hid_get_udata rumpns_hid_get_udata
|
||||
#define uhidevdebug rumpns_uhidevdebug
|
||||
#include <usb.h>
|
||||
#include <usbhid.h>
|
||||
#include <hid.h>
|
||||
|
||||
#include "../../lib/libusbhid/hid_test_data.c"
|
||||
|
||||
#define MYd_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== %d", (d))
|
||||
|
||||
#define MYld_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== %ld", (d))
|
||||
|
||||
#define MYu_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== %u", (d))
|
||||
|
||||
#define MYlu_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== %lu", (d))
|
||||
|
||||
#define MYx_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d))
|
||||
|
||||
#define MYlx_ATF_CHECK_EQ(d, v) \
|
||||
ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d))
|
||||
|
||||
int uhidevdebug;
|
||||
|
||||
ATF_TC(khid);
|
||||
|
||||
ATF_TC_HEAD(khid, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "check kernel hid.c");
|
||||
}
|
||||
|
||||
static int
|
||||
locate_item(const void *desc, int size, u_int32_t u, u_int8_t id,
|
||||
enum hid_kind k, struct hid_item *hip)
|
||||
{
|
||||
struct hid_data *d;
|
||||
struct hid_item h;
|
||||
|
||||
h.report_ID = 0;
|
||||
for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
|
||||
if (h.kind == k && !(h.flags & HIO_CONST) &&
|
||||
(/*XXX*/uint32_t)h.usage == u && h.report_ID == id) {
|
||||
if (hip != NULL)
|
||||
*hip = h;
|
||||
hid_end_parse(d);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
hid_end_parse(d);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TC_BODY(khid, tc)
|
||||
{
|
||||
int ret;
|
||||
struct hid_item hi;
|
||||
|
||||
uhidevdebug = 0;
|
||||
|
||||
rump_init();
|
||||
|
||||
rump_schedule();
|
||||
|
||||
ret = locate_item(range_test_report_descriptor,
|
||||
sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input,
|
||||
&hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 32);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
|
||||
&hi.loc), -2147483648);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
|
||||
&hi.loc), -1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
|
||||
&hi.loc), 1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
|
||||
&hi.loc), 2147483647);
|
||||
|
||||
ret = locate_item(range_test_report_descriptor,
|
||||
sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input,
|
||||
&hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 16);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
|
||||
&hi.loc), -32768);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
|
||||
&hi.loc), -1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
|
||||
&hi.loc), 1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
|
||||
&hi.loc), 32767);
|
||||
|
||||
ret = locate_item(range_test_report_descriptor,
|
||||
sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input,
|
||||
&hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 8);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_minimum, -128);
|
||||
MYd_ATF_CHECK_EQ(hi.logical_maximum, 127);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_minimum, -128);
|
||||
MYd_ATF_CHECK_EQ(hi.physical_maximum, 127);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
|
||||
&hi.loc), -128);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
|
||||
&hi.loc), -1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
|
||||
&hi.loc), 1);
|
||||
MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
|
||||
&hi.loc), 127);
|
||||
|
||||
|
||||
ret = locate_item(unsigned_range_test_report_descriptor,
|
||||
sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0,
|
||||
hid_input, &hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 32);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
|
||||
&hi.loc), 0x0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
|
||||
&hi.loc), 0x1);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
|
||||
&hi.loc), 0xfffffffe);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
|
||||
&hi.loc), 0xffffffff);
|
||||
|
||||
ret = locate_item(unsigned_range_test_report_descriptor,
|
||||
sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0,
|
||||
hid_input, &hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 16);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
|
||||
&hi.loc), 0x0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
|
||||
&hi.loc), 0x1);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
|
||||
&hi.loc), 0xfffe);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
|
||||
&hi.loc), 0xffff);
|
||||
|
||||
ret = locate_item(unsigned_range_test_report_descriptor,
|
||||
sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0,
|
||||
hid_input, &hi);
|
||||
ATF_REQUIRE(ret > 0);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.size, 8);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.count, 1);
|
||||
MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
|
||||
MYx_ATF_CHECK_EQ(hi.flags, 0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
|
||||
&hi.loc), 0x0);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
|
||||
&hi.loc), 0x1);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
|
||||
&hi.loc), 0xfe);
|
||||
MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
|
||||
&hi.loc), 0xff);
|
||||
|
||||
rump_unschedule();
|
||||
}
|
||||
|
||||
ATF_TC(khid_parse_just_pop);
|
||||
|
||||
ATF_TC_HEAD(khid_parse_just_pop, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "check kernel hid.c for "
|
||||
"Pop on empty stack bug");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(khid_parse_just_pop, tc)
|
||||
{
|
||||
struct hid_data *hdp;
|
||||
struct hid_item hi;
|
||||
|
||||
rump_init();
|
||||
|
||||
rump_schedule();
|
||||
|
||||
hdp = hid_start_parse(just_pop_report_descriptor,
|
||||
sizeof just_pop_report_descriptor, hid_none);
|
||||
while (hid_get_item(hdp, &hi) > 0) {
|
||||
}
|
||||
hid_end_parse(hdp);
|
||||
|
||||
rump_unschedule();
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, khid);
|
||||
ATF_TP_ADD_TC(tp, khid_parse_just_pop);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
2
dist/dev/usb/t_hid/CVS/Entries
vendored
Normal file
2
dist/dev/usb/t_hid/CVS/Entries
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/Makefile/1.1/Fri Jan 8 17:27:48 2016//D2016.08.12.00.58.30
|
||||
D
|
1
dist/dev/usb/t_hid/CVS/Repository
vendored
Normal file
1
dist/dev/usb/t_hid/CVS/Repository
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/tests/dev/usb/t_hid
|
1
dist/dev/usb/t_hid/CVS/Root
vendored
Normal file
1
dist/dev/usb/t_hid/CVS/Root
vendored
Normal file
@ -0,0 +1 @@
|
||||
anoncvs@anoncvs.NetBSD.org:/cvsroot
|
1
dist/dev/usb/t_hid/CVS/Tag
vendored
Normal file
1
dist/dev/usb/t_hid/CVS/Tag
vendored
Normal file
@ -0,0 +1 @@
|
||||
D2016.08.12.00.58.30
|
26
dist/dev/usb/t_hid/Makefile
vendored
Normal file
26
dist/dev/usb/t_hid/Makefile
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# $NetBSD: Makefile,v 1.1 2016/01/08 17:27:48 jakllsch Exp $
|
||||
#
|
||||
|
||||
PROG= t_hid
|
||||
NOMAN=
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
CPPFLAGS.t_hid.c= -I${.CURDIR}/../../../../sys/dev/usb
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
BINDIR= ${TESTSBASE}/dev/usb
|
||||
|
||||
LIBHIDDIR!= cd ${.CURDIR}/../libhid && ${PRINTOBJDIR}
|
||||
LDFLAGS+= -L${LIBHIDDIR}
|
||||
LDADD+= -Wl,--whole-archive -lrumpdev_hid -Wl,--no-whole-archive
|
||||
DPADD+= ${LIBHIDDIR}/librumpdev_hid.a
|
||||
DPADD+= ${ATF_C}
|
||||
|
||||
LDADD+= -latf-c
|
||||
LDADD+= -lrump
|
||||
LDADD+= -lrumpuser
|
||||
LDADD+= -lpthread
|
||||
|
||||
.include <bsd.prog.mk>
|
1
dist/fs/Makefile.inc
vendored
1
dist/fs/Makefile.inc
vendored
@ -1 +1,2 @@
|
||||
.include "../Makefile.inc"
|
||||
CPPFLAGS+= -D_KERNTYPES
|
||||
|
4
dist/fs/common/fstest_lfs.c
vendored
4
dist/fs/common/fstest_lfs.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fstest_lfs.c,v 1.4 2010/07/30 16:15:05 pooka Exp $ */
|
||||
/* $NetBSD: fstest_lfs.c,v 1.5 2015/08/30 18:27:26 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -48,8 +48,6 @@
|
||||
#include "h_fsmacros.h"
|
||||
#include "mount_lfs.h"
|
||||
|
||||
sem_t lfs_clearnerloop;
|
||||
|
||||
struct lfstestargs {
|
||||
struct ufs_args ta_uargs;
|
||||
pthread_t ta_cleanerthread;
|
||||
|
12
dist/fs/common/h_fsmacros.h
vendored
12
dist/fs/common/h_fsmacros.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: h_fsmacros.h,v 1.38 2013/06/26 19:29:24 reinoud Exp $ */
|
||||
/* $NetBSD: h_fsmacros.h,v 1.40 2015/08/29 19:19:43 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -110,10 +110,6 @@ do { \
|
||||
atf_tc_set_md_var(tc, "descr", type " test for " desc); \
|
||||
atf_tc_set_md_var(tc, "X-fs.type", #fs); \
|
||||
atf_tc_set_md_var(tc, "X-fs.mntname", type); \
|
||||
if (strcmp(#fs, "zfs") == 0) { \
|
||||
/* This should not be necessary. */ \
|
||||
atf_tc_set_md_var(tc, "require.user", "root"); \
|
||||
} \
|
||||
} \
|
||||
void *fs##func##tmp; \
|
||||
\
|
||||
@ -136,10 +132,6 @@ do { \
|
||||
atf_tc_set_md_var(tc, "descr",_type_" test for "_desc_);\
|
||||
atf_tc_set_md_var(tc, "X-fs.type", #_fs_); \
|
||||
atf_tc_set_md_var(tc, "X-fs.mntname", _type_); \
|
||||
if (strcmp(#_fs_, "zfs") == 0) { \
|
||||
/* This should not be necessary. */ \
|
||||
atf_tc_set_md_var(tc, "require.user", "root"); \
|
||||
} \
|
||||
} \
|
||||
void *_fs_##_func_##tmp; \
|
||||
\
|
||||
@ -153,7 +145,7 @@ do { \
|
||||
atf_tc_fail_errno("unmount r/w failed"); \
|
||||
if (_fs_##_fstest_mount(tc, _fs_##_func_##tmp, \
|
||||
FSTEST_MNTNAME, MNT_RDONLY) != 0) \
|
||||
atf_tc_fail_errno("mount ro failed"); \
|
||||
atf_tc_fail_errno("mount ro failed"); \
|
||||
_func_(tc,FSTEST_MNTNAME); \
|
||||
if (_fs_##_fstest_unmount(tc, FSTEST_MNTNAME, 0) != 0) {\
|
||||
rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); \
|
||||
|
5
dist/fs/ffs/Makefile
vendored
5
dist/fs/ffs/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.17 2012/01/18 20:51:23 bouyer Exp $
|
||||
# $NetBSD: Makefile,v 1.18 2015/01/07 22:24:03 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -34,6 +34,7 @@ LDADD+=-lrumpdev_disk -lrumpdev # disk device
|
||||
LDADD+=-lrumpvfs_fifofs -lrumpnet_local -lrumpnet_net -lrumpnet # fifos
|
||||
VFSTESTDIR != cd ${.CURDIR}/../common && ${PRINTOBJDIR}
|
||||
LDADD+=-L${VFSTESTDIR} -lvfstest
|
||||
LDADD+=-lrumpvfs -lrump -lrumpuser -lpthread # base
|
||||
LDADD+=-lrumpvfs -lrumpkern_sysproxy -lrump -lrumpuser # base
|
||||
LDADD+=-lpthread
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
5
dist/fs/msdosfs/Makefile
vendored
5
dist/fs/msdosfs/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.1 2010/04/13 10:21:47 pooka Exp $
|
||||
# $NetBSD: Makefile,v 1.2 2015/01/07 23:12:31 pooka Exp $
|
||||
#
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/fs/msdosfs
|
||||
@ -9,6 +9,7 @@ TESTS_C= t_snapshot
|
||||
LDADD+=-lrumpfs_msdos -lrumpfs_tmpfs # fs drivers
|
||||
LDADD+=-lrumpdev_fss # snapshot dev
|
||||
LDADD+=-lrumpdev_disk -lrumpdev # disk device
|
||||
LDADD+=-lrumpvfs -lrump -lrumpuser -lpthread # base
|
||||
LDADD+=-lrumpvfs -lrumpkern_sysproxy -lrump -lrumpuser # base
|
||||
LDADD+=-lpthread
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
5
dist/fs/nfs/Makefile
vendored
5
dist/fs/nfs/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.9 2014/06/10 04:28:39 he Exp $
|
||||
# $NetBSD: Makefile,v 1.10 2015/01/08 03:50:56 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -22,7 +22,8 @@ LDADD+=-lrumpfs_ffs -lrumpvfs # ffs
|
||||
LDADD+=-lrumpdev_disk -lrumpdev # disk device
|
||||
LDADD+=-lrumpnet_shmif # shmif
|
||||
LDADD+=-lrumpnet_netinet -lrumpnet_net -lrumpnet
|
||||
LDADD+=-lrump -lrumpuser -lrump -lpthread # base
|
||||
LDADD+=-lrumpkern_sysproxy -lrump -lrumpuser # base
|
||||
LDADD+=-lpthread
|
||||
|
||||
LDADD+=-lutil
|
||||
|
||||
|
27
dist/fs/nfs/nfsservice/Makefile
vendored
27
dist/fs/nfs/nfsservice/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.7 2013/03/06 13:35:22 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.11 2015/12/23 18:42:23 christos Exp $
|
||||
#
|
||||
|
||||
NOMAN= 1
|
||||
@ -16,22 +16,35 @@ LDADD+= -L${VFSTESTDIR} -Wl,--whole-archive -lvfstest -Wl,--no-whole-archive
|
||||
|
||||
TESTS_C=rumpnfsd
|
||||
|
||||
SRCS.rumpnfsd= rumpnfsd.c nfsd.c mountd.c getmntinfo.c
|
||||
SRCS.rumpnfsd= rumpnfsd.c nfsd.c mountd.c getmntinfo.c get_net.c
|
||||
|
||||
LDADD+= -lrumpfs_nfsserver -lrumpfs_nfs # NFS support
|
||||
LDADD+= -lrumpdev_disk -lrumpdev # disk devices
|
||||
LDADD+= -lrumpfs_ffs -lrumpvfs # FFS
|
||||
LDADD+= -lrumpnet_netinet -lrumpnet_net -lrumpnet_local # TCP/IP
|
||||
LDADD+= -lrumpnet_shmif # shmif
|
||||
LDADD+= -lrumpnet -lrump -lrumpuser # base
|
||||
LDADD+= -lrumpnet -lrumpkern_sysproxy -lrump -lrumpuser # base
|
||||
LDADD+= -lpthread -lutil
|
||||
|
||||
CPPFLAGS+= -DDEBUG -DMOUNT_NOMAIN -D_REENTRANT
|
||||
CPPFLAGS+= -DRUMP_SYS_NETWORKING
|
||||
CPPFLAGS+= -DRUMP_SYS_NETWORKING -DMOUNTD_RUMP -DNFSD_RUMP
|
||||
|
||||
.PATH: ${.CURDIR}/rpcbind
|
||||
.include "rpcbind/Makefile.inc"
|
||||
.PATH.c: ${NETBSDSRCDIR}/usr.sbin/mountd ${NETBSDSRCDIR}/usr.sbin/nfsd
|
||||
|
||||
WARNS= 2
|
||||
# RPCBIND
|
||||
.PATH.c: ${NETBSDSRCDIR}/usr.sbin/rpcbind
|
||||
SRCS.rumpnfsd+= check_bound.c rpcb_stat.c rpcb_svc_4.c rpcbind.c pmap_svc.c \
|
||||
rpcb_svc.c rpcb_svc_com.c security.c util.c
|
||||
|
||||
LIBRPCDIR= ${NETBSDSRCDIR}/lib/libc/rpc
|
||||
|
||||
CPPFLAGS+= -I${LIBRPCDIR} -DPORTMAP -DLIBWRAP -DRPCBIND_RUMP
|
||||
|
||||
# Uncomment these to get any useful output from 'rpcbind -d'
|
||||
# CPPFLAGS+= -DRPCBIND_DEBUG
|
||||
# CPPFLAGS+= -DSVC_RUN_DEBUG
|
||||
|
||||
LDADD+= -lwrap -lutil
|
||||
DPADD+= ${LIBWRAP} ${LIBUTIL}
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
2575
dist/fs/nfs/nfsservice/mountd.c
vendored
2575
dist/fs/nfs/nfsservice/mountd.c
vendored
File diff suppressed because it is too large
Load Diff
571
dist/fs/nfs/nfsservice/nfsd.c
vendored
571
dist/fs/nfs/nfsservice/nfsd.c
vendored
@ -1,571 +0,0 @@
|
||||
/* $NetBSD: nfsd.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Rick Macklem at The University of Guelph.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: nfsd.c,v 1.4 2013/10/19 17:45:00 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsproto.h>
|
||||
#include <nfs/nfs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
/* Global defs */
|
||||
#ifdef DEBUG
|
||||
#define syslog(e, s, args...) \
|
||||
do { \
|
||||
fprintf(stderr,(s), ## args); \
|
||||
fprintf(stderr, "\n"); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
int debug = 1;
|
||||
#else
|
||||
int debug = 0;
|
||||
#endif
|
||||
|
||||
int main __P((int, char **));
|
||||
void nonfs __P((int));
|
||||
void usage __P((void));
|
||||
|
||||
static void *
|
||||
child(void *arg)
|
||||
{
|
||||
struct nfsd_srvargs nsd;
|
||||
int nfssvc_flag;
|
||||
|
||||
nfssvc_flag = NFSSVC_NFSD;
|
||||
memset(&nsd, 0, sizeof(nsd));
|
||||
while (rump_sys_nfssvc(nfssvc_flag, &nsd) < 0) {
|
||||
if (errno != ENEEDAUTH) {
|
||||
syslog(LOG_ERR, "nfssvc: %m %d", errno);
|
||||
exit(1);
|
||||
}
|
||||
nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nfs server daemon mostly just a user context for nfssvc()
|
||||
*
|
||||
* 1 - do file descriptor and signal cleanup
|
||||
* 2 - create the nfsd thread(s)
|
||||
* 3 - create server socket(s)
|
||||
* 4 - register socket with portmap
|
||||
*
|
||||
* For connectionless protocols, just pass the socket into the kernel via
|
||||
* nfssvc().
|
||||
* For connection based sockets, loop doing accepts. When you get a new
|
||||
* socket from accept, pass the msgsock into the kernel via nfssvc().
|
||||
* The arguments are:
|
||||
* -c - support iso cltp clients
|
||||
* -r - reregister with portmapper
|
||||
* -t - support tcp nfs clients
|
||||
* -u - support udp nfs clients
|
||||
* followed by "n" which is the number of nfsd threads to create
|
||||
*/
|
||||
int nfsd_main(int, char**);
|
||||
int
|
||||
nfsd_main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct nfsd_args nfsdargs;
|
||||
struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
|
||||
struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
|
||||
struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
|
||||
struct sockaddr_in inetpeer;
|
||||
struct pollfd set[4];
|
||||
socklen_t len;
|
||||
int ch, connect_type_cnt, i, msgsock;
|
||||
int nfsdcnt, on = 1, reregister, sock, tcpflag, tcpsock;
|
||||
int tcp6sock, ip6flag;
|
||||
int tp4cnt, tp4flag, tpipcnt, udpflag, ecode, s;
|
||||
int error = 0;
|
||||
|
||||
#define DEFNFSDCNT 4
|
||||
nfsdcnt = DEFNFSDCNT;
|
||||
reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
|
||||
udpflag = ip6flag = 0;
|
||||
nconf_udp = nconf_tcp = nconf_udp6 = nconf_tcp6 = NULL;
|
||||
tcpsock = tcp6sock = -1;
|
||||
#define GETOPT "6n:rtu"
|
||||
#define USAGE "[-rtu] [-n num_servers]"
|
||||
while ((ch = getopt(argc, argv, GETOPT)) != -1) {
|
||||
switch (ch) {
|
||||
case '6':
|
||||
ip6flag = 1;
|
||||
s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (s < 0 && (errno == EPROTONOSUPPORT ||
|
||||
errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
|
||||
ip6flag = 0;
|
||||
else
|
||||
close(s);
|
||||
break;
|
||||
case 'n':
|
||||
nfsdcnt = atoi(optarg);
|
||||
if (nfsdcnt < 1) {
|
||||
warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
|
||||
nfsdcnt = DEFNFSDCNT;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
reregister = 1;
|
||||
break;
|
||||
case 't':
|
||||
tcpflag = 1;
|
||||
break;
|
||||
case 'u':
|
||||
udpflag = 1;
|
||||
break;
|
||||
default:
|
||||
case '?':
|
||||
usage();
|
||||
};
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Backward compatibility, trailing number is the count of daemons.
|
||||
*/
|
||||
if (argc > 1)
|
||||
usage();
|
||||
if (argc == 1) {
|
||||
nfsdcnt = atoi(argv[0]);
|
||||
if (nfsdcnt < 1) {
|
||||
warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
|
||||
nfsdcnt = DEFNFSDCNT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If none of TCP or UDP are specified, default to UDP only.
|
||||
*/
|
||||
if (tcpflag == 0 && udpflag == 0)
|
||||
udpflag = 1;
|
||||
|
||||
if (debug == 0) {
|
||||
fprintf(stderr, "non-debug not supported here\n");
|
||||
exit(1);
|
||||
|
||||
#ifdef not_the_debug_man
|
||||
daemon(0, 0);
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
(void)signal(SIGSYS, nonfs);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (udpflag) {
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = PF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
|
||||
if (ecode != 0) {
|
||||
syslog(LOG_ERR, "getaddrinfo udp: %s",
|
||||
gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nconf_udp = getnetconfigent("udp");
|
||||
|
||||
if (nconf_udp == NULL)
|
||||
err(1, "getnetconfigent udp failed");
|
||||
|
||||
nb_udp.buf = ai_udp->ai_addr;
|
||||
nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
|
||||
if (reregister)
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp))
|
||||
err(1, "rpcb_set udp failed");
|
||||
}
|
||||
|
||||
if (tcpflag) {
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = PF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
|
||||
if (ecode != 0) {
|
||||
syslog(LOG_ERR, "getaddrinfo tcp: %s",
|
||||
gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nconf_tcp = getnetconfigent("tcp");
|
||||
|
||||
if (nconf_tcp == NULL)
|
||||
err(1, "getnetconfigent tcp failed");
|
||||
|
||||
nb_tcp.buf = ai_tcp->ai_addr;
|
||||
nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
|
||||
if (reregister)
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp))
|
||||
err(1, "rpcb_set tcp failed");
|
||||
}
|
||||
|
||||
if (udpflag && ip6flag) {
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = PF_INET6;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
|
||||
if (ecode != 0) {
|
||||
syslog(LOG_ERR, "getaddrinfo udp: %s",
|
||||
gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nconf_udp6 = getnetconfigent("udp6");
|
||||
|
||||
if (nconf_udp6 == NULL)
|
||||
err(1, "getnetconfigent udp6 failed");
|
||||
|
||||
nb_udp6.buf = ai_udp6->ai_addr;
|
||||
nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
|
||||
if (reregister)
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6))
|
||||
err(1, "rpcb_set udp6 failed");
|
||||
}
|
||||
|
||||
if (tcpflag && ip6flag) {
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = PF_INET6;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
|
||||
if (ecode != 0) {
|
||||
syslog(LOG_ERR, "getaddrinfo tcp: %s",
|
||||
gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nconf_tcp6 = getnetconfigent("tcp6");
|
||||
|
||||
if (nconf_tcp6 == NULL)
|
||||
err(1, "getnetconfigent tcp6 failed");
|
||||
|
||||
nb_tcp6.buf = ai_tcp6->ai_addr;
|
||||
nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
|
||||
if (reregister)
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6))
|
||||
err(1, "rpcb_set tcp6 failed");
|
||||
}
|
||||
|
||||
openlog("nfsd", LOG_PID, LOG_DAEMON);
|
||||
|
||||
for (i = 0; i < nfsdcnt; i++) {
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, child, NULL);
|
||||
}
|
||||
|
||||
/* If we are serving udp, set up the socket. */
|
||||
if (udpflag) {
|
||||
if ((sock = rump_sys_socket(ai_udp->ai_family, ai_udp->ai_socktype,
|
||||
ai_udp->ai_protocol)) < 0) {
|
||||
syslog(LOG_ERR, "can't create udp socket");
|
||||
exit(1);
|
||||
}
|
||||
if (bind(sock, ai_udp->ai_addr, ai_udp->ai_addrlen) < 0) {
|
||||
syslog(LOG_ERR, "can't bind udp addr");
|
||||
exit(1);
|
||||
}
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp) ||
|
||||
!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)) {
|
||||
syslog(LOG_ERR, "can't register with udp portmap");
|
||||
exit(1);
|
||||
}
|
||||
nfsdargs.sock = sock;
|
||||
nfsdargs.name = NULL;
|
||||
nfsdargs.namelen = 0;
|
||||
if (rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
|
||||
syslog(LOG_ERR, "can't add UDP socket");
|
||||
exit(1);
|
||||
}
|
||||
(void)rump_sys_close(sock);
|
||||
}
|
||||
|
||||
if (udpflag &&ip6flag) {
|
||||
if ((sock = rump_sys_socket(ai_udp6->ai_family, ai_udp6->ai_socktype,
|
||||
ai_udp6->ai_protocol)) < 0) {
|
||||
syslog(LOG_ERR, "can't create udp socket");
|
||||
exit(1);
|
||||
}
|
||||
if (rump_sys_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
&on, sizeof on) < 0) {
|
||||
syslog(LOG_ERR, "can't set v6-only binding for udp6 "
|
||||
"socket: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (rump_sys_bind(sock, ai_udp6->ai_addr, ai_udp6->ai_addrlen) < 0) {
|
||||
syslog(LOG_ERR, "can't bind udp addr");
|
||||
exit(1);
|
||||
}
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6) ||
|
||||
!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)) {
|
||||
syslog(LOG_ERR, "can't register with udp portmap");
|
||||
exit(1);
|
||||
}
|
||||
nfsdargs.sock = sock;
|
||||
nfsdargs.name = NULL;
|
||||
nfsdargs.namelen = 0;
|
||||
if (rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
|
||||
syslog(LOG_ERR, "can't add UDP6 socket");
|
||||
exit(1);
|
||||
}
|
||||
(void)rump_sys_close(sock);
|
||||
}
|
||||
|
||||
/* Now set up the master server socket waiting for tcp connections. */
|
||||
on = 1;
|
||||
connect_type_cnt = 0;
|
||||
if (tcpflag) {
|
||||
if ((tcpsock = rump_sys_socket(ai_tcp->ai_family, ai_tcp->ai_socktype,
|
||||
ai_tcp->ai_protocol)) < 0) {
|
||||
syslog(LOG_ERR, "can't create tcp socket");
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(tcpsock,
|
||||
SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
|
||||
syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
|
||||
if (bind(tcpsock, ai_tcp->ai_addr, ai_tcp->ai_addrlen) < 0) {
|
||||
syslog(LOG_ERR, "can't bind tcp addr");
|
||||
exit(1);
|
||||
}
|
||||
if (rump_sys_listen(tcpsock, 5) < 0) {
|
||||
syslog(LOG_ERR, "listen failed");
|
||||
exit(1);
|
||||
}
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp) ||
|
||||
!rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp)) {
|
||||
syslog(LOG_ERR, "can't register tcp with rpcbind");
|
||||
exit(1);
|
||||
}
|
||||
set[0].fd = tcpsock;
|
||||
set[0].events = POLLIN;
|
||||
connect_type_cnt++;
|
||||
} else
|
||||
set[0].fd = -1;
|
||||
|
||||
if (tcpflag && ip6flag) {
|
||||
if ((tcp6sock = socket(ai_tcp6->ai_family, ai_tcp6->ai_socktype,
|
||||
ai_tcp6->ai_protocol)) < 0) {
|
||||
syslog(LOG_ERR, "can't create tcp socket");
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(tcp6sock,
|
||||
SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
|
||||
syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
|
||||
if (setsockopt(tcp6sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
&on, sizeof on) < 0) {
|
||||
syslog(LOG_ERR, "can't set v6-only binding for tcp6 "
|
||||
"socket: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (bind(tcp6sock, ai_tcp6->ai_addr, ai_tcp6->ai_addrlen) < 0) {
|
||||
syslog(LOG_ERR, "can't bind tcp6 addr");
|
||||
exit(1);
|
||||
}
|
||||
if (listen(tcp6sock, 5) < 0) {
|
||||
syslog(LOG_ERR, "listen failed");
|
||||
exit(1);
|
||||
}
|
||||
if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6) ||
|
||||
!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)) {
|
||||
syslog(LOG_ERR, "can't register tcp6 with rpcbind");
|
||||
exit(1);
|
||||
}
|
||||
set[1].fd = tcp6sock;
|
||||
set[1].events = POLLIN;
|
||||
connect_type_cnt++;
|
||||
} else
|
||||
set[1].fd = -1;
|
||||
|
||||
set[2].fd = -1;
|
||||
set[3].fd = -1;
|
||||
|
||||
if (connect_type_cnt == 0) {
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop forever accepting connections and passing the sockets
|
||||
* into the kernel for the mounts.
|
||||
*/
|
||||
for (;;) {
|
||||
if (rump_sys_poll(set, 4, INFTIM) < 1) {
|
||||
syslog(LOG_ERR, "poll failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
len = sizeof(inetpeer);
|
||||
if ((msgsock = accept(tcpsock,
|
||||
(struct sockaddr *)&inetpeer, &len)) < 0) {
|
||||
syslog(LOG_ERR, "accept failed: %d", error);
|
||||
exit(1);
|
||||
}
|
||||
memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero));
|
||||
if (setsockopt(msgsock, SOL_SOCKET,
|
||||
SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
|
||||
syslog(LOG_ERR,
|
||||
"setsockopt SO_KEEPALIVE: %m");
|
||||
nfsdargs.sock = msgsock;
|
||||
nfsdargs.name = (caddr_t)&inetpeer;
|
||||
nfsdargs.namelen = sizeof(inetpeer);
|
||||
rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
|
||||
(void)rump_sys_close(msgsock);
|
||||
|
||||
#ifdef notyet
|
||||
if (set[1].revents & POLLIN) {
|
||||
len = sizeof(inet6peer);
|
||||
if ((msgsock = rump_sys_accept(tcp6sock,
|
||||
(struct sockaddr *)&inet6peer, &len, &error)) < 0) {
|
||||
syslog(LOG_ERR, "accept failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (rump_sys_setsockopt(msgsock, SOL_SOCKET,
|
||||
SO_KEEPALIVE, (char *)&on, sizeof(on), &error) < 0)
|
||||
syslog(LOG_ERR,
|
||||
"setsockopt SO_KEEPALIVE: %m");
|
||||
nfsdargs.sock = msgsock;
|
||||
nfsdargs.name = (caddr_t)&inet6peer;
|
||||
nfsdargs.namelen = sizeof(inet6peer);
|
||||
rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs, &error);
|
||||
(void)rump_sys_close(msgsock, &error);
|
||||
}
|
||||
|
||||
if (set[2].revents & POLLIN) {
|
||||
len = sizeof(isopeer);
|
||||
if ((msgsock = rump_sys_accept(tp4sock,
|
||||
(struct sockaddr *)&isopeer, &len, &error)) < 0) {
|
||||
syslog(LOG_ERR, "accept failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (rump_sys_setsockopt(msgsock, SOL_SOCKET,
|
||||
SO_KEEPALIVE, (char *)&on, sizeof(on), &error) < 0)
|
||||
syslog(LOG_ERR,
|
||||
"setsockopt SO_KEEPALIVE: %m");
|
||||
nfsdargs.sock = msgsock;
|
||||
nfsdargs.name = (caddr_t)&isopeer;
|
||||
nfsdargs.namelen = len;
|
||||
rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs, &error);
|
||||
(void)rump_sys_close(msgsock, &error);
|
||||
}
|
||||
|
||||
if (set[3].revents & POLLIN) {
|
||||
len = sizeof(inetpeer);
|
||||
if ((msgsock = rump_sys_accept(tpipsock,
|
||||
(struct sockaddr *)&inetpeer, &len)) < 0) {
|
||||
syslog(LOG_ERR, "accept failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(msgsock, SOL_SOCKET,
|
||||
SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
|
||||
syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m");
|
||||
nfsdargs.sock = msgsock;
|
||||
nfsdargs.name = (caddr_t)&inetpeer;
|
||||
nfsdargs.namelen = len;
|
||||
rump_sys_nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
|
||||
(void)rump_sys_close(msgsock);
|
||||
}
|
||||
#endif /* notyet */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
nonfs(signo)
|
||||
int signo;
|
||||
{
|
||||
syslog(LOG_ERR, "missing system call: NFS not available.");
|
||||
}
|
15
dist/fs/nfs/nfsservice/rpcbind/Makefile.inc
vendored
15
dist/fs/nfs/nfsservice/rpcbind/Makefile.inc
vendored
@ -1,15 +0,0 @@
|
||||
# $NetBSD: Makefile.inc,v 1.3 2013/03/06 13:36:50 christos Exp $
|
||||
|
||||
SRCS.rumpnfsd+= check_bound.c rpcb_stat.c rpcb_svc_4.c rpcbind.c pmap_svc.c \
|
||||
rpcb_svc.c rpcb_svc_com.c security.c util.c
|
||||
|
||||
LIBRPCDIR= ${NETBSDSRCDIR}/lib/libc/rpc
|
||||
|
||||
CPPFLAGS+= -I${LIBRPCDIR} -DPORTMAP -DLIBWRAP
|
||||
|
||||
# Uncomment these to get any useful output from 'rpcbind -d'
|
||||
# CPPFLAGS+= -DRPCBIND_DEBUG
|
||||
# CPPFLAGS+= -DSVC_RUN_DEBUG
|
||||
|
||||
LDADD+= -lwrap -lutil
|
||||
DPADD+= ${LIBWRAP} ${LIBUTIL}
|
231
dist/fs/nfs/nfsservice/rpcbind/check_bound.c
vendored
231
dist/fs/nfs/nfsservice/rpcbind/check_bound.c
vendored
@ -1,231 +0,0 @@
|
||||
/* $NetBSD: check_bound.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)check_bound.c 1.15 93/07/05 SMI" */
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)check_bound.c 1.11 89/04/21 Copyr 1989 Sun Micro";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* check_bound.c
|
||||
* Checks to see whether the program is still bound to the
|
||||
* claimed address and returns the univeral merged address
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <netconfig.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
#include "rpcbind.h"
|
||||
|
||||
struct fdlist {
|
||||
int fd;
|
||||
struct netconfig *nconf;
|
||||
struct fdlist *next;
|
||||
int check_binding;
|
||||
};
|
||||
|
||||
static struct fdlist *fdhead; /* Link list of the check fd's */
|
||||
static struct fdlist *fdtail;
|
||||
static const char emptystring[] = "";
|
||||
|
||||
static bool_t check_bound(struct fdlist *, const char *uaddr);
|
||||
|
||||
/*
|
||||
* Returns 1 if the given address is bound for the given addr & transport
|
||||
* For all error cases, we assume that the address is bound
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
static bool_t
|
||||
check_bound(struct fdlist *fdl, const char *uaddr)
|
||||
{
|
||||
int fd;
|
||||
struct netbuf *na;
|
||||
int ans;
|
||||
|
||||
if (fdl->check_binding == FALSE)
|
||||
return (TRUE);
|
||||
|
||||
na = uaddr2taddr(fdl->nconf, uaddr);
|
||||
if (!na)
|
||||
return (TRUE); /* punt, should never happen */
|
||||
|
||||
fd = __rpc_nconf2fd(fdl->nconf);
|
||||
if (fd < 0) {
|
||||
free(na);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
ans = bind(fd, (struct sockaddr *)na->buf, na->len);
|
||||
|
||||
rump_sys_close(fd);
|
||||
free(na);
|
||||
|
||||
return (ans == 0 ? FALSE : TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
add_bndlist(struct netconfig *nconf, struct netbuf *baddr)
|
||||
{
|
||||
struct fdlist *fdl;
|
||||
struct netconfig *newnconf;
|
||||
|
||||
newnconf = getnetconfigent(nconf->nc_netid);
|
||||
if (newnconf == NULL)
|
||||
return (-1);
|
||||
fdl = (struct fdlist *)malloc((u_int)sizeof (struct fdlist));
|
||||
if (fdl == NULL) {
|
||||
freenetconfigent(newnconf);
|
||||
syslog(LOG_ERR, "no memory!");
|
||||
return (-1);
|
||||
}
|
||||
fdl->nconf = newnconf;
|
||||
fdl->next = NULL;
|
||||
if (fdhead == NULL) {
|
||||
fdhead = fdl;
|
||||
fdtail = fdl;
|
||||
} else {
|
||||
fdtail->next = fdl;
|
||||
fdtail = fdl;
|
||||
}
|
||||
/* XXX no bound checking for now */
|
||||
fdl->check_binding = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t
|
||||
is_bound(const char *netid, const char *uaddr)
|
||||
{
|
||||
struct fdlist *fdl;
|
||||
|
||||
for (fdl = fdhead; fdl; fdl = fdl->next)
|
||||
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
|
||||
break;
|
||||
if (fdl == NULL)
|
||||
return (TRUE);
|
||||
return (check_bound(fdl, uaddr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns NULL if there was some system error.
|
||||
* Returns "" if the address was not bound, i.e the server crashed.
|
||||
* Returns the merged address otherwise.
|
||||
*/
|
||||
char *
|
||||
mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
|
||||
{
|
||||
struct fdlist *fdl;
|
||||
char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL;
|
||||
|
||||
for (fdl = fdhead; fdl; fdl = fdl->next)
|
||||
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
|
||||
break;
|
||||
if (fdl == NULL)
|
||||
return (NULL);
|
||||
if (check_bound(fdl, uaddr) == FALSE)
|
||||
/* that server died */
|
||||
return strdup(emptystring);
|
||||
/*
|
||||
* If saddr is not NULL, the remote client may have included the
|
||||
* address by which it contacted us. Use that for the "client" uaddr,
|
||||
* otherwise use the info from the SVCXPRT.
|
||||
*/
|
||||
if (saddr != NULL) {
|
||||
c_uaddr = saddr;
|
||||
} else {
|
||||
c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
|
||||
if (c_uaddr == NULL) {
|
||||
syslog(LOG_ERR, "taddr2uaddr failed for %s",
|
||||
fdl->nconf->nc_netid);
|
||||
return (NULL);
|
||||
}
|
||||
allocated_uaddr = c_uaddr;
|
||||
}
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
if (saddr == NULL) {
|
||||
fprintf(stderr, "mergeaddr: client uaddr = %s\n",
|
||||
c_uaddr);
|
||||
} else {
|
||||
fprintf(stderr, "mergeaddr: contact uaddr = %s\n",
|
||||
c_uaddr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
s_uaddr = uaddr;
|
||||
/*
|
||||
* This is all we should need for IP 4 and 6
|
||||
*/
|
||||
m_uaddr = addrmerge(svc_getrpccaller(xprt), s_uaddr, c_uaddr, netid);
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n",
|
||||
uaddr, m_uaddr);
|
||||
#endif
|
||||
if (allocated_uaddr != NULL)
|
||||
free(allocated_uaddr);
|
||||
return (m_uaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a netconf structure from its internal list. This
|
||||
* structure should not be freed.
|
||||
*/
|
||||
struct netconfig *
|
||||
rpcbind_get_conf(const char *netid)
|
||||
{
|
||||
struct fdlist *fdl;
|
||||
|
||||
for (fdl = fdhead; fdl; fdl = fdl->next)
|
||||
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
|
||||
break;
|
||||
if (fdl == NULL)
|
||||
return (NULL);
|
||||
return (fdl->nconf);
|
||||
}
|
366
dist/fs/nfs/nfsservice/rpcbind/pmap_svc.c
vendored
366
dist/fs/nfs/nfsservice/rpcbind/pmap_svc.c
vendored
@ -1,366 +0,0 @@
|
||||
/* $NetBSD: pmap_svc.c,v 1.2 2013/10/19 17:45:00 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)pmap_svc.c 1.14 93/07/05 SMI" */
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)pmap_svc.c 1.23 89/04/05 Copyr 1984 Sun Micro";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pmap_svc.c
|
||||
* The server procedure for the version 2 portmapper.
|
||||
* All the portmapper related interface from the portmap side.
|
||||
*/
|
||||
|
||||
#ifdef PORTMAP
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
#ifdef RPCBIND_DEBUG
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "rpcbind.h"
|
||||
|
||||
static struct pmaplist *find_service_pmap(rpcprog_t, rpcvers_t, rpcprot_t);
|
||||
static bool_t pmapproc_change(struct svc_req *, SVCXPRT *, u_long);
|
||||
static bool_t pmapproc_getport(struct svc_req *, SVCXPRT *);
|
||||
static bool_t pmapproc_dump(struct svc_req *, SVCXPRT *);
|
||||
|
||||
/*
|
||||
* Called for all the version 2 inquiries.
|
||||
*/
|
||||
void
|
||||
pmap_service(struct svc_req *rqstp, SVCXPRT *xprt)
|
||||
{
|
||||
rpcbs_procinfo(RPCBVERS_2_STAT, rqstp->rq_proc);
|
||||
switch (rqstp->rq_proc) {
|
||||
case PMAPPROC_NULL:
|
||||
/*
|
||||
* Null proc call
|
||||
*/
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "PMAPPROC_NULL\n");
|
||||
#endif
|
||||
check_access(xprt, rqstp->rq_proc, NULL, PMAPVERS);
|
||||
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_void, NULL)) &&
|
||||
debugging) {
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PMAPPROC_SET:
|
||||
/*
|
||||
* Set a program, version to port mapping
|
||||
*/
|
||||
pmapproc_change(rqstp, xprt, rqstp->rq_proc);
|
||||
break;
|
||||
|
||||
case PMAPPROC_UNSET:
|
||||
/*
|
||||
* Remove a program, version to port mapping.
|
||||
*/
|
||||
pmapproc_change(rqstp, xprt, rqstp->rq_proc);
|
||||
break;
|
||||
|
||||
case PMAPPROC_GETPORT:
|
||||
/*
|
||||
* Lookup the mapping for a program, version and return its
|
||||
* port number.
|
||||
*/
|
||||
pmapproc_getport(rqstp, xprt);
|
||||
break;
|
||||
|
||||
case PMAPPROC_DUMP:
|
||||
/*
|
||||
* Return the current set of mapped program, version
|
||||
*/
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "PMAPPROC_DUMP\n");
|
||||
#endif
|
||||
pmapproc_dump(rqstp, xprt);
|
||||
break;
|
||||
|
||||
case PMAPPROC_CALLIT:
|
||||
/*
|
||||
* Calls a procedure on the local machine. If the requested
|
||||
* procedure is not registered this procedure does not return
|
||||
* error information!!
|
||||
* This procedure is only supported on rpc/udp and calls via
|
||||
* rpc/udp. It passes null authentication parameters.
|
||||
*/
|
||||
rpcbproc_callit_com(rqstp, xprt, PMAPPROC_CALLIT, PMAPVERS);
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(xprt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the item with the given program, version number. If that version
|
||||
* number is not found, it returns the item with that program number, so that
|
||||
* the port number is now returned to the caller. The caller when makes a
|
||||
* call to this program, version number, the call will fail and it will
|
||||
* return with PROGVERS_MISMATCH. The user can then determine the highest
|
||||
* and the lowest version number for this program using clnt_geterr() and
|
||||
* use those program version numbers.
|
||||
*/
|
||||
static struct pmaplist *
|
||||
find_service_pmap(rpcprog_t prog, rpcvers_t vers, rpcprot_t prot)
|
||||
{
|
||||
register struct pmaplist *hit = NULL;
|
||||
register struct pmaplist *pml;
|
||||
|
||||
for (pml = list_pml; pml != NULL; pml = pml->pml_next) {
|
||||
if ((pml->pml_map.pm_prog != prog) ||
|
||||
(pml->pml_map.pm_prot != prot))
|
||||
continue;
|
||||
hit = pml;
|
||||
if (pml->pml_map.pm_vers == vers)
|
||||
break;
|
||||
}
|
||||
return (hit);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
|
||||
{
|
||||
struct pmap reg;
|
||||
RPCB rpcbreg;
|
||||
long ans;
|
||||
struct sockcred *sc;
|
||||
char uidbuf[32];
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "%s request for (%lu, %lu) : ",
|
||||
op == PMAPPROC_SET ? "PMAP_SET" : "PMAP_UNSET",
|
||||
reg.pm_prog, reg.pm_vers);
|
||||
#endif
|
||||
|
||||
if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) {
|
||||
svcerr_decode(xprt);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!check_access(xprt, op, ®, PMAPVERS)) {
|
||||
svcerr_weakauth(xprt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(void)svc_getcaller(xprt);
|
||||
sc = __svc_getcallercreds(xprt);
|
||||
|
||||
/*
|
||||
* Can't use getpwnam here. We might end up calling ourselves
|
||||
* and looping.
|
||||
*/
|
||||
if (sc == NULL)
|
||||
rpcbreg.r_owner = __UNCONST(rpcbind_unknown);
|
||||
else if (sc->sc_uid == 0)
|
||||
rpcbreg.r_owner = __UNCONST(rpcbind_superuser);
|
||||
else {
|
||||
/* r_owner will be strdup-ed later */
|
||||
snprintf(uidbuf, sizeof uidbuf, "%d", sc->sc_uid);
|
||||
rpcbreg.r_owner = uidbuf;
|
||||
}
|
||||
|
||||
rpcbreg.r_prog = reg.pm_prog;
|
||||
rpcbreg.r_vers = reg.pm_vers;
|
||||
|
||||
if (op == PMAPPROC_SET) {
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof(buf), "0.0.0.0.%d.%d",
|
||||
(int)((reg.pm_port >> 8) & 0xff),
|
||||
(int)(reg.pm_port & 0xff));
|
||||
rpcbreg.r_addr = buf;
|
||||
if (reg.pm_prot == IPPROTO_UDP) {
|
||||
rpcbreg.r_netid = __UNCONST(udptrans);
|
||||
} else if (reg.pm_prot == IPPROTO_TCP) {
|
||||
rpcbreg.r_netid = __UNCONST(tcptrans);
|
||||
} else {
|
||||
ans = FALSE;
|
||||
goto done_change;
|
||||
}
|
||||
ans = map_set(&rpcbreg, rpcbreg.r_owner);
|
||||
} else if (op == PMAPPROC_UNSET) {
|
||||
bool_t ans1, ans2;
|
||||
|
||||
rpcbreg.r_addr = NULL;
|
||||
rpcbreg.r_netid = __UNCONST(tcptrans);
|
||||
ans1 = map_unset(&rpcbreg, rpcbreg.r_owner);
|
||||
rpcbreg.r_netid = __UNCONST(udptrans);
|
||||
ans2 = map_unset(&rpcbreg, rpcbreg.r_owner);
|
||||
ans = ans1 || ans2;
|
||||
} else {
|
||||
ans = FALSE;
|
||||
}
|
||||
done_change:
|
||||
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t) &ans)) &&
|
||||
debugging) {
|
||||
fprintf(stderr, "portmap: svc_sendreply\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed");
|
||||
#endif
|
||||
if (op == PMAPPROC_SET)
|
||||
rpcbs_set(RPCBVERS_2_STAT, ans);
|
||||
else
|
||||
rpcbs_unset(RPCBVERS_2_STAT, ans);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static bool_t
|
||||
pmapproc_getport(struct svc_req *rqstp, SVCXPRT *xprt)
|
||||
{
|
||||
struct pmap reg;
|
||||
long lport;
|
||||
int port = 0;
|
||||
struct pmaplist *fnd;
|
||||
#ifdef RPCBIND_DEBUG
|
||||
char *uaddr;
|
||||
#endif
|
||||
|
||||
if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) {
|
||||
svcerr_decode(xprt);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!check_access(xprt, PMAPPROC_GETPORT, ®, PMAPVERS)) {
|
||||
svcerr_weakauth(xprt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
uaddr = taddr2uaddr(rpcbind_get_conf(xprt->xp_netid),
|
||||
svc_getrpccaller(xprt));
|
||||
fprintf(stderr, "PMAP_GETPORT req for (%lu, %lu, %s) from %s :",
|
||||
reg.pm_prog, reg.pm_vers,
|
||||
reg.pm_prot == IPPROTO_UDP ? "udp" : "tcp", uaddr);
|
||||
free(uaddr);
|
||||
}
|
||||
#endif
|
||||
fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot);
|
||||
if (fnd) {
|
||||
char serveuaddr[32];
|
||||
int h1, h2, h3, h4, p1, p2;
|
||||
const char *netid, *ua;
|
||||
|
||||
if (reg.pm_prot == IPPROTO_UDP) {
|
||||
ua = udp_uaddr;
|
||||
netid = udptrans;
|
||||
} else {
|
||||
ua = tcp_uaddr; /* To get the len */
|
||||
netid = tcptrans;
|
||||
}
|
||||
if (ua == NULL) {
|
||||
goto sendreply;
|
||||
}
|
||||
if (sscanf(ua, "%d.%d.%d.%d.%d.%d", &h1, &h2, &h3,
|
||||
&h4, &p1, &p2) == 6) {
|
||||
p1 = (fnd->pml_map.pm_port >> 8) & 0xff;
|
||||
p2 = (fnd->pml_map.pm_port) & 0xff;
|
||||
snprintf(serveuaddr, sizeof(serveuaddr),
|
||||
"%d.%d.%d.%d.%d.%d", h1, h2, h3, h4, p1, p2);
|
||||
if (is_bound(netid, serveuaddr)) {
|
||||
port = fnd->pml_map.pm_port;
|
||||
} else { /* this service is dead; delete it */
|
||||
delete_prog(reg.pm_prog);
|
||||
}
|
||||
}
|
||||
}
|
||||
sendreply:
|
||||
lport = port;
|
||||
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&lport)) &&
|
||||
debugging) {
|
||||
(void) fprintf(stderr, "portmap: svc_sendreply\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "port = %d\n", port);
|
||||
#endif
|
||||
rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers,
|
||||
reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans,
|
||||
port ? udptrans : "");
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static bool_t
|
||||
pmapproc_dump(struct svc_req *rqstp, SVCXPRT *xprt)
|
||||
{
|
||||
if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) {
|
||||
svcerr_decode(xprt);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!check_access(xprt, PMAPPROC_DUMP, NULL, PMAPVERS)) {
|
||||
svcerr_weakauth(xprt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist_ptr,
|
||||
(caddr_t)&list_pml)) && debugging) {
|
||||
if (debugging)
|
||||
(void) fprintf(stderr, "portmap: svc_sendreply\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* PORTMAP */
|
206
dist/fs/nfs/nfsservice/rpcbind/rpcb_stat.c
vendored
206
dist/fs/nfs/nfsservice/rpcbind/rpcb_stat.c
vendored
@ -1,206 +0,0 @@
|
||||
/* $NetBSD: rpcb_stat.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/* #pragma ident "@(#)rpcb_stat.c 1.7 94/04/25 SMI" */
|
||||
|
||||
/*
|
||||
* rpcb_stat.c
|
||||
* Allows for gathering of statistics
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netconfig.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef PORTMAP
|
||||
#include <rpc/pmap_prot.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rpcbind.h"
|
||||
|
||||
static rpcb_stat_byvers inf;
|
||||
|
||||
void
|
||||
rpcbs_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
rpcbs_procinfo(rpcvers_t rtype, rpcproc_t proc)
|
||||
{
|
||||
switch (rtype + 2) {
|
||||
#ifdef PORTMAP
|
||||
case PMAPVERS: /* version 2 */
|
||||
if (proc > rpcb_highproc_2)
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
case RPCBVERS: /* version 3 */
|
||||
if (proc > rpcb_highproc_3)
|
||||
return;
|
||||
break;
|
||||
case RPCBVERS4: /* version 4 */
|
||||
if (proc > rpcb_highproc_4)
|
||||
return;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
inf[rtype].info[proc]++;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
rpcbs_set(rpcvers_t rtype, bool_t success)
|
||||
{
|
||||
if ((rtype >= RPCBVERS_STAT) || (success == FALSE))
|
||||
return;
|
||||
inf[rtype].setinfo++;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
rpcbs_unset(rpcvers_t rtype, bool_t success)
|
||||
{
|
||||
if ((rtype >= RPCBVERS_STAT) || (success == FALSE))
|
||||
return;
|
||||
inf[rtype].unsetinfo++;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
rpcbs_getaddr(rpcvers_t rtype, rpcprog_t prog, rpcvers_t vers,
|
||||
const char *netid, const char *uaddr)
|
||||
{
|
||||
rpcbs_addrlist *al;
|
||||
struct netconfig *nconf;
|
||||
|
||||
if (rtype >= RPCBVERS_STAT)
|
||||
return;
|
||||
for (al = inf[rtype].addrinfo; al; al = al->next) {
|
||||
|
||||
if(al->netid == NULL)
|
||||
return;
|
||||
if ((al->prog == prog) && (al->vers == vers) &&
|
||||
(strcmp(al->netid, netid) == 0)) {
|
||||
if ((uaddr == NULL) || (uaddr[0] == 0))
|
||||
al->failure++;
|
||||
else
|
||||
al->success++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
nconf = rpcbind_get_conf(netid);
|
||||
if (nconf == NULL) {
|
||||
return;
|
||||
}
|
||||
al = (rpcbs_addrlist *) malloc(sizeof (rpcbs_addrlist));
|
||||
if (al == NULL) {
|
||||
return;
|
||||
}
|
||||
al->prog = prog;
|
||||
al->vers = vers;
|
||||
al->netid = nconf->nc_netid;
|
||||
if ((uaddr == NULL) || (uaddr[0] == 0)) {
|
||||
al->failure = 1;
|
||||
al->success = 0;
|
||||
} else {
|
||||
al->failure = 0;
|
||||
al->success = 1;
|
||||
}
|
||||
al->next = inf[rtype].addrinfo;
|
||||
inf[rtype].addrinfo = al;
|
||||
}
|
||||
|
||||
void
|
||||
rpcbs_rmtcall(rpcvers_t rtype, rpcproc_t rpcbproc, rpcprog_t prog,
|
||||
rpcvers_t vers, rpcproc_t proc, char *netid, rpcblist_ptr rbl)
|
||||
{
|
||||
rpcbs_rmtcalllist *rl;
|
||||
struct netconfig *nconf;
|
||||
|
||||
if (rtype >= RPCBVERS_STAT)
|
||||
return;
|
||||
for (rl = inf[rtype].rmtinfo; rl; rl = rl->next) {
|
||||
|
||||
if(rl->netid == NULL)
|
||||
return;
|
||||
|
||||
if ((rl->prog == prog) && (rl->vers == vers) &&
|
||||
(rl->proc == proc) &&
|
||||
(strcmp(rl->netid, netid) == 0)) {
|
||||
if ((rbl == NULL) ||
|
||||
(rbl->rpcb_map.r_vers != vers))
|
||||
rl->failure++;
|
||||
else
|
||||
rl->success++;
|
||||
if (rpcbproc == RPCBPROC_INDIRECT)
|
||||
rl->indirect++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
nconf = rpcbind_get_conf(netid);
|
||||
if (nconf == NULL) {
|
||||
return;
|
||||
}
|
||||
rl = (rpcbs_rmtcalllist *) malloc(sizeof (rpcbs_rmtcalllist));
|
||||
if (rl == NULL) {
|
||||
return;
|
||||
}
|
||||
rl->prog = prog;
|
||||
rl->vers = vers;
|
||||
rl->proc = proc;
|
||||
rl->netid = nconf->nc_netid;
|
||||
if ((rbl == NULL) ||
|
||||
(rbl->rpcb_map.r_vers != vers)) {
|
||||
rl->failure = 1;
|
||||
rl->success = 0;
|
||||
} else {
|
||||
rl->failure = 0;
|
||||
rl->success = 1;
|
||||
}
|
||||
rl->indirect = 1;
|
||||
rl->next = inf[rtype].rmtinfo;
|
||||
inf[rtype].rmtinfo = rl;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
void *
|
||||
rpcbproc_getstat(void *arg, struct svc_req *req, SVCXPRT *xprt,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
return (void *)&inf;
|
||||
}
|
232
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc.c
vendored
232
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc.c
vendored
@ -1,232 +0,0 @@
|
||||
/* $NetBSD: rpcb_svc.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)rpcb_svc.c 1.16 93/07/05 SMI" */
|
||||
|
||||
/*
|
||||
* rpcb_svc.c
|
||||
* The server procedure for the version 3 rpcbind (TLI).
|
||||
*
|
||||
* It maintains a separate list of all the registered services with the
|
||||
* version 3 of rpcbind.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
#include <netconfig.h>
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rpcbind.h"
|
||||
|
||||
static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
|
||||
/*
|
||||
* Called by svc_getreqset. There is a separate server handle for
|
||||
* every transport that it waits on.
|
||||
*/
|
||||
void
|
||||
rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
RPCB rpcbproc_set_3_arg;
|
||||
RPCB rpcbproc_unset_3_arg;
|
||||
RPCB rpcbproc_getaddr_3_local_arg;
|
||||
struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
|
||||
char *rpcbproc_uaddr2taddr_3_arg;
|
||||
struct netbuf rpcbproc_taddr2uaddr_3_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t xdr_argument, xdr_result;
|
||||
void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
|
||||
|
||||
rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
/*
|
||||
* Null proc call
|
||||
*/
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_NULL\n");
|
||||
#endif
|
||||
/* This call just logs, no actual checks */
|
||||
check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
|
||||
(void) svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
|
||||
return;
|
||||
|
||||
case RPCBPROC_SET:
|
||||
xdr_argument = (xdrproc_t )xdr_rpcb;
|
||||
xdr_result = (xdrproc_t )xdr_bool;
|
||||
local = rpcbproc_set_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_UNSET:
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_bool;
|
||||
local = rpcbproc_unset_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_GETADDR:
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_wrapstring;
|
||||
local = rpcbproc_getaddr_3_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_DUMP:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_DUMP\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_void;
|
||||
xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
|
||||
local = rpcbproc_dump_3_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_CALLIT:
|
||||
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
|
||||
return;
|
||||
|
||||
case RPCBPROC_GETTIME:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_GETTIME\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_void;
|
||||
xdr_result = (xdrproc_t)xdr_u_long;
|
||||
local = rpcbproc_gettime_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_UADDR2TADDR:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_wrapstring;
|
||||
xdr_result = (xdrproc_t)xdr_netbuf;
|
||||
local = rpcbproc_uaddr2taddr_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_TADDR2UADDR:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_netbuf;
|
||||
xdr_result = (xdrproc_t)xdr_wrapstring;
|
||||
local = rpcbproc_taddr2uaddr_com;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
(void) memset((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
|
||||
(char *) &argument)) {
|
||||
svcerr_decode(transp);
|
||||
if (debugging)
|
||||
(void) fprintf(stderr, "rpcbind: could not decode\n");
|
||||
return;
|
||||
}
|
||||
if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
|
||||
svcerr_weakauth(transp);
|
||||
goto done;
|
||||
}
|
||||
result = (*local)(&argument, rqstp, transp, RPCBVERS);
|
||||
if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
|
||||
result)) {
|
||||
svcerr_systemerr(transp);
|
||||
if (debugging) {
|
||||
(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
|
||||
&argument)) {
|
||||
if (debugging) {
|
||||
(void) fprintf(stderr, "unable to free arguments\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the mapping for a program, version and return its
|
||||
* address. Assuming that the caller wants the address of the
|
||||
* server running on the transport on which the request came.
|
||||
*
|
||||
* We also try to resolve the universal address in terms of
|
||||
* address of the caller.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
RPCB *regp = (RPCB *)arg;
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
char *uaddr;
|
||||
|
||||
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
|
||||
svc_getrpccaller(transp));
|
||||
fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
|
||||
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
|
||||
regp->r_netid, uaddr);
|
||||
free(uaddr);
|
||||
}
|
||||
#endif
|
||||
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
|
||||
RPCB_ALLVERS));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_dump_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
return ((void *)&list_rbl);
|
||||
}
|
455
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc_4.c
vendored
455
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc_4.c
vendored
@ -1,455 +0,0 @@
|
||||
/* $NetBSD: rpcb_svc_4.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */
|
||||
|
||||
/*
|
||||
* rpcb_svc_4.c
|
||||
* The server procedure for the version 4 rpcbind.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <netconfig.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "rpcbind.h"
|
||||
|
||||
static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
|
||||
static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
|
||||
/*
|
||||
* Called by svc_getreqset. There is a separate server handle for
|
||||
* every transport that it waits on.
|
||||
*/
|
||||
void
|
||||
rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
rpcb rpcbproc_set_4_arg;
|
||||
rpcb rpcbproc_unset_4_arg;
|
||||
rpcb rpcbproc_getaddr_4_local_arg;
|
||||
char *rpcbproc_uaddr2taddr_4_arg;
|
||||
struct netbuf rpcbproc_taddr2uaddr_4_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t xdr_argument, xdr_result;
|
||||
void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
|
||||
|
||||
rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
/*
|
||||
* Null proc call
|
||||
*/
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_NULL\n");
|
||||
#endif
|
||||
check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
|
||||
(void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
|
||||
return;
|
||||
|
||||
case RPCBPROC_SET:
|
||||
/*
|
||||
* Check to see whether the message came from
|
||||
* loopback transports (for security reasons)
|
||||
*/
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_bool;
|
||||
local = rpcbproc_set_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_UNSET:
|
||||
/*
|
||||
* Check to see whether the message came from
|
||||
* loopback transports (for security reasons)
|
||||
*/
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_bool;
|
||||
local = rpcbproc_unset_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_GETADDR:
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_wrapstring;
|
||||
local = rpcbproc_getaddr_4_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_GETVERSADDR:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_wrapstring;
|
||||
local = rpcbproc_getversaddr_4_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_DUMP:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_DUMP\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_void;
|
||||
xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
|
||||
local = rpcbproc_dump_4_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_INDIRECT:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_INDIRECT\n");
|
||||
#endif
|
||||
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
|
||||
return;
|
||||
|
||||
/* case RPCBPROC_CALLIT: */
|
||||
case RPCBPROC_BCAST:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_BCAST\n");
|
||||
#endif
|
||||
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
|
||||
return;
|
||||
|
||||
case RPCBPROC_GETTIME:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_GETTIME\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_void;
|
||||
xdr_result = (xdrproc_t)xdr_u_long;
|
||||
local = rpcbproc_gettime_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_UADDR2TADDR:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_wrapstring;
|
||||
xdr_result = (xdrproc_t)xdr_netbuf;
|
||||
local = rpcbproc_uaddr2taddr_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_TADDR2UADDR:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_netbuf;
|
||||
xdr_result = (xdrproc_t)xdr_wrapstring;
|
||||
local = rpcbproc_taddr2uaddr_com;
|
||||
break;
|
||||
|
||||
case RPCBPROC_GETADDRLIST:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_rpcb;
|
||||
xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
|
||||
local = rpcbproc_getaddrlist_4_local;
|
||||
break;
|
||||
|
||||
case RPCBPROC_GETSTAT:
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "RPCBPROC_GETSTAT\n");
|
||||
#endif
|
||||
xdr_argument = (xdrproc_t)xdr_void;
|
||||
xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
|
||||
local = rpcbproc_getstat;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
memset((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
|
||||
(char *)&argument)) {
|
||||
svcerr_decode(transp);
|
||||
if (debugging)
|
||||
(void) fprintf(stderr, "rpcbind: could not decode\n");
|
||||
return;
|
||||
}
|
||||
if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
|
||||
svcerr_weakauth(transp);
|
||||
goto done;
|
||||
}
|
||||
result = (*local)(&argument, rqstp, transp, RPCBVERS4);
|
||||
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
|
||||
result)) {
|
||||
svcerr_systemerr(transp);
|
||||
if (debugging) {
|
||||
(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
|
||||
(char *)&argument)) {
|
||||
if (debugging) {
|
||||
(void) fprintf(stderr, "unable to free arguments\n");
|
||||
if (doabort) {
|
||||
rpcbind_abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the mapping for a program, version and return its
|
||||
* address. Assuming that the caller wants the address of the
|
||||
* server running on the transport on which the request came.
|
||||
* Even if a service with a different version number is available,
|
||||
* it will return that address. The client should check with an
|
||||
* clnt_call to verify whether the service is the one that is desired.
|
||||
* We also try to resolve the universal address in terms of
|
||||
* address of the caller.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
|
||||
rpcvers_t rpcbversnum)
|
||||
{
|
||||
RPCB *regp = (RPCB *)arg;
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
char *uaddr;
|
||||
|
||||
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
|
||||
svc_getrpccaller(transp));
|
||||
fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
|
||||
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
|
||||
regp->r_netid, uaddr);
|
||||
free(uaddr);
|
||||
}
|
||||
#endif
|
||||
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
|
||||
RPCB_ALLVERS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the mapping for a program, version and return its
|
||||
* address. Assuming that the caller wants the address of the
|
||||
* server running on the transport on which the request came.
|
||||
*
|
||||
* We also try to resolve the universal address in terms of
|
||||
* address of the caller.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
RPCB *regp = (RPCB *)arg;
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
char *uaddr;
|
||||
|
||||
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
|
||||
svc_getrpccaller(transp));
|
||||
fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
|
||||
" from %s : ",
|
||||
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
|
||||
regp->r_netid, uaddr);
|
||||
free(uaddr);
|
||||
}
|
||||
#endif
|
||||
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
|
||||
RPCB_ONEVERS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the mapping for a program, version and return the
|
||||
* addresses for all transports in the current transport family.
|
||||
* We return a merged address.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
RPCB *regp = (RPCB *)arg;
|
||||
static rpcb_entry_list_ptr rlist;
|
||||
register rpcblist_ptr rbl;
|
||||
rpcb_entry_list_ptr rp, tail = NULL;
|
||||
rpcprog_t prog;
|
||||
rpcvers_t vers;
|
||||
rpcb_entry *a;
|
||||
struct netconfig *nconf;
|
||||
struct netconfig *reg_nconf;
|
||||
char *saddr, *maddr = NULL;
|
||||
|
||||
free_rpcb_entry_list(&rlist);
|
||||
prog = regp->r_prog;
|
||||
vers = regp->r_vers;
|
||||
reg_nconf = rpcbind_get_conf(transp->xp_netid);
|
||||
if (reg_nconf == NULL)
|
||||
return (NULL);
|
||||
if (*(regp->r_addr) != '\0') {
|
||||
saddr = regp->r_addr;
|
||||
} else {
|
||||
saddr = NULL;
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
|
||||
regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
|
||||
}
|
||||
#endif
|
||||
for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
|
||||
if ((rbl->rpcb_map.r_prog == prog) &&
|
||||
(rbl->rpcb_map.r_vers == vers)) {
|
||||
nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
|
||||
if (nconf == NULL)
|
||||
goto fail;
|
||||
if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
|
||||
!= 0) {
|
||||
continue; /* not same proto family */
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr);
|
||||
#endif
|
||||
if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
|
||||
rbl->rpcb_map.r_addr, saddr)) == NULL) {
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, " FAILED\n");
|
||||
#endif
|
||||
continue;
|
||||
} else if (!maddr[0]) {
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n");
|
||||
#endif
|
||||
/* The server died. Unset this combination */
|
||||
delete_prog(regp->r_prog);
|
||||
free(maddr);
|
||||
continue;
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
|
||||
#endif
|
||||
/*
|
||||
* Add it to rlist.
|
||||
*/
|
||||
rp = (rpcb_entry_list_ptr)
|
||||
malloc((u_int)sizeof (rpcb_entry_list));
|
||||
if (rp == NULL) {
|
||||
free(maddr);
|
||||
goto fail;
|
||||
}
|
||||
a = &rp->rpcb_entry_map;
|
||||
a->r_maddr = maddr;
|
||||
a->r_nc_netid = nconf->nc_netid;
|
||||
a->r_nc_semantics = nconf->nc_semantics;
|
||||
a->r_nc_protofmly = nconf->nc_protofmly;
|
||||
a->r_nc_proto = nconf->nc_proto;
|
||||
rp->rpcb_entry_next = NULL;
|
||||
if (rlist == NULL) {
|
||||
rlist = rp;
|
||||
tail = rp;
|
||||
} else if (tail) {
|
||||
tail->rpcb_entry_next = rp;
|
||||
tail = rp;
|
||||
}
|
||||
rp = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
|
||||
fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
|
||||
rp->rpcb_entry_map.r_nc_proto);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* XXX: getaddrlist info is also being stuffed into getaddr.
|
||||
* Perhaps wrong, but better than it not getting counted at all.
|
||||
*/
|
||||
rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
|
||||
return (void *)&rlist;
|
||||
|
||||
fail: free_rpcb_entry_list(&rlist);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free only the allocated structure, rest is all a pointer to some
|
||||
* other data somewhere else.
|
||||
*/
|
||||
static void
|
||||
free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
|
||||
{
|
||||
register rpcb_entry_list_ptr rbl, tmp;
|
||||
|
||||
for (rbl = *rlistp; rbl != NULL; ) {
|
||||
tmp = rbl;
|
||||
rbl = rbl->rpcb_entry_next;
|
||||
free((char *)tmp->rpcb_entry_map.r_maddr);
|
||||
free((char *)tmp);
|
||||
}
|
||||
*rlistp = NULL;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void *
|
||||
rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt,
|
||||
rpcvers_t versnum)
|
||||
{
|
||||
return ((void *)&list_rbl);
|
||||
}
|
1460
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc_com.c
vendored
1460
dist/fs/nfs/nfsservice/rpcbind/rpcb_svc_com.c
vendored
File diff suppressed because it is too large
Load Diff
127
dist/fs/nfs/nfsservice/rpcbind/rpcbind.8
vendored
127
dist/fs/nfs/nfsservice/rpcbind/rpcbind.8
vendored
@ -1,127 +0,0 @@
|
||||
.\" $NetBSD: rpcbind.8,v 1.1 2010/07/26 15:53:00 pooka Exp $
|
||||
.\" @(#)rpcbind.1m 1.19 92/09/14 SMI; from SVr4
|
||||
.\" Copyright 1989 AT&T
|
||||
.\" Copyright 1991 Sun Microsystems, Inc.
|
||||
.Dd October 19, 2008
|
||||
.Dt RPCBIND 8
|
||||
.Sh NAME
|
||||
.Nm rpcbind
|
||||
.Nd universal addresses to RPC program number mapper
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dilLs
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a server that converts
|
||||
.Tn RPC
|
||||
program numbers into
|
||||
universal addresses.
|
||||
It must be running on the host to be able to make
|
||||
.Tn RPC
|
||||
calls
|
||||
on a server on that machine.
|
||||
.Pp
|
||||
When an
|
||||
.Tn RPC
|
||||
service is started,
|
||||
it tells
|
||||
.Nm
|
||||
the address at which it is listening,
|
||||
and the
|
||||
.Tn RPC
|
||||
program numbers it is prepared to serve.
|
||||
When a client wishes to make an
|
||||
.Tn RPC
|
||||
call to a given program number,
|
||||
it first contacts
|
||||
.Nm
|
||||
on the server machine to determine
|
||||
the address where
|
||||
.Tn RPC
|
||||
requests should be sent.
|
||||
.Pp
|
||||
.Nm
|
||||
should be started before any other RPC service.
|
||||
Normally, standard
|
||||
.Tn RPC
|
||||
servers are started by port monitors, so
|
||||
.Nm
|
||||
must be started before port monitors are invoked.
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
is started, it checks that certain name-to-address
|
||||
translation-calls function correctly.
|
||||
If they fail, the network configuration databases may be corrupt.
|
||||
Since
|
||||
.Tn RPC
|
||||
services cannot function correctly in this situation,
|
||||
.Nm
|
||||
reports the condition and terminates.
|
||||
.Pp
|
||||
.Nm
|
||||
can only be started by the super-user.
|
||||
.Pp
|
||||
Access control is provided by
|
||||
.Pa /etc/hosts.allow
|
||||
and
|
||||
.Pa /etc/hosts.deny ,
|
||||
as described in
|
||||
.Xr hosts_access 5
|
||||
with daemon name
|
||||
.Nm .
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d
|
||||
Run in debug mode.
|
||||
In this mode,
|
||||
.Nm
|
||||
will not fork when it starts, will print additional information
|
||||
during operation, and will abort on certain errors.
|
||||
With this option, the name-to-address translation consistency
|
||||
checks are shown in detail.
|
||||
.It Fl i
|
||||
.Dq insecure
|
||||
mode.
|
||||
Allows calls to SET and UNSET from any host.
|
||||
Normally
|
||||
.Nm
|
||||
accepts these requests only from the loopback interface for security reasons.
|
||||
This change is necessary for programs that were compiled with earlier
|
||||
versions of the rpc library and do not make those requests using the
|
||||
loopback interface.
|
||||
.It Fl l
|
||||
Turns on libwrap connection logging.
|
||||
.It Fl s
|
||||
Causes
|
||||
.Nm
|
||||
to change to the user daemon as soon as possible.
|
||||
This causes
|
||||
.Nm
|
||||
to use non-privileged ports for outgoing connections, preventing non-privileged
|
||||
clients from using
|
||||
.Nm
|
||||
to connect to services from a privileged port.
|
||||
.It Fl L
|
||||
Allow old-style local connections over the loopback interface.
|
||||
Without this flag, local connections are only allowed over a local socket,
|
||||
.Pa /var/run/rpcbind.sock
|
||||
.El
|
||||
.Sh NOTES
|
||||
All RPC servers must be restarted if
|
||||
.Nm
|
||||
is restarted.
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/var/run/rpcbind.sock" -compact
|
||||
.It Pa /var/run/rpcbind.sock
|
||||
.It Pa /etc/hosts.allow
|
||||
explicit remote host access list.
|
||||
.It Pa /etc/hosts.deny
|
||||
explicit remote host denial of service list.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rpcbind 3 ,
|
||||
.Xr hosts_access 5 ,
|
||||
.Xr hosts_options 5 ,
|
||||
.Xr netconfig 5 ,
|
||||
.Xr rpcinfo 8
|
613
dist/fs/nfs/nfsservice/rpcbind/rpcbind.c
vendored
613
dist/fs/nfs/nfsservice/rpcbind/rpcbind.c
vendored
@ -1,613 +0,0 @@
|
||||
/* $NetBSD: rpcbind.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)rpcbind.c 1.19 94/04/25 SMI" */
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpcbind.c 1.35 89/04/21 Copyr 1984 Sun Micro";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpcbind.c
|
||||
* Implements the program, version to address mapping for rpc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <rpc/rpc.h>
|
||||
#ifdef PORTMAP
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <netconfig.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <err.h>
|
||||
#include <util.h>
|
||||
#include <pwd.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "rpcbind.h"
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
/* Global variables */
|
||||
int debugging = 1; /* Tell me what's going on */
|
||||
int doabort = 0; /* When debugging, do an abort on errors */
|
||||
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
|
||||
|
||||
#include "svc_fdset.h"
|
||||
|
||||
/* who to suid to if -s is given */
|
||||
#define RUN_AS "daemon"
|
||||
|
||||
int runasdaemon = 0;
|
||||
int insecure = 0;
|
||||
int oldstyle_local = 0;
|
||||
int verboselog = 0;
|
||||
|
||||
#ifdef WARMSTART
|
||||
/* Local Variable */
|
||||
static int warmstart = 0; /* Grab a old copy of registrations */
|
||||
#endif
|
||||
|
||||
#ifdef PORTMAP
|
||||
struct pmaplist *list_pml; /* A list of version 2 rpcbind services */
|
||||
const char *udptrans; /* Name of UDP transport */
|
||||
const char *tcptrans; /* Name of TCP transport */
|
||||
const char *udp_uaddr; /* Universal UDP address */
|
||||
const char *tcp_uaddr; /* Universal TCP address */
|
||||
#endif
|
||||
static const char servname[] = "sunrpc";
|
||||
|
||||
const char rpcbind_superuser[] = "superuser";
|
||||
const char rpcbind_unknown[] = "unknown";
|
||||
|
||||
static int init_transport(struct netconfig *);
|
||||
static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
|
||||
struct netbuf *);
|
||||
static void terminate(int);
|
||||
#if 0
|
||||
static void parseargs(int, char *[]);
|
||||
#endif
|
||||
|
||||
int rpcbind_main(void *);
|
||||
int
|
||||
rpcbind_main(void *arg)
|
||||
{
|
||||
struct netconfig *nconf;
|
||||
void *nc_handle; /* Net config handle */
|
||||
struct rlimit rl;
|
||||
int maxrec = RPC_MAXDATASIZE;
|
||||
extern sem_t gensem;
|
||||
|
||||
#if 0
|
||||
parseargs(argc, argv);
|
||||
#endif
|
||||
|
||||
alloc_fdset();
|
||||
|
||||
getrlimit(RLIMIT_NOFILE, &rl);
|
||||
if (rl.rlim_cur < 128) {
|
||||
if (rl.rlim_max <= 128)
|
||||
rl.rlim_cur = rl.rlim_max;
|
||||
else
|
||||
rl.rlim_cur = 128;
|
||||
setrlimit(RLIMIT_NOFILE, &rl);
|
||||
}
|
||||
#if 0
|
||||
if (geteuid()) /* This command allowed only to root */
|
||||
errx(1, "Sorry. You are not superuser");
|
||||
#endif
|
||||
nc_handle = setnetconfig(); /* open netconfig file */
|
||||
if (nc_handle == NULL)
|
||||
errx(1, "could not read /etc/netconfig");
|
||||
#ifdef PORTMAP
|
||||
udptrans = "";
|
||||
tcptrans = "";
|
||||
#endif
|
||||
|
||||
nconf = getnetconfigent("local");
|
||||
if (nconf == NULL)
|
||||
errx(1, "can't find local transport");
|
||||
|
||||
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
|
||||
|
||||
init_transport(nconf);
|
||||
|
||||
while ((nconf = getnetconfig(nc_handle))) {
|
||||
if (nconf->nc_flag & NC_VISIBLE)
|
||||
init_transport(nconf);
|
||||
}
|
||||
endnetconfig(nc_handle);
|
||||
|
||||
/* catch the usual termination signals for graceful exit */
|
||||
(void) signal(SIGCHLD, reap);
|
||||
(void) signal(SIGINT, terminate);
|
||||
(void) signal(SIGTERM, terminate);
|
||||
(void) signal(SIGQUIT, terminate);
|
||||
/* ignore others that could get sent */
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
//(void) signal(SIGHUP, SIG_IGN); used by mountd
|
||||
(void) signal(SIGUSR1, SIG_IGN);
|
||||
(void) signal(SIGUSR2, SIG_IGN);
|
||||
#ifdef WARMSTART
|
||||
if (warmstart) {
|
||||
read_warmstart();
|
||||
}
|
||||
#endif
|
||||
if (debugging) {
|
||||
printf("rpcbind debugging enabled.");
|
||||
if (doabort) {
|
||||
printf(" Will abort on errors!\n");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
} else {
|
||||
if (daemon(0, 0))
|
||||
err(1, "fork failed");
|
||||
}
|
||||
|
||||
openlog("rpcbind", 0, LOG_DAEMON);
|
||||
pidfile(NULL);
|
||||
|
||||
if (runasdaemon) {
|
||||
struct passwd *p;
|
||||
|
||||
if((p = getpwnam(RUN_AS)) == NULL) {
|
||||
syslog(LOG_ERR, "cannot get uid of daemon: %m");
|
||||
exit(1);
|
||||
}
|
||||
if (setuid(p->pw_uid) == -1) {
|
||||
syslog(LOG_ERR, "setuid to daemon failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
network_init();
|
||||
|
||||
sem_post(&gensem);
|
||||
my_svc_run();
|
||||
syslog(LOG_ERR, "svc_run returned unexpectedly");
|
||||
rpcbind_abort();
|
||||
/* NOTREACHED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds the entry into the rpcbind database.
|
||||
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
|
||||
* Returns 0 if succeeds, else fails
|
||||
*/
|
||||
static int
|
||||
init_transport(struct netconfig *nconf)
|
||||
{
|
||||
int fd;
|
||||
struct t_bind taddr;
|
||||
struct addrinfo hints, *res = NULL;
|
||||
struct __rpc_sockinfo si;
|
||||
SVCXPRT *my_xprt;
|
||||
int aicode, status, addrlen;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_un sun;
|
||||
const int one = 1;
|
||||
|
||||
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS_ORD))
|
||||
return 1; /* not my type */
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
int i;
|
||||
char **s;
|
||||
|
||||
(void)fprintf(stderr, "%s: %ld lookup routines :\n",
|
||||
nconf->nc_netid, nconf->nc_nlookups);
|
||||
for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
|
||||
i++, s++)
|
||||
(void)fprintf(stderr, "[%d] - %s\n", i, *s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX - using RPC library internal functions.
|
||||
*/
|
||||
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
|
||||
if (errno == EAFNOSUPPORT)
|
||||
return 1;
|
||||
warn("Cannot create socket for `%s'", nconf->nc_netid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!__rpc_nconf2sockinfo(nconf, &si)) {
|
||||
warnx("Cannot get information for `%s'", nconf->nc_netid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (si.si_af == AF_INET6) {
|
||||
/*
|
||||
* We're doing host-based access checks here, so don't allow
|
||||
* v4-in-v6 to confuse things.
|
||||
*/
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one,
|
||||
sizeof one) < 0) {
|
||||
warn("Can't make socket ipv6 only");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(nconf->nc_netid, "local")) {
|
||||
(void)memset(&sun, 0, sizeof sun);
|
||||
sun.sun_family = AF_LOCAL;
|
||||
(void)rump_sys_unlink(_PATH_RPCBINDSOCK);
|
||||
(void)strlcpy(sun.sun_path, _PATH_RPCBINDSOCK,
|
||||
sizeof(sun.sun_path));
|
||||
sun.sun_len = SUN_LEN(&sun);
|
||||
addrlen = sizeof(struct sockaddr_un);
|
||||
sa = (struct sockaddr *)&sun;
|
||||
} else {
|
||||
/* Get rpcbind's address on this transport */
|
||||
|
||||
(void)memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = si.si_af;
|
||||
hints.ai_socktype = si.si_socktype;
|
||||
hints.ai_protocol = si.si_proto;
|
||||
if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
|
||||
warnx("Cannot get local address for `%s' (%s)",
|
||||
nconf->nc_netid, gai_strerror(aicode));
|
||||
return 1;
|
||||
}
|
||||
addrlen = res->ai_addrlen;
|
||||
sa = (struct sockaddr *)res->ai_addr;
|
||||
}
|
||||
|
||||
if (bind(fd, sa, addrlen) < 0) {
|
||||
warn("Cannot bind `%s'", nconf->nc_netid);
|
||||
if (res != NULL)
|
||||
freeaddrinfo(res);
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
if (sa->sa_family == AF_LOCAL)
|
||||
if (rump_sys_chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1)
|
||||
warn("Cannot chmod `%s'", sun.sun_path);
|
||||
#endif
|
||||
|
||||
/* Copy the address */
|
||||
taddr.addr.len = taddr.addr.maxlen = addrlen;
|
||||
taddr.addr.buf = malloc(addrlen);
|
||||
if (taddr.addr.buf == NULL) {
|
||||
warn("Cannot allocate memory for `%s' address",
|
||||
nconf->nc_netid);
|
||||
if (res != NULL)
|
||||
freeaddrinfo(res);
|
||||
return 1;
|
||||
}
|
||||
(void)memcpy(taddr.addr.buf, sa, addrlen);
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
/* for debugging print out our universal address */
|
||||
char *uaddr;
|
||||
struct netbuf nb;
|
||||
|
||||
nb.buf = sa;
|
||||
nb.len = nb.maxlen = sa->sa_len;
|
||||
uaddr = taddr2uaddr(nconf, &nb);
|
||||
(void)fprintf(stderr, "rpcbind: my address is %s\n", uaddr);
|
||||
(void)free(uaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (res != NULL)
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (nconf->nc_semantics != NC_TPI_CLTS)
|
||||
listen(fd, SOMAXCONN);
|
||||
|
||||
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE,
|
||||
RPC_MAXDATASIZE);
|
||||
if (my_xprt == NULL) {
|
||||
warnx("Could not create service for `%s'", nconf->nc_netid);
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef PORTMAP
|
||||
/*
|
||||
* Register both the versions for tcp/ip, udp/ip and local.
|
||||
*/
|
||||
if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 &&
|
||||
(strcmp(nconf->nc_proto, NC_TCP) == 0 ||
|
||||
strcmp(nconf->nc_proto, NC_UDP) == 0)) ||
|
||||
strcmp(nconf->nc_netid, "local") == 0) {
|
||||
struct pmaplist *pml;
|
||||
|
||||
if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
|
||||
pmap_service, 0)) {
|
||||
warn("Could not register on `%s'", nconf->nc_netid);
|
||||
goto error;
|
||||
}
|
||||
pml = malloc(sizeof (struct pmaplist));
|
||||
if (pml == NULL) {
|
||||
warn("Cannot allocate memory");
|
||||
goto error;
|
||||
}
|
||||
pml->pml_map.pm_prog = PMAPPROG;
|
||||
pml->pml_map.pm_vers = PMAPVERS;
|
||||
pml->pml_map.pm_port = PMAPPORT;
|
||||
if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
|
||||
if (tcptrans[0]) {
|
||||
warnx(
|
||||
"Cannot have more than one TCP transport");
|
||||
free(pml);
|
||||
goto error;
|
||||
}
|
||||
tcptrans = strdup(nconf->nc_netid);
|
||||
if (tcptrans == NULL) {
|
||||
free(pml);
|
||||
warn("Cannot allocate memory");
|
||||
goto error;
|
||||
}
|
||||
pml->pml_map.pm_prot = IPPROTO_TCP;
|
||||
|
||||
/* Let's snarf the universal address */
|
||||
/* "h1.h2.h3.h4.p1.p2" */
|
||||
tcp_uaddr = taddr2uaddr(nconf, &taddr.addr);
|
||||
} else if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
|
||||
if (udptrans[0]) {
|
||||
free(pml);
|
||||
warnx(
|
||||
"Cannot have more than one UDP transport");
|
||||
goto error;
|
||||
}
|
||||
udptrans = strdup(nconf->nc_netid);
|
||||
if (udptrans == NULL) {
|
||||
free(pml);
|
||||
warn("Cannot allocate memory");
|
||||
goto error;
|
||||
}
|
||||
pml->pml_map.pm_prot = IPPROTO_UDP;
|
||||
|
||||
/* Let's snarf the universal address */
|
||||
/* "h1.h2.h3.h4.p1.p2" */
|
||||
udp_uaddr = taddr2uaddr(nconf, &taddr.addr);
|
||||
}
|
||||
pml->pml_next = list_pml;
|
||||
list_pml = pml;
|
||||
|
||||
/* Add version 3 information */
|
||||
pml = malloc(sizeof (struct pmaplist));
|
||||
if (pml == NULL) {
|
||||
warn("Cannot allocate memory");
|
||||
goto error;
|
||||
}
|
||||
pml->pml_map = list_pml->pml_map;
|
||||
pml->pml_map.pm_vers = RPCBVERS;
|
||||
pml->pml_next = list_pml;
|
||||
list_pml = pml;
|
||||
|
||||
/* Add version 4 information */
|
||||
pml = malloc(sizeof (struct pmaplist));
|
||||
if (pml == NULL) {
|
||||
warn("Cannot allocate memory");
|
||||
goto error;
|
||||
}
|
||||
pml->pml_map = list_pml->pml_map;
|
||||
pml->pml_map.pm_vers = RPCBVERS4;
|
||||
pml->pml_next = list_pml;
|
||||
list_pml = pml;
|
||||
|
||||
/* Also add version 2 stuff to rpcbind list */
|
||||
rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* version 3 registration */
|
||||
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
|
||||
warn("Could not register %s version 3", nconf->nc_netid);
|
||||
goto error;
|
||||
}
|
||||
rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);
|
||||
|
||||
/* version 4 registration */
|
||||
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
|
||||
warn("Could not register %s version 4", nconf->nc_netid);
|
||||
goto error;
|
||||
}
|
||||
rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);
|
||||
|
||||
/* decide if bound checking works for this transport */
|
||||
status = add_bndlist(nconf, &taddr.addr);
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
if (status < 0) {
|
||||
fprintf(stderr, "Error in finding bind status for %s\n",
|
||||
nconf->nc_netid);
|
||||
} else if (status == 0) {
|
||||
fprintf(stderr, "check binding for %s\n",
|
||||
nconf->nc_netid);
|
||||
} else if (status > 0) {
|
||||
fprintf(stderr, "No check binding for %s\n",
|
||||
nconf->nc_netid);
|
||||
}
|
||||
}
|
||||
#else
|
||||
__USE(status);
|
||||
#endif
|
||||
/*
|
||||
* rmtcall only supported on CLTS transports for now.
|
||||
*/
|
||||
if (nconf->nc_semantics == NC_TPI_CLTS) {
|
||||
status = create_rmtcall_fd(nconf);
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging) {
|
||||
if (status < 0) {
|
||||
fprintf(stderr,
|
||||
"Could not create rmtcall fd for %s\n",
|
||||
nconf->nc_netid);
|
||||
} else {
|
||||
fprintf(stderr, "rmtcall fd for %s is %d\n",
|
||||
nconf->nc_netid, status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
error:
|
||||
(void)rump_sys_close(fd);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
|
||||
struct netbuf *addr)
|
||||
{
|
||||
rpcblist_ptr rbl;
|
||||
|
||||
rbl = malloc(sizeof(rpcblist));
|
||||
if (rbl == NULL) {
|
||||
warn("Out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
rbl->rpcb_map.r_prog = prog;
|
||||
rbl->rpcb_map.r_vers = vers;
|
||||
rbl->rpcb_map.r_netid = strdup(nconf->nc_netid);
|
||||
rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr);
|
||||
rbl->rpcb_map.r_owner = strdup(rpcbind_superuser);
|
||||
rbl->rpcb_next = list_rbl; /* Attach to global list */
|
||||
list_rbl = rbl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Catch the signal and die
|
||||
*/
|
||||
static void
|
||||
terminate(int dummy)
|
||||
{
|
||||
#ifdef WARMSTART
|
||||
syslog(LOG_ERR,
|
||||
"rpcbind terminating on signal. Restart with \"rpcbind -w\"");
|
||||
write_warmstart(); /* Dump yourself */
|
||||
#endif
|
||||
exit(2);
|
||||
}
|
||||
|
||||
void
|
||||
rpcbind_abort()
|
||||
{
|
||||
#ifdef WARMSTART
|
||||
write_warmstart(); /* Dump yourself */
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* get command line options */
|
||||
static void
|
||||
parseargs(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "dwailLs")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
doabort = 1; /* when debugging, do an abort on */
|
||||
break; /* errors; for rpcbind developers */
|
||||
/* only! */
|
||||
case 'd':
|
||||
debugging = 1;
|
||||
break;
|
||||
case 'i':
|
||||
insecure = 1;
|
||||
break;
|
||||
case 'L':
|
||||
oldstyle_local = 1;
|
||||
break;
|
||||
case 'l':
|
||||
verboselog = 1;
|
||||
break;
|
||||
case 's':
|
||||
runasdaemon = 1;
|
||||
break;
|
||||
#ifdef WARMSTART
|
||||
case 'w':
|
||||
warmstart = 1;
|
||||
break;
|
||||
#endif
|
||||
default: /* error */
|
||||
fprintf(stderr, "usage: rpcbind [-Idwils]\n");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
if (doabort && !debugging) {
|
||||
fprintf(stderr,
|
||||
"-a (abort) specified without -d (debugging) -- ignored.\n");
|
||||
doabort = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
reap(int dummy)
|
||||
{
|
||||
int save_errno = errno;
|
||||
|
||||
while (wait3(NULL, WNOHANG, NULL) > 0)
|
||||
;
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
void
|
||||
toggle_verboselog(int dummy)
|
||||
{
|
||||
verboselog = !verboselog;
|
||||
}
|
146
dist/fs/nfs/nfsservice/rpcbind/rpcbind.h
vendored
146
dist/fs/nfs/nfsservice/rpcbind/rpcbind.h
vendored
@ -1,146 +0,0 @@
|
||||
/* $NetBSD: rpcbind.h,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)rpcbind.h 1.4 90/04/12 SMI" */
|
||||
|
||||
/*
|
||||
* rpcbind.h
|
||||
* The common header declarations
|
||||
*/
|
||||
|
||||
#ifndef rpcbind_h
|
||||
#define rpcbind_h
|
||||
|
||||
#ifdef PORTMAP
|
||||
#include <rpc/pmap_prot.h>
|
||||
#endif
|
||||
#include <rpc/rpcb_prot.h>
|
||||
|
||||
/*
|
||||
* Stuff for the rmtcall service
|
||||
*/
|
||||
struct encap_parms {
|
||||
u_int32_t arglen;
|
||||
char *args;
|
||||
};
|
||||
|
||||
struct r_rmtcall_args {
|
||||
u_int32_t rmt_prog;
|
||||
u_int32_t rmt_vers;
|
||||
u_int32_t rmt_proc;
|
||||
int rmt_localvers; /* whether to send port # or uaddr */
|
||||
char *rmt_uaddr;
|
||||
struct encap_parms rmt_args;
|
||||
};
|
||||
|
||||
extern int debugging;
|
||||
extern int doabort;
|
||||
extern int verboselog;
|
||||
extern int insecure;
|
||||
extern int oldstyle_local;
|
||||
extern rpcblist_ptr list_rbl; /* A list of version 3 & 4 rpcbind services */
|
||||
|
||||
#ifdef PORTMAP
|
||||
extern struct pmaplist *list_pml; /* A list of version 2 rpcbind services */
|
||||
extern const char *udptrans; /* Name of UDP transport */
|
||||
extern const char *tcptrans; /* Name of TCP transport */
|
||||
extern const char *udp_uaddr; /* Universal UDP address */
|
||||
extern const char *tcp_uaddr; /* Universal TCP address */
|
||||
#endif
|
||||
|
||||
extern const char rpcbind_superuser[];
|
||||
extern const char rpcbind_unknown[];
|
||||
|
||||
int add_bndlist(struct netconfig *, struct netbuf *);
|
||||
bool_t is_bound(const char *, const char *);
|
||||
char *mergeaddr(SVCXPRT *, char *, char *, char *);
|
||||
struct netconfig *rpcbind_get_conf(const char *);
|
||||
|
||||
void rpcbs_init(void);
|
||||
void rpcbs_procinfo(rpcvers_t, rpcproc_t);
|
||||
void rpcbs_set(rpcvers_t, bool_t);
|
||||
void rpcbs_unset(rpcvers_t, bool_t);
|
||||
void rpcbs_getaddr(rpcvers_t, rpcprog_t, rpcvers_t, const char *, const char *);
|
||||
void rpcbs_rmtcall(rpcvers_t, rpcproc_t, rpcprog_t, rpcvers_t, rpcproc_t,
|
||||
char *, rpcblist_ptr);
|
||||
void *rpcbproc_getstat(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
|
||||
|
||||
void rpcb_service_3(struct svc_req *, SVCXPRT *);
|
||||
void rpcb_service_4(struct svc_req *, SVCXPRT *);
|
||||
|
||||
/* Common functions shared between versions */
|
||||
void *rpcbproc_set_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
|
||||
void *rpcbproc_unset_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
|
||||
bool_t map_set(RPCB *, char *);
|
||||
bool_t map_unset(RPCB *, const char *);
|
||||
void delete_prog(int);
|
||||
void *rpcbproc_getaddr_com(RPCB *, struct svc_req *, SVCXPRT *, rpcvers_t,
|
||||
rpcvers_t);
|
||||
void *rpcbproc_gettime_com(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
void *rpcbproc_uaddr2taddr_com(void *, struct svc_req *,
|
||||
SVCXPRT *, rpcvers_t);
|
||||
void *rpcbproc_taddr2uaddr_com(void *, struct svc_req *, SVCXPRT *,
|
||||
rpcvers_t);
|
||||
int create_rmtcall_fd(struct netconfig *);
|
||||
void rpcbproc_callit_com(struct svc_req *, SVCXPRT *, rpcvers_t,
|
||||
rpcvers_t);
|
||||
void my_svc_run(void);
|
||||
|
||||
void rpcbind_abort(void);
|
||||
void reap(int);
|
||||
void toggle_verboselog(int);
|
||||
|
||||
int check_access(SVCXPRT *, rpcproc_t, void *, int);
|
||||
int check_callit(SVCXPRT *, struct r_rmtcall_args *, int);
|
||||
void logit(int, struct sockaddr *, rpcproc_t, rpcprog_t, const char *);
|
||||
int is_loopback(struct netbuf *);
|
||||
|
||||
#ifdef PORTMAP
|
||||
extern void pmap_service(struct svc_req *, SVCXPRT *);
|
||||
#endif
|
||||
|
||||
void write_warmstart(void);
|
||||
void read_warmstart(void);
|
||||
|
||||
char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
|
||||
char *netid);
|
||||
void network_init(void);
|
||||
struct sockaddr *local_sa(int);
|
||||
|
||||
/* For different getaddr semantics */
|
||||
#define RPCB_ALLVERS 0
|
||||
#define RPCB_ONEVERS 1
|
||||
|
||||
#endif /* rpcbind_h */
|
282
dist/fs/nfs/nfsservice/rpcbind/security.c
vendored
282
dist/fs/nfs/nfsservice/rpcbind/security.c
vendored
@ -1,282 +0,0 @@
|
||||
/* $NetBSD: security.c,v 1.1 2010/07/26 15:53:01 pooka Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <syslog.h>
|
||||
#include <netdb.h>
|
||||
|
||||
/*
|
||||
* XXX for special case checks in check_callit.
|
||||
*/
|
||||
#include <rpcsvc/mount.h>
|
||||
#include <rpcsvc/rquota.h>
|
||||
#include <rpcsvc/nfs_prot.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <rpcsvc/yppasswd.h>
|
||||
|
||||
#include "rpcbind.h"
|
||||
|
||||
#ifdef LIBWRAP
|
||||
# include <tcpd.h>
|
||||
#ifndef LIBWRAP_ALLOW_FACILITY
|
||||
# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
|
||||
#endif
|
||||
#ifndef LIBWRAP_ALLOW_SEVERITY
|
||||
# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
|
||||
#endif
|
||||
#ifndef LIBWRAP_DENY_FACILITY
|
||||
# define LIBWRAP_DENY_FACILITY LOG_AUTH
|
||||
#endif
|
||||
#ifndef LIBWRAP_DENY_SEVERITY
|
||||
# define LIBWRAP_DENY_SEVERITY LOG_WARNING
|
||||
#endif
|
||||
int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY;
|
||||
int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
|
||||
#endif
|
||||
|
||||
#ifndef PORTMAP_LOG_FACILITY
|
||||
# define PORTMAP_LOG_FACILITY LOG_AUTH
|
||||
#endif
|
||||
#ifndef PORTMAP_LOG_SEVERITY
|
||||
# define PORTMAP_LOG_SEVERITY LOG_INFO
|
||||
#endif
|
||||
int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY;
|
||||
|
||||
extern int verboselog;
|
||||
|
||||
int
|
||||
check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, int rpcbvers)
|
||||
{
|
||||
struct netbuf *caller = svc_getrpccaller(xprt);
|
||||
struct sockaddr *addr = (struct sockaddr *)caller->buf;
|
||||
#ifdef LIBWRAP
|
||||
struct request_info req;
|
||||
#endif
|
||||
rpcprog_t prog = 0;
|
||||
rpcb *rpcbp;
|
||||
struct pmap *pmap;
|
||||
|
||||
/*
|
||||
* The older PMAP_* equivalents have the same numbers, so
|
||||
* they are accounted for here as well.
|
||||
*/
|
||||
switch (proc) {
|
||||
case RPCBPROC_GETADDR:
|
||||
case RPCBPROC_SET:
|
||||
case RPCBPROC_UNSET:
|
||||
if (rpcbvers > PMAPVERS) {
|
||||
rpcbp = (rpcb *)args;
|
||||
prog = rpcbp->r_prog;
|
||||
} else {
|
||||
pmap = (struct pmap *)args;
|
||||
prog = pmap->pm_prog;
|
||||
}
|
||||
if (proc == RPCBPROC_GETADDR)
|
||||
break;
|
||||
if (!insecure && !is_loopback(caller)) {
|
||||
if (verboselog)
|
||||
logit(log_severity, addr, proc, prog,
|
||||
" declined (non-loopback sender)");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case RPCBPROC_CALLIT:
|
||||
case RPCBPROC_INDIRECT:
|
||||
case RPCBPROC_DUMP:
|
||||
case RPCBPROC_GETTIME:
|
||||
case RPCBPROC_UADDR2TADDR:
|
||||
case RPCBPROC_TADDR2UADDR:
|
||||
case RPCBPROC_GETVERSADDR:
|
||||
case RPCBPROC_GETADDRLIST:
|
||||
case RPCBPROC_GETSTAT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef LIBWRAP
|
||||
if (addr->sa_family == AF_LOCAL)
|
||||
return 1;
|
||||
request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0);
|
||||
sock_methods(&req);
|
||||
if(!hosts_access(&req)) {
|
||||
logit(deny_severity, addr, proc, prog, ": request from unauthorized host");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (verboselog)
|
||||
logit(log_severity, addr, proc, prog, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
is_loopback(struct netbuf *nbuf)
|
||||
{
|
||||
struct sockaddr *addr = (struct sockaddr *)nbuf->buf;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET:
|
||||
if (!oldstyle_local)
|
||||
return 0;
|
||||
sin = (struct sockaddr_in *)addr;
|
||||
return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
|
||||
(ntohs(sin->sin_port) < IPPORT_RESERVED));
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (!oldstyle_local)
|
||||
return 0;
|
||||
sin6 = (struct sockaddr_in6 *)addr;
|
||||
return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
|
||||
(ntohs(sin6->sin6_port) < IPV6PORT_RESERVED));
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* logit - report events of interest via the syslog daemon */
|
||||
void
|
||||
logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum,
|
||||
const char *text)
|
||||
{
|
||||
const char *procname;
|
||||
char procbuf[32];
|
||||
char *progname;
|
||||
char progbuf[32];
|
||||
char fromname[NI_MAXHOST];
|
||||
struct rpcent *rpc;
|
||||
static const char *procmap[] = {
|
||||
/* RPCBPROC_NULL */ "null",
|
||||
/* RPCBPROC_SET */ "set",
|
||||
/* RPCBPROC_UNSET */ "unset",
|
||||
/* RPCBPROC_GETADDR */ "getport/addr",
|
||||
/* RPCBPROC_DUMP */ "dump",
|
||||
/* RPCBPROC_CALLIT */ "callit",
|
||||
/* RPCBPROC_GETTIME */ "gettime",
|
||||
/* RPCBPROC_UADDR2TADDR */ "uaddr2taddr",
|
||||
/* RPCBPROC_TADDR2UADDR */ "taddr2uaddr",
|
||||
/* RPCBPROC_GETVERSADDR */ "getversaddr",
|
||||
/* RPCBPROC_INDIRECT */ "indirect",
|
||||
/* RPCBPROC_GETADDRLIST */ "getaddrlist",
|
||||
/* RPCBPROC_GETSTAT */ "getstat"
|
||||
};
|
||||
|
||||
/*
|
||||
* Fork off a process or the portmap daemon might hang while
|
||||
* getrpcbynumber() or syslog() does its thing.
|
||||
*/
|
||||
|
||||
if (fork() == 0) {
|
||||
setproctitle("logit");
|
||||
|
||||
/* Try to map program number to name. */
|
||||
|
||||
if (prognum == 0) {
|
||||
progname = __UNCONST("");
|
||||
} else if ((rpc = getrpcbynumber((int) prognum))) {
|
||||
progname = rpc->r_name;
|
||||
} else {
|
||||
snprintf(progname = progbuf, sizeof(progbuf), "%u",
|
||||
(unsigned)prognum);
|
||||
}
|
||||
|
||||
/* Try to map procedure number to name. */
|
||||
|
||||
if (procnum >= (sizeof procmap / sizeof (char *))) {
|
||||
snprintf(procbuf, sizeof procbuf, "%u",
|
||||
(unsigned)procnum);
|
||||
procname = procbuf;
|
||||
} else
|
||||
procname = procmap[procnum];
|
||||
|
||||
/* Write syslog record. */
|
||||
|
||||
if (addr->sa_family == AF_LOCAL)
|
||||
strlcpy(fromname, "local", sizeof(fromname));
|
||||
else
|
||||
getnameinfo(addr, addr->sa_len, fromname,
|
||||
sizeof fromname, NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
syslog(severity, "connect from %s to %s(%s)%s",
|
||||
fromname, procname, progname, text);
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf;
|
||||
|
||||
/*
|
||||
* Always allow calling NULLPROC
|
||||
*/
|
||||
if (args->rmt_proc == 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* XXX - this special casing sucks.
|
||||
*/
|
||||
switch (args->rmt_prog) {
|
||||
case RPCBPROG:
|
||||
/*
|
||||
* Allow indirect calls to ourselves in insecure mode.
|
||||
* The is_loopback checks aren't useful then anyway.
|
||||
*/
|
||||
if (!insecure)
|
||||
goto deny;
|
||||
break;
|
||||
case MOUNTPROG:
|
||||
if (args->rmt_proc != MOUNTPROC_MNT &&
|
||||
args->rmt_proc != MOUNTPROC_UMNT)
|
||||
break;
|
||||
goto deny;
|
||||
case YPBINDPROG:
|
||||
if (args->rmt_proc != YPBINDPROC_SETDOM)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case YPPASSWDPROG:
|
||||
case NFS_PROGRAM:
|
||||
case RQUOTAPROG:
|
||||
goto deny;
|
||||
case YPPROG:
|
||||
switch (args->rmt_proc) {
|
||||
case YPPROC_ALL:
|
||||
case YPPROC_MATCH:
|
||||
case YPPROC_FIRST:
|
||||
case YPPROC_NEXT:
|
||||
goto deny;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
deny:
|
||||
logit(deny_severity, sa, args->rmt_proc, args->rmt_prog,
|
||||
": indirect call not allowed");
|
||||
|
||||
return 0;
|
||||
}
|
401
dist/fs/nfs/nfsservice/rpcbind/util.c
vendored
401
dist/fs/nfs/nfsservice/rpcbind/util.c
vendored
@ -1,401 +0,0 @@
|
||||
/* $NetBSD: util.c,v 1.2 2011/06/11 18:03:17 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Frank van der Linden.
|
||||
*
|
||||
* 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/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <assert.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <poll.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <netconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
#include "rpcbind.h"
|
||||
|
||||
static struct sockaddr_in *local_in4;
|
||||
#ifdef INET6
|
||||
static struct sockaddr_in6 *local_in6;
|
||||
#endif
|
||||
|
||||
static int bitmaskcmp(void *, void *, void *, int);
|
||||
#ifdef INET6
|
||||
static void in6_fillscopeid(struct sockaddr_in6 *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For all bits set in "mask", compare the corresponding bits in
|
||||
* "dst" and "src", and see if they match.
|
||||
*/
|
||||
static int
|
||||
bitmaskcmp(void *dst, void *src, void *mask, int bytelen)
|
||||
{
|
||||
int i, j;
|
||||
u_int8_t *p1 = dst, *p2 = src, *netmask = mask;
|
||||
u_int8_t bitmask;
|
||||
|
||||
for (i = 0; i < bytelen; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
bitmask = 1 << j;
|
||||
if (!(netmask[i] & bitmask))
|
||||
continue;
|
||||
if ((p1[i] & bitmask) != (p2[i] & bitmask))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Taken from ifconfig.c
|
||||
*/
|
||||
#ifdef INET6
|
||||
static void
|
||||
in6_fillscopeid(struct sockaddr_in6 *sin6)
|
||||
{
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
sin6->sin6_scope_id =
|
||||
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
|
||||
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
|
||||
char *netid)
|
||||
{
|
||||
struct ifaddrs *ifap, *ifp, *bestif;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6;
|
||||
struct sockaddr_in6 *newsin6;
|
||||
#endif
|
||||
struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin;
|
||||
struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf;
|
||||
struct sockaddr *serv_sa;
|
||||
struct sockaddr *clnt_sa;
|
||||
struct sockaddr_storage ss;
|
||||
struct netconfig *nconf;
|
||||
struct sockaddr *clnt = caller->buf;
|
||||
char *ret = NULL;
|
||||
|
||||
#ifdef INET6
|
||||
servsin6 = ifsin6 = newsin6 = NULL; /* XXXGCC -Wuninitialized */
|
||||
#endif
|
||||
servsin = newsin = NULL; /* XXXGCC -Wuninitialized */
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
|
||||
clnt_uaddr, netid);
|
||||
#endif
|
||||
nconf = getnetconfigent(netid);
|
||||
if (nconf == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Local merge, just return a duplicate.
|
||||
*/
|
||||
if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0)
|
||||
return strdup(clnt_uaddr);
|
||||
|
||||
serv_nbp = uaddr2taddr(nconf, serv_uaddr);
|
||||
if (serv_nbp == NULL)
|
||||
return NULL;
|
||||
|
||||
serv_sa = (struct sockaddr *)serv_nbp->buf;
|
||||
if (clnt_uaddr != NULL) {
|
||||
clnt_nbp = uaddr2taddr(nconf, clnt_uaddr);
|
||||
if (clnt_nbp == NULL) {
|
||||
free(serv_nbp);
|
||||
return NULL;
|
||||
}
|
||||
clnt_sa = (struct sockaddr *)clnt_nbp->buf;
|
||||
if (clnt_sa->sa_family == AF_LOCAL) {
|
||||
free(serv_nbp);
|
||||
free(clnt_nbp);
|
||||
free(clnt_sa);
|
||||
return strdup(serv_uaddr);
|
||||
}
|
||||
} else {
|
||||
clnt_sa = (struct sockaddr *)
|
||||
malloc(sizeof (struct sockaddr_storage));
|
||||
memcpy(clnt_sa, clnt, clnt->sa_len);
|
||||
}
|
||||
|
||||
if (getifaddrs(&ifp) < 0) {
|
||||
free(serv_nbp);
|
||||
free(clnt_sa);
|
||||
if (clnt_nbp != NULL)
|
||||
free(clnt_nbp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through all interfaces. For each interface, see if the
|
||||
* network portion of its address is equal to that of the client.
|
||||
* If so, we have found the interface that we want to use.
|
||||
*/
|
||||
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
|
||||
if (ifap->ifa_addr->sa_family != clnt->sa_family ||
|
||||
!(ifap->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
|
||||
switch (clnt->sa_family) {
|
||||
case AF_INET:
|
||||
/*
|
||||
* realsin: address that recvfrom gave us.
|
||||
* ifsin: address of interface being examined.
|
||||
* clntsin: address that client want us to contact
|
||||
* it on
|
||||
* servsin: local address of RPC service.
|
||||
* sinmask: netmask of this interface
|
||||
* newsin: initially a copy of clntsin, eventually
|
||||
* the merged address
|
||||
*/
|
||||
servsin = (struct sockaddr_in *)serv_sa;
|
||||
clntsin = (struct sockaddr_in *)clnt_sa;
|
||||
sinmask = (struct sockaddr_in *)ifap->ifa_netmask;
|
||||
newsin = (struct sockaddr_in *)&ss;
|
||||
ifsin = (struct sockaddr_in *)ifap->ifa_addr;
|
||||
if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr,
|
||||
&sinmask->sin_addr, sizeof (struct in_addr))) {
|
||||
goto found;
|
||||
}
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
/*
|
||||
* realsin6: address that recvfrom gave us.
|
||||
* ifsin6: address of interface being examined.
|
||||
* clntsin6: address that client want us to contact
|
||||
* it on
|
||||
* servsin6: local address of RPC service.
|
||||
* sin6mask: netmask of this interface
|
||||
* newsin6: initially a copy of clntsin, eventually
|
||||
* the merged address
|
||||
*
|
||||
* For v6 link local addresses, if the client contacted
|
||||
* us via a link-local address, and wants us to reply
|
||||
* to one, use the scope id to see which one.
|
||||
*/
|
||||
realsin6 = (struct sockaddr_in6 *)clnt;
|
||||
ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
|
||||
in6_fillscopeid(ifsin6);
|
||||
clntsin6 = (struct sockaddr_in6 *)clnt_sa;
|
||||
servsin6 = (struct sockaddr_in6 *)serv_sa;
|
||||
sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
|
||||
newsin6 = (struct sockaddr_in6 *)&ss;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) {
|
||||
if (ifsin6->sin6_scope_id !=
|
||||
realsin6->sin6_scope_id)
|
||||
continue;
|
||||
goto found;
|
||||
}
|
||||
if (!bitmaskcmp(&ifsin6->sin6_addr,
|
||||
&clntsin6->sin6_addr, &sin6mask->sin6_addr,
|
||||
sizeof (struct in6_addr)))
|
||||
goto found;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto freeit;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Didn't find anything. Get the first possibly useful interface,
|
||||
* preferring "normal" interfaces to point-to-point and loopback
|
||||
* ones.
|
||||
*/
|
||||
bestif = NULL;
|
||||
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
|
||||
if (ifap->ifa_addr->sa_family != clnt->sa_family ||
|
||||
!(ifap->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
if (!(ifap->ifa_flags & IFF_LOOPBACK) &&
|
||||
!(ifap->ifa_flags & IFF_POINTOPOINT)) {
|
||||
bestif = ifap;
|
||||
break;
|
||||
}
|
||||
if (bestif == NULL)
|
||||
bestif = ifap;
|
||||
else if ((bestif->ifa_flags & IFF_LOOPBACK) &&
|
||||
!(ifap->ifa_flags & IFF_LOOPBACK))
|
||||
bestif = ifap;
|
||||
}
|
||||
ifap = bestif;
|
||||
found:
|
||||
switch (clnt->sa_family) {
|
||||
case AF_INET:
|
||||
memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len);
|
||||
newsin->sin_port = servsin->sin_port;
|
||||
tbuf.len = clnt_sa->sa_len;
|
||||
tbuf.maxlen = sizeof (struct sockaddr_storage);
|
||||
tbuf.buf = newsin;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
assert(newsin6);
|
||||
memcpy(newsin6, ifsin6, clnt_sa->sa_len);
|
||||
newsin6->sin6_port = servsin6->sin6_port;
|
||||
tbuf.maxlen = sizeof (struct sockaddr_storage);
|
||||
tbuf.len = clnt_sa->sa_len;
|
||||
tbuf.buf = newsin6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto freeit;
|
||||
}
|
||||
if (ifap != NULL)
|
||||
ret = taddr2uaddr(nconf, &tbuf);
|
||||
freeit:
|
||||
freenetconfigent(nconf);
|
||||
free(serv_sa);
|
||||
free(serv_nbp);
|
||||
if (clnt_sa != NULL)
|
||||
free(clnt_sa);
|
||||
if (clnt_nbp != NULL)
|
||||
free(clnt_nbp);
|
||||
freeifaddrs(ifp);
|
||||
|
||||
#ifdef RPCBIND_DEBUG
|
||||
if (debugging)
|
||||
fprintf(stderr, "addrmerge: returning %s\n", ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
network_init()
|
||||
{
|
||||
#ifdef INET6
|
||||
struct ifaddrs *ifap, *ifp;
|
||||
struct ipv6_mreq mreq6;
|
||||
int ifindex, s;
|
||||
#endif
|
||||
int ecode;
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET;
|
||||
if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
|
||||
if (debugging)
|
||||
fprintf(stderr, "can't get local ip4 address: %s\n",
|
||||
gai_strerror(ecode));
|
||||
} else {
|
||||
local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4);
|
||||
if (local_in4 == NULL) {
|
||||
if (debugging)
|
||||
fprintf(stderr, "can't alloc local ip4 addr\n");
|
||||
}
|
||||
memcpy(local_in4, res->ai_addr, sizeof *local_in4);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
hints.ai_family = AF_INET6;
|
||||
if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
|
||||
if (debugging)
|
||||
fprintf(stderr, "can't get local ip6 address: %s\n",
|
||||
gai_strerror(ecode));
|
||||
} else {
|
||||
local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6);
|
||||
if (local_in6 == NULL) {
|
||||
if (debugging)
|
||||
fprintf(stderr, "can't alloc local ip6 addr\n");
|
||||
}
|
||||
memcpy(local_in6, res->ai_addr, sizeof *local_in6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now join the RPC ipv6 multicast group on all interfaces.
|
||||
*/
|
||||
if (getifaddrs(&ifp) < 0)
|
||||
return;
|
||||
|
||||
mreq6.ipv6mr_interface = 0;
|
||||
inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr);
|
||||
|
||||
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
/*
|
||||
* Loop through all interfaces. For each interface, see if the
|
||||
* network portion of its address is equal to that of the client.
|
||||
* If so, we have found the interface that we want to use.
|
||||
*/
|
||||
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
|
||||
if (ifap->ifa_addr->sa_family != AF_INET6 ||
|
||||
!(ifap->ifa_flags & IFF_MULTICAST))
|
||||
continue;
|
||||
ifindex = if_nametoindex(ifap->ifa_name);
|
||||
if (ifindex == mreq6.ipv6mr_interface)
|
||||
/*
|
||||
* Already did this one.
|
||||
*/
|
||||
continue;
|
||||
mreq6.ipv6mr_interface = ifindex;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
|
||||
sizeof mreq6) < 0)
|
||||
if (debugging)
|
||||
warn("setsockopt v6 multicast");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* close(s); */
|
||||
}
|
||||
|
||||
struct sockaddr *
|
||||
local_sa(int af)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (struct sockaddr *)local_in4;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return (struct sockaddr *)local_in6;
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
5
dist/fs/nfs/nfsservice/rumpnfsd.c
vendored
5
dist/fs/nfs/nfsservice/rumpnfsd.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rumpnfsd.c,v 1.8 2014/05/12 15:31:07 christos Exp $ */
|
||||
/* $NetBSD: rumpnfsd.c,v 1.9 2015/11/08 02:45:16 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -37,6 +37,7 @@
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
void *mountd_main(void *);
|
||||
void *rpcbind_main(void *);
|
||||
@ -87,7 +88,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
rump_init();
|
||||
init_fdsets();
|
||||
svc_fdset_init(SVC_FDSET_MT);
|
||||
|
||||
rv = rump_pub_etfs_register("/etc/exports", "./exports", RUMP_ETFS_REG);
|
||||
if (rv) {
|
||||
|
4
dist/fs/nfs/t_rquotad.sh
vendored
4
dist/fs/nfs/t_rquotad.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_rquotad.sh,v 1.4 2014/03/13 12:45:14 gson Exp $
|
||||
# $NetBSD: t_rquotad.sh,v 1.5 2016/08/10 23:25:39 kre Exp $
|
||||
#
|
||||
# Copyright (c) 2011 Manuel Bouyer
|
||||
# All rights reserved.
|
||||
@ -114,7 +114,7 @@ get_nfs_quota()
|
||||
unset RUMPHIJACK
|
||||
unset LD_PRELOAD
|
||||
|
||||
atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet \
|
||||
atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet -lrumpdev \
|
||||
-lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\
|
||||
${RUMP_SERVER}
|
||||
|
||||
|
3
dist/fs/puffs/h_dtfs/Makefile
vendored
3
dist/fs/puffs/h_dtfs/Makefile
vendored
@ -1,10 +1,11 @@
|
||||
# $NetBSD: Makefile,v 1.4 2010/07/13 21:13:23 jmmv Exp $
|
||||
# $NetBSD: Makefile,v 1.5 2016/01/23 21:22:48 christos Exp $
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/fs/puffs/h_dtfs
|
||||
ATFFILE= no
|
||||
|
||||
TESTS_C= h_dtfs
|
||||
|
||||
CPPFLAGS+= -D_KERNTYPES
|
||||
SRCS.h_dtfs= dtfs.c dtfs_vfsops.c dtfs_vnops.c dtfs_subr.c
|
||||
LDADD+= -lpuffs -lutil
|
||||
|
||||
|
8
dist/fs/tmpfs/t_vnd.sh
vendored
8
dist/fs/tmpfs/t_vnd.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_vnd.sh,v 1.8 2011/04/21 22:26:46 haad Exp $
|
||||
# $NetBSD: t_vnd.sh,v 1.9 2016/07/29 05:23:24 pgoyette Exp $
|
||||
#
|
||||
# Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -38,7 +38,7 @@ basic_body() {
|
||||
|
||||
atf_check -s eq:0 -o ignore -e ignore \
|
||||
dd if=/dev/zero of=disk.img bs=1m count=10
|
||||
atf_check -s eq:0 -o empty -e empty vnconfig /dev/vnd3 disk.img
|
||||
atf_check -s eq:0 -o empty -e empty vndconfig /dev/vnd3 disk.img
|
||||
|
||||
atf_check -s eq:0 -o ignore -e ignore newfs /dev/rvnd3a
|
||||
|
||||
@ -58,7 +58,7 @@ basic_body() {
|
||||
done
|
||||
|
||||
atf_check -s eq:0 -o empty -e empty umount mnt
|
||||
atf_check -s eq:0 -o empty -e empty vnconfig -u /dev/vnd3
|
||||
atf_check -s eq:0 -o empty -e empty vndconfig -u /dev/vnd3
|
||||
|
||||
test_unmount
|
||||
touch done
|
||||
@ -66,7 +66,7 @@ basic_body() {
|
||||
basic_cleanup() {
|
||||
if [ ! -f done ]; then
|
||||
umount mnt 2>/dev/null 1>&2
|
||||
vnconfig -u /dev/vnd3 2>/dev/null 1>&2
|
||||
vndconfig -u /dev/vnd3 2>/dev/null 1>&2
|
||||
fi
|
||||
}
|
||||
|
||||
|
5
dist/fs/vfs/Makefile
vendored
5
dist/fs/vfs/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.19 2013/06/28 13:04:06 reinoud Exp $
|
||||
# $NetBSD: Makefile,v 1.20 2015/01/07 22:24:03 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -35,7 +35,8 @@ LDADD+=-L${VFSTESTDIR} -lvfstest
|
||||
|
||||
LDADD+=-lrumpfs_nfs # NFS
|
||||
LDADD+=-lrumpnet_shmif -lrumpnet_netinet -lrumpnet_net -lrumpnet
|
||||
LDADD+=-lrumpvfs -lrump -lrumpuser -lpthread # base
|
||||
LDADD+=-lrumpvfs -lrumpkern_sysproxy -lrump -lrumpuser # base
|
||||
LDADD+=-lpthread
|
||||
|
||||
LDADD+=-lutil
|
||||
|
||||
|
20
dist/fs/vfs/t_io.c
vendored
20
dist/fs/vfs/t_io.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_io.c,v 1.12 2013/08/04 11:02:02 pooka Exp $ */
|
||||
/* $NetBSD: t_io.c,v 1.16 2015/04/04 12:34:44 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -222,6 +222,22 @@ wrrd_after_unlink(const atf_tc_t *tc, const char *mp)
|
||||
FSTEST_EXIT();
|
||||
}
|
||||
|
||||
static void
|
||||
read_fault(const atf_tc_t *tc, const char *mp)
|
||||
{
|
||||
char ch = 123;
|
||||
int fd;
|
||||
|
||||
FSTEST_ENTER();
|
||||
RL(fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777));
|
||||
ATF_REQUIRE_EQ(rump_sys_write(fd, &ch, 1), 1);
|
||||
RL(rump_sys_close(fd));
|
||||
RL(fd = rump_sys_open("file", O_RDONLY | O_SYNC | O_RSYNC));
|
||||
ATF_REQUIRE_ERRNO(EFAULT, rump_sys_read(fd, NULL, 1) == -1);
|
||||
RL(rump_sys_close(fd));
|
||||
FSTEST_EXIT();
|
||||
}
|
||||
|
||||
ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole");
|
||||
ATF_TC_FSAPPLY(extendfile, "check that extending a file works");
|
||||
ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works "
|
||||
@ -232,6 +248,7 @@ ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite");
|
||||
ATF_TC_FSAPPLY(shrinkfile, "shrink file");
|
||||
ATF_TC_FSAPPLY(read_after_unlink, "contents can be read off disk after unlink");
|
||||
ATF_TC_FSAPPLY(wrrd_after_unlink, "file can be written and read after unlink");
|
||||
ATF_TC_FSAPPLY(read_fault, "read at bad address must return EFAULT");
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
@ -245,6 +262,7 @@ ATF_TP_ADD_TCS(tp)
|
||||
ATF_TP_FSAPPLY(shrinkfile);
|
||||
ATF_TP_FSAPPLY(read_after_unlink);
|
||||
ATF_TP_FSAPPLY(wrrd_after_unlink);
|
||||
ATF_TP_FSAPPLY(read_fault);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
4
dist/fs/vfs/t_renamerace.c
vendored
4
dist/fs/vfs/t_renamerace.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_renamerace.c,v 1.32 2014/07/29 09:15:48 gson Exp $ */
|
||||
/* $NetBSD: t_renamerace.c,v 1.33 2016/05/04 08:30:22 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Modified for rump and atf from a program supplied
|
||||
@ -127,7 +127,7 @@ renamerace(const atf_tc_t *tc, const char *mp)
|
||||
atf_tc_fail("race did not trigger this time");
|
||||
|
||||
if (FSTYPE_MSDOS(tc)) {
|
||||
atf_tc_expect_fail("PR kern/44661");
|
||||
atf_tc_expect_fail("PR kern/43626");
|
||||
/*
|
||||
* XXX: race does not trigger every time at least
|
||||
* on amd64/qemu.
|
||||
|
4
dist/fs/vfs/t_unpriv.c
vendored
4
dist/fs/vfs/t_unpriv.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_unpriv.c,v 1.11 2014/08/29 17:39:18 gson Exp $ */
|
||||
/* $NetBSD: t_unpriv.c,v 1.12 2015/04/09 19:51:13 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
@ -55,8 +55,6 @@ owner(const atf_tc_t *tc, const char *mp)
|
||||
rump_pub_lwproc_rfork(RUMP_RFCFDG);
|
||||
if (rump_sys_setuid(1) == -1)
|
||||
atf_tc_fail_errno("setuid");
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be broken");
|
||||
if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM)
|
||||
atf_tc_fail_errno("chown");
|
||||
if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM)
|
||||
|
105
dist/fs/vfs/t_vnops.c
vendored
105
dist/fs/vfs/t_vnops.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_vnops.c,v 1.43 2014/09/09 06:51:00 gson Exp $ */
|
||||
/* $NetBSD: t_vnops.c,v 1.55 2016/01/28 10:10:09 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <atf-c.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
@ -118,10 +119,10 @@ lookup_complex(const atf_tc_t *tc, const char *mountpath)
|
||||
FIELD(st_uid);
|
||||
FIELD(st_gid);
|
||||
FIELD(st_rdev);
|
||||
TIME(st_atim);
|
||||
TIME(st_mtim);
|
||||
TIME(st_ctim);
|
||||
TIME(st_birthtim);
|
||||
TIME(st_atimespec);
|
||||
TIME(st_mtimespec);
|
||||
TIME(st_ctimespec);
|
||||
TIME(st_birthtimespec);
|
||||
FIELD(st_size);
|
||||
FIELD(st_blocks);
|
||||
FIELD(st_flags);
|
||||
@ -179,8 +180,6 @@ dir_notempty(const atf_tc_t *tc, const char *mountpath)
|
||||
rump_sys_close(fd);
|
||||
|
||||
rv = rump_sys_rmdir(pb);
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be broken");
|
||||
if (rv != -1 || errno != ENOTEMPTY)
|
||||
atf_tc_fail("non-empty directory removed succesfully");
|
||||
|
||||
@ -276,8 +275,6 @@ rename_dir(const atf_tc_t *tc, const char *mp)
|
||||
md(pb1, mp, "dir3/.");
|
||||
if (rump_sys_rename(pb1, pb3) != -1 || errno != EINVAL)
|
||||
atf_tc_fail_errno("rename 2");
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be broken");
|
||||
if (rump_sys_rename(pb3, pb1) != -1 || errno != EISDIR)
|
||||
atf_tc_fail_errno("rename 3");
|
||||
|
||||
@ -442,6 +439,78 @@ rename_reg_nodir(const atf_tc_t *tc, const char *mp)
|
||||
rump_sys_chdir("/");
|
||||
}
|
||||
|
||||
/* PR kern/50607 */
|
||||
static void
|
||||
create_many(const atf_tc_t *tc, const char *mp)
|
||||
{
|
||||
char buf[64];
|
||||
int nfiles = 2324; /* #Nancy */
|
||||
int i;
|
||||
|
||||
/* takes forever with many files */
|
||||
if (FSTYPE_MSDOS(tc))
|
||||
nfiles /= 4;
|
||||
|
||||
RL(rump_sys_chdir(mp));
|
||||
|
||||
if (FSTYPE_SYSVBFS(tc)) {
|
||||
/* fs doesn't support many files or subdirectories */
|
||||
nfiles = 5;
|
||||
} else {
|
||||
/* msdosfs doesn't like many entries in the root directory */
|
||||
RL(rump_sys_mkdir("subdir", 0777));
|
||||
RL(rump_sys_chdir("subdir"));
|
||||
}
|
||||
|
||||
/* create them */
|
||||
#define TESTFN "testfile"
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
int fd;
|
||||
|
||||
sprintf(buf, TESTFN "%d", i);
|
||||
RL(fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666));
|
||||
RL(rump_sys_close(fd));
|
||||
}
|
||||
|
||||
/* wipe them out */
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
sprintf(buf, TESTFN "%d", i);
|
||||
RL(rump_sys_unlink(buf));
|
||||
}
|
||||
#undef TESTFN
|
||||
|
||||
rump_sys_chdir("/");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test creating files with one-character names using all possible
|
||||
* character values. Failures to create the file are ignored as the
|
||||
* characters allowed in file names vary by file system, but at least
|
||||
* we can check that the fs does not crash, and if the file is
|
||||
* successfully created, unlinking it should also succeed.
|
||||
*/
|
||||
static void
|
||||
create_nonalphanum(const atf_tc_t *tc, const char *mp)
|
||||
{
|
||||
char buf[64];
|
||||
int i;
|
||||
|
||||
RL(rump_sys_chdir(mp));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int fd;
|
||||
sprintf(buf, "%c", i);
|
||||
fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
continue;
|
||||
RL(rump_sys_close(fd));
|
||||
RL(rump_sys_unlink(buf));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
rump_sys_chdir("/");
|
||||
}
|
||||
|
||||
static void
|
||||
create_nametoolong(const atf_tc_t *tc, const char *mp)
|
||||
{
|
||||
@ -645,8 +714,6 @@ attrs(const atf_tc_t *tc, const char *mp)
|
||||
|
||||
RL(rump_sys_stat(TESTFILE, &sb2));
|
||||
#define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a)
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be broken");
|
||||
if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
|
||||
CHECK(st_uid);
|
||||
CHECK(st_gid);
|
||||
@ -684,9 +751,6 @@ fcntl_lock(const atf_tc_t *tc, const char *mp)
|
||||
RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
|
||||
RL(rump_sys_ftruncate(fd, 8192));
|
||||
|
||||
/* PR kern/43321 */
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be broken");
|
||||
RL(rump_sys_fcntl(fd, F_SETLK, &l));
|
||||
|
||||
/* Next, we fork and try to lock the same area */
|
||||
@ -820,9 +884,6 @@ fcntl_getlock_pids(const atf_tc_t *tc, const char *mp)
|
||||
|
||||
RL(rump_sys_ftruncate(fd[i], sz));
|
||||
|
||||
if (FSTYPE_ZFS(tc))
|
||||
atf_tc_expect_fail("PR kern/47656: Test known to be "
|
||||
"broken");
|
||||
if (i < __arraycount(lock)) {
|
||||
RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i]));
|
||||
expect[i].l_pid = pid[i];
|
||||
@ -932,9 +993,6 @@ lstat_symlink(const atf_tc_t *tc, const char *mp)
|
||||
|
||||
USES_SYMLINKS;
|
||||
|
||||
if (FSTYPE_V7FS(tc))
|
||||
atf_tc_expect_fail("PR kern/48864");
|
||||
|
||||
FSTEST_ENTER();
|
||||
|
||||
src = "source";
|
||||
@ -973,6 +1031,11 @@ ATF_TC_FSAPPLY(access_simple, "access(2)");
|
||||
ATF_TC_FSAPPLY(read_directory, "read(2) on directories");
|
||||
ATF_TC_FSAPPLY(lstat_symlink, "lstat(2) values for symbolic links");
|
||||
|
||||
#undef FSTEST_IMGSIZE
|
||||
#define FSTEST_IMGSIZE (1024*1024*64)
|
||||
ATF_TC_FSAPPLY(create_many, "create many directory entries");
|
||||
ATF_TC_FSAPPLY(create_nonalphanum, "non-alphanumeric filenames");
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
@ -984,6 +1047,8 @@ ATF_TP_ADD_TCS(tp)
|
||||
ATF_TP_FSAPPLY(rename_dir);
|
||||
ATF_TP_FSAPPLY(rename_dotdot);
|
||||
ATF_TP_FSAPPLY(rename_reg_nodir);
|
||||
ATF_TP_FSAPPLY(create_many);
|
||||
ATF_TP_FSAPPLY(create_nonalphanum);
|
||||
ATF_TP_FSAPPLY(create_nametoolong);
|
||||
ATF_TP_FSAPPLY(create_exist);
|
||||
ATF_TP_FSAPPLY(rename_nametoolong);
|
||||
|
43
dist/games/t_factor.sh
vendored
43
dist/games/t_factor.sh
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: t_factor.sh,v 1.7 2010/11/19 12:31:36 pgoyette Exp $
|
||||
# $NetBSD: t_factor.sh,v 1.9 2016/06/27 05:29:32 pgoyette Exp $
|
||||
#
|
||||
# Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
@ -27,32 +27,55 @@
|
||||
|
||||
expect() {
|
||||
echo "${2}" >expout
|
||||
ncrypt=$( ldd /usr/games/factor | grep -c -- -lcrypt )
|
||||
if [ "X$3" != "X" -a $ncrypt -eq 0 ] ; then
|
||||
atf_skip "crypto needed for huge non-prime factors - PR bin/23663"
|
||||
fi
|
||||
atf_check -s eq:0 -o file:expout -e empty /usr/games/factor ${1}
|
||||
}
|
||||
|
||||
atf_test_case overflow
|
||||
overflow_head() {
|
||||
atf_test_case overflow1
|
||||
overflow1_head() {
|
||||
atf_set "descr" "Tests for overflow conditions"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
}
|
||||
overflow_body() {
|
||||
overflow1_body() {
|
||||
expect '8675309' '8675309: 8675309'
|
||||
}
|
||||
|
||||
atf_test_case overflow2
|
||||
overflow2_head() {
|
||||
atf_set "descr" "Tests for overflow conditions"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
}
|
||||
overflow2_body() {
|
||||
expect '6172538568' '6172538568: 2 2 2 3 7 17 2161253'
|
||||
}
|
||||
|
||||
atf_test_case loop
|
||||
loop_head() {
|
||||
atf_test_case loop1
|
||||
loop1_head() {
|
||||
atf_set "descr" "Tests some cases that once locked the program" \
|
||||
"in an infinite loop"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
}
|
||||
loop_body() {
|
||||
expect '99999999999991' '99999999999991: 7 13 769231 1428571'
|
||||
loop1_body() {
|
||||
expect '2147483647111311' '2147483647111311: 3 3 3 131 607148331103'
|
||||
}
|
||||
|
||||
atf_test_case loop2
|
||||
loop2_head() {
|
||||
atf_set "descr" "Tests some cases that once locked the program" \
|
||||
"in an infinite loop"
|
||||
atf_set "require.progs" "/usr/games/factor"
|
||||
}
|
||||
loop2_body() {
|
||||
expect '99999999999991' '99999999999991: 7 13 769231 1428571' Need_Crypto
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case overflow
|
||||
atf_add_test_case loop
|
||||
atf_add_test_case overflow1
|
||||
atf_add_test_case overflow2
|
||||
atf_add_test_case loop1
|
||||
atf_add_test_case loop2
|
||||
}
|
||||
|
6
dist/h_macros.h
vendored
6
dist/h_macros.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: h_macros.h,v 1.9 2013/05/17 15:42:09 christos Exp $ */
|
||||
/* $NetBSD: h_macros.h,v 1.12 2016/08/04 11:49:07 jakllsch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||
@ -51,7 +51,7 @@ do { \
|
||||
ATF_REQUIRE_MSG(RZ_rv == 0, "%s: %s", #x, strerror(RZ_rv)); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
static __inline __printflike(1, 2) void
|
||||
__dead static __inline __printflike(1, 2) void
|
||||
atf_tc_fail_errno(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -75,7 +75,7 @@ tests_makegarbage(void *space, size_t len)
|
||||
uint16_t randval;
|
||||
|
||||
while (len >= sizeof(randval)) {
|
||||
*sb++ = (random() & 0xffff);
|
||||
*sb++ = (uint16_t)random();
|
||||
len -= sizeof(*sb);
|
||||
}
|
||||
randval = (uint16_t)random();
|
||||
|
15
dist/include/sys/Makefile
vendored
15
dist/include/sys/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.7 2012/08/08 13:57:06 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.12 2016/08/08 14:11:08 pgoyette Exp $
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
@ -6,14 +6,21 @@ NOMAN= # defined
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/include/sys
|
||||
|
||||
TESTS_C= t_bitops t_bootblock t_cdefs t_tree t_types
|
||||
TESTS_C+= t_bitops
|
||||
TESTS_C+= t_bootblock
|
||||
TESTS_C+= t_cdefs
|
||||
TESTS_C+= t_pslist
|
||||
TESTS_C+= t_tree
|
||||
TESTS_C+= t_types
|
||||
|
||||
CPPFLAGS.t_pslist.c+= -I${NETBSDSRCDIR}/sys
|
||||
LDADD.t_bitops+= -lm
|
||||
|
||||
.if (${MKRUMP} != "no")
|
||||
.if (${MKRUMP} != "no") && !defined(BSD_MK_COMPAT_FILE)
|
||||
TESTS_C+= t_socket
|
||||
CPPFLAGS.t_socket.c+= -D_KERNTYPES
|
||||
LDADD.t_socket+= -lrumpnet_local -lrumpnet_net -lrumpnet
|
||||
LDADD.t_socket+= -lrumpvfs -lrump -lrumpuser -lpthread
|
||||
LDADD.t_socket+= -lrumpvfs -lrump -lrumpuser -lpthread -lrumpdev
|
||||
.endif
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
204
dist/include/sys/t_bitops.c
vendored
204
dist/include/sys/t_bitops.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_bitops.c,v 1.16 2012/12/07 02:28:19 christos Exp $ */
|
||||
/* $NetBSD: t_bitops.c,v 1.19 2015/03/21 05:50:19 isaki Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011, 2012 The NetBSD Foundation, Inc.
|
||||
@ -29,7 +29,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: t_bitops.c,v 1.16 2012/12/07 02:28:19 christos Exp $");
|
||||
__RCSID("$NetBSD: t_bitops.c,v 1.19 2015/03/21 05:50:19 isaki Exp $");
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
@ -67,7 +67,7 @@ static const struct {
|
||||
ATF_TC(bitmap_basic);
|
||||
ATF_TC_HEAD(bitmap_basic, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "A basic test of __BITMAP_*");
|
||||
atf_tc_set_md_var(tc, "descr", "A basic test of __BITMAP_*");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(bitmap_basic, tc)
|
||||
@ -174,65 +174,191 @@ ATF_TC_BODY(ffsfls, tc)
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC(ilog2_basic);
|
||||
ATF_TC_HEAD(ilog2_basic, tc)
|
||||
ATF_TC(ilog2_32bit);
|
||||
ATF_TC_HEAD(ilog2_32bit, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for correctness");
|
||||
atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for 32bit variable");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(ilog2_basic, tc)
|
||||
ATF_TC_BODY(ilog2_32bit, tc)
|
||||
{
|
||||
uint64_t i, x;
|
||||
int i;
|
||||
uint32_t x;
|
||||
|
||||
for (i = x = 0; i < 64; i++) {
|
||||
|
||||
x = (uint64_t)1 << i;
|
||||
|
||||
ATF_REQUIRE(i == (uint64_t)ilog2(x));
|
||||
for (i = 0; i < 32; i++) {
|
||||
x = 1 << i;
|
||||
ATF_REQUIRE(ilog2(x) == i);
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC(ilog2_log2);
|
||||
ATF_TC_HEAD(ilog2_log2, tc)
|
||||
ATF_TC(ilog2_64bit);
|
||||
ATF_TC_HEAD(ilog2_64bit, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Test log2(3) vs. ilog2(3)");
|
||||
atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for 64bit variable");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(ilog2_log2, tc)
|
||||
ATF_TC_BODY(ilog2_64bit, tc)
|
||||
{
|
||||
#ifdef __vax__
|
||||
atf_tc_skip("Test is unavailable on vax because of lack of log2()");
|
||||
#else
|
||||
double x, y;
|
||||
uint64_t i;
|
||||
int i;
|
||||
uint64_t x;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
x = ((uint64_t)1) << i;
|
||||
ATF_REQUIRE(ilog2(x) == i);
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC(ilog2_const);
|
||||
ATF_TC_HEAD(ilog2_const, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for constant");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(ilog2_const, tc)
|
||||
{
|
||||
/*
|
||||
* This may fail under QEMU; see PR misc/44767.
|
||||
* These inlines test __builtin_constant_p() part of ilog2()
|
||||
* at compile time, so don't change it to loop. PR lib/49745
|
||||
*/
|
||||
for (i = 1; i < UINT32_MAX; i += UINT16_MAX) {
|
||||
ATF_REQUIRE(ilog2(0x0000000000000001ULL) == 0);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000002ULL) == 1);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000004ULL) == 2);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000008ULL) == 3);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000010ULL) == 4);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000020ULL) == 5);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000040ULL) == 6);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000080ULL) == 7);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000100ULL) == 8);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000200ULL) == 9);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000400ULL) == 10);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000800ULL) == 11);
|
||||
ATF_REQUIRE(ilog2(0x0000000000001000ULL) == 12);
|
||||
ATF_REQUIRE(ilog2(0x0000000000002000ULL) == 13);
|
||||
ATF_REQUIRE(ilog2(0x0000000000004000ULL) == 14);
|
||||
ATF_REQUIRE(ilog2(0x0000000000008000ULL) == 15);
|
||||
ATF_REQUIRE(ilog2(0x0000000000010000ULL) == 16);
|
||||
ATF_REQUIRE(ilog2(0x0000000000020000ULL) == 17);
|
||||
ATF_REQUIRE(ilog2(0x0000000000040000ULL) == 18);
|
||||
ATF_REQUIRE(ilog2(0x0000000000080000ULL) == 19);
|
||||
ATF_REQUIRE(ilog2(0x0000000000100000ULL) == 20);
|
||||
ATF_REQUIRE(ilog2(0x0000000000200000ULL) == 21);
|
||||
ATF_REQUIRE(ilog2(0x0000000000400000ULL) == 22);
|
||||
ATF_REQUIRE(ilog2(0x0000000000800000ULL) == 23);
|
||||
ATF_REQUIRE(ilog2(0x0000000001000000ULL) == 24);
|
||||
ATF_REQUIRE(ilog2(0x0000000002000000ULL) == 25);
|
||||
ATF_REQUIRE(ilog2(0x0000000004000000ULL) == 26);
|
||||
ATF_REQUIRE(ilog2(0x0000000008000000ULL) == 27);
|
||||
ATF_REQUIRE(ilog2(0x0000000010000000ULL) == 28);
|
||||
ATF_REQUIRE(ilog2(0x0000000020000000ULL) == 29);
|
||||
ATF_REQUIRE(ilog2(0x0000000040000000ULL) == 30);
|
||||
ATF_REQUIRE(ilog2(0x0000000080000000ULL) == 31);
|
||||
ATF_REQUIRE(ilog2(0x0000000100000000ULL) == 32);
|
||||
ATF_REQUIRE(ilog2(0x0000000200000000ULL) == 33);
|
||||
ATF_REQUIRE(ilog2(0x0000000400000000ULL) == 34);
|
||||
ATF_REQUIRE(ilog2(0x0000000800000000ULL) == 35);
|
||||
ATF_REQUIRE(ilog2(0x0000001000000000ULL) == 36);
|
||||
ATF_REQUIRE(ilog2(0x0000002000000000ULL) == 37);
|
||||
ATF_REQUIRE(ilog2(0x0000004000000000ULL) == 38);
|
||||
ATF_REQUIRE(ilog2(0x0000008000000000ULL) == 39);
|
||||
ATF_REQUIRE(ilog2(0x0000010000000000ULL) == 40);
|
||||
ATF_REQUIRE(ilog2(0x0000020000000000ULL) == 41);
|
||||
ATF_REQUIRE(ilog2(0x0000040000000000ULL) == 42);
|
||||
ATF_REQUIRE(ilog2(0x0000080000000000ULL) == 43);
|
||||
ATF_REQUIRE(ilog2(0x0000100000000000ULL) == 44);
|
||||
ATF_REQUIRE(ilog2(0x0000200000000000ULL) == 45);
|
||||
ATF_REQUIRE(ilog2(0x0000400000000000ULL) == 46);
|
||||
ATF_REQUIRE(ilog2(0x0000800000000000ULL) == 47);
|
||||
ATF_REQUIRE(ilog2(0x0001000000000000ULL) == 48);
|
||||
ATF_REQUIRE(ilog2(0x0002000000000000ULL) == 49);
|
||||
ATF_REQUIRE(ilog2(0x0004000000000000ULL) == 50);
|
||||
ATF_REQUIRE(ilog2(0x0008000000000000ULL) == 51);
|
||||
ATF_REQUIRE(ilog2(0x0010000000000000ULL) == 52);
|
||||
ATF_REQUIRE(ilog2(0x0020000000000000ULL) == 53);
|
||||
ATF_REQUIRE(ilog2(0x0040000000000000ULL) == 54);
|
||||
ATF_REQUIRE(ilog2(0x0080000000000000ULL) == 55);
|
||||
ATF_REQUIRE(ilog2(0x0100000000000000ULL) == 56);
|
||||
ATF_REQUIRE(ilog2(0x0200000000000000ULL) == 57);
|
||||
ATF_REQUIRE(ilog2(0x0400000000000000ULL) == 58);
|
||||
ATF_REQUIRE(ilog2(0x0800000000000000ULL) == 59);
|
||||
ATF_REQUIRE(ilog2(0x1000000000000000ULL) == 60);
|
||||
ATF_REQUIRE(ilog2(0x2000000000000000ULL) == 61);
|
||||
ATF_REQUIRE(ilog2(0x4000000000000000ULL) == 62);
|
||||
ATF_REQUIRE(ilog2(0x8000000000000000ULL) == 63);
|
||||
|
||||
x = log2(i);
|
||||
y = (double)(ilog2(i));
|
||||
|
||||
ATF_REQUIRE(ceil(x) >= y);
|
||||
|
||||
if (fabs(floor(x) - y) > 1.0e-40) {
|
||||
atf_tc_expect_fail("PR misc/44767");
|
||||
atf_tc_fail("log2(%"PRIu64") != "
|
||||
"ilog2(%"PRIu64")", i, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ATF_REQUIRE(ilog2(0x0000000000000003ULL) == 1);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000007ULL) == 2);
|
||||
ATF_REQUIRE(ilog2(0x000000000000000fULL) == 3);
|
||||
ATF_REQUIRE(ilog2(0x000000000000001fULL) == 4);
|
||||
ATF_REQUIRE(ilog2(0x000000000000003fULL) == 5);
|
||||
ATF_REQUIRE(ilog2(0x000000000000007fULL) == 6);
|
||||
ATF_REQUIRE(ilog2(0x00000000000000ffULL) == 7);
|
||||
ATF_REQUIRE(ilog2(0x00000000000001ffULL) == 8);
|
||||
ATF_REQUIRE(ilog2(0x00000000000003ffULL) == 9);
|
||||
ATF_REQUIRE(ilog2(0x00000000000007ffULL) == 10);
|
||||
ATF_REQUIRE(ilog2(0x0000000000000fffULL) == 11);
|
||||
ATF_REQUIRE(ilog2(0x0000000000001fffULL) == 12);
|
||||
ATF_REQUIRE(ilog2(0x0000000000003fffULL) == 13);
|
||||
ATF_REQUIRE(ilog2(0x0000000000007fffULL) == 14);
|
||||
ATF_REQUIRE(ilog2(0x000000000000ffffULL) == 15);
|
||||
ATF_REQUIRE(ilog2(0x000000000001ffffULL) == 16);
|
||||
ATF_REQUIRE(ilog2(0x000000000003ffffULL) == 17);
|
||||
ATF_REQUIRE(ilog2(0x000000000007ffffULL) == 18);
|
||||
ATF_REQUIRE(ilog2(0x00000000000fffffULL) == 19);
|
||||
ATF_REQUIRE(ilog2(0x00000000001fffffULL) == 20);
|
||||
ATF_REQUIRE(ilog2(0x00000000003fffffULL) == 21);
|
||||
ATF_REQUIRE(ilog2(0x00000000007fffffULL) == 22);
|
||||
ATF_REQUIRE(ilog2(0x0000000000ffffffULL) == 23);
|
||||
ATF_REQUIRE(ilog2(0x0000000001ffffffULL) == 24);
|
||||
ATF_REQUIRE(ilog2(0x0000000003ffffffULL) == 25);
|
||||
ATF_REQUIRE(ilog2(0x0000000007ffffffULL) == 26);
|
||||
ATF_REQUIRE(ilog2(0x000000000fffffffULL) == 27);
|
||||
ATF_REQUIRE(ilog2(0x000000001fffffffULL) == 28);
|
||||
ATF_REQUIRE(ilog2(0x000000003fffffffULL) == 29);
|
||||
ATF_REQUIRE(ilog2(0x000000007fffffffULL) == 30);
|
||||
ATF_REQUIRE(ilog2(0x00000000ffffffffULL) == 31);
|
||||
ATF_REQUIRE(ilog2(0x00000001ffffffffULL) == 32);
|
||||
ATF_REQUIRE(ilog2(0x00000003ffffffffULL) == 33);
|
||||
ATF_REQUIRE(ilog2(0x00000007ffffffffULL) == 34);
|
||||
ATF_REQUIRE(ilog2(0x0000000fffffffffULL) == 35);
|
||||
ATF_REQUIRE(ilog2(0x0000001fffffffffULL) == 36);
|
||||
ATF_REQUIRE(ilog2(0x0000003fffffffffULL) == 37);
|
||||
ATF_REQUIRE(ilog2(0x0000007fffffffffULL) == 38);
|
||||
ATF_REQUIRE(ilog2(0x000000ffffffffffULL) == 39);
|
||||
ATF_REQUIRE(ilog2(0x000001ffffffffffULL) == 40);
|
||||
ATF_REQUIRE(ilog2(0x000003ffffffffffULL) == 41);
|
||||
ATF_REQUIRE(ilog2(0x000007ffffffffffULL) == 42);
|
||||
ATF_REQUIRE(ilog2(0x00000fffffffffffULL) == 43);
|
||||
ATF_REQUIRE(ilog2(0x00001fffffffffffULL) == 44);
|
||||
ATF_REQUIRE(ilog2(0x00003fffffffffffULL) == 45);
|
||||
ATF_REQUIRE(ilog2(0x00007fffffffffffULL) == 46);
|
||||
ATF_REQUIRE(ilog2(0x0000ffffffffffffULL) == 47);
|
||||
ATF_REQUIRE(ilog2(0x0001ffffffffffffULL) == 48);
|
||||
ATF_REQUIRE(ilog2(0x0003ffffffffffffULL) == 49);
|
||||
ATF_REQUIRE(ilog2(0x0007ffffffffffffULL) == 50);
|
||||
ATF_REQUIRE(ilog2(0x000fffffffffffffULL) == 51);
|
||||
ATF_REQUIRE(ilog2(0x001fffffffffffffULL) == 52);
|
||||
ATF_REQUIRE(ilog2(0x003fffffffffffffULL) == 53);
|
||||
ATF_REQUIRE(ilog2(0x007fffffffffffffULL) == 54);
|
||||
ATF_REQUIRE(ilog2(0x00ffffffffffffffULL) == 55);
|
||||
ATF_REQUIRE(ilog2(0x01ffffffffffffffULL) == 56);
|
||||
ATF_REQUIRE(ilog2(0x03ffffffffffffffULL) == 57);
|
||||
ATF_REQUIRE(ilog2(0x07ffffffffffffffULL) == 58);
|
||||
ATF_REQUIRE(ilog2(0x0fffffffffffffffULL) == 59);
|
||||
ATF_REQUIRE(ilog2(0x1fffffffffffffffULL) == 60);
|
||||
ATF_REQUIRE(ilog2(0x3fffffffffffffffULL) == 61);
|
||||
ATF_REQUIRE(ilog2(0x7fffffffffffffffULL) == 62);
|
||||
ATF_REQUIRE(ilog2(0xffffffffffffffffULL) == 63);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, bitmap_basic);
|
||||
ATF_TP_ADD_TC(tp, bitmap_basic);
|
||||
ATF_TP_ADD_TC(tp, fast_divide32);
|
||||
ATF_TP_ADD_TC(tp, ffsfls);
|
||||
ATF_TP_ADD_TC(tp, ilog2_basic);
|
||||
ATF_TP_ADD_TC(tp, ilog2_log2);
|
||||
ATF_TP_ADD_TC(tp, ilog2_32bit);
|
||||
ATF_TP_ADD_TC(tp, ilog2_64bit);
|
||||
ATF_TP_ADD_TC(tp, ilog2_const);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
100
dist/include/sys/t_cdefs.c
vendored
100
dist/include/sys/t_cdefs.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_cdefs.c,v 1.3 2013/09/05 09:01:27 gsutre Exp $ */
|
||||
/* $NetBSD: t_cdefs.c,v 1.4 2016/03/16 07:21:36 mrg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
@ -32,7 +32,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__COPYRIGHT("@(#) Copyright (c) 2008\
|
||||
The NetBSD Foundation, inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: t_cdefs.c,v 1.3 2013/09/05 09:01:27 gsutre Exp $");
|
||||
__RCSID("$NetBSD: t_cdefs.c,v 1.4 2016/03/16 07:21:36 mrg Exp $");
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <sys/types.h>
|
||||
@ -180,34 +180,34 @@ ATF_TC_HEAD(stypefit, tc)
|
||||
|
||||
ATF_TC_BODY(stypefit, tc)
|
||||
{
|
||||
#define CHECK(a, b, c) ATF_REQUIRE(!__type_fit(a, b) == c)
|
||||
#define CHECK(a, b, c) ATF_REQUIRE(__type_fit(a, b) == c)
|
||||
|
||||
CHECK(signed char, -1, 0);
|
||||
CHECK(signed char, 1, 0);
|
||||
CHECK(signed char, 0x7f, 0);
|
||||
CHECK(signed char, 0x80, 1);
|
||||
CHECK(signed char, 0xff, 1);
|
||||
CHECK(signed char, 0x1ff, 1);
|
||||
CHECK(signed char, -1, 1);
|
||||
CHECK(signed char, 1, 1);
|
||||
CHECK(signed char, 0x7f, 1);
|
||||
CHECK(signed char, 0x80, 0);
|
||||
CHECK(signed char, 0xff, 0);
|
||||
CHECK(signed char, 0x1ff, 0);
|
||||
|
||||
CHECK(signed short, -1, 0);
|
||||
CHECK(signed short, 1, 0);
|
||||
CHECK(signed short, 0x7fff, 0);
|
||||
CHECK(signed short, 0x8000, 1);
|
||||
CHECK(signed short, 0xffff, 1);
|
||||
CHECK(signed short, 0x1ffff, 1);
|
||||
CHECK(signed short, -1, 1);
|
||||
CHECK(signed short, 1, 1);
|
||||
CHECK(signed short, 0x7fff, 1);
|
||||
CHECK(signed short, 0x8000, 0);
|
||||
CHECK(signed short, 0xffff, 0);
|
||||
CHECK(signed short, 0x1ffff, 0);
|
||||
|
||||
CHECK(signed int, -1, 0);
|
||||
CHECK(signed int, 1, 0);
|
||||
CHECK(signed int, 0x7fffffff, 0);
|
||||
CHECK(signed int, 0x80000000, 1);
|
||||
CHECK(signed int, 0xffffffff, 1);
|
||||
CHECK(signed int, 0x1ffffffffLL, 1);
|
||||
CHECK(signed int, -1, 1);
|
||||
CHECK(signed int, 1, 1);
|
||||
CHECK(signed int, 0x7fffffff, 1);
|
||||
CHECK(signed int, 0x80000000, 0);
|
||||
CHECK(signed int, 0xffffffff, 0);
|
||||
CHECK(signed int, 0x1ffffffffLL, 0);
|
||||
|
||||
CHECK(signed long long, -1, 0);
|
||||
CHECK(signed long long, 1, 0);
|
||||
CHECK(signed long long, 0x7fffffffffffffffLL, 0);
|
||||
CHECK(signed long long, 0x8000000000000000LL, 1);
|
||||
CHECK(signed long long, 0xffffffffffffffffLL, 1);
|
||||
CHECK(signed long long, -1, 1);
|
||||
CHECK(signed long long, 1, 1);
|
||||
CHECK(signed long long, 0x7fffffffffffffffLL, 1);
|
||||
CHECK(signed long long, 0x8000000000000000LL, 0);
|
||||
CHECK(signed long long, 0xffffffffffffffffLL, 0);
|
||||
|
||||
#undef CHECK
|
||||
}
|
||||
@ -220,34 +220,34 @@ ATF_TC_HEAD(utypefit, tc)
|
||||
|
||||
ATF_TC_BODY(utypefit, tc)
|
||||
{
|
||||
#define CHECK(a, b, c) ATF_REQUIRE(!__type_fit(a, b) == c)
|
||||
#define CHECK(a, b, c) ATF_REQUIRE(__type_fit(a, b) == c)
|
||||
|
||||
CHECK(unsigned char, -1, 1);
|
||||
CHECK(unsigned char, 1, 0);
|
||||
CHECK(unsigned char, 0x7f, 0);
|
||||
CHECK(unsigned char, 0x80, 0);
|
||||
CHECK(unsigned char, 0xff, 0);
|
||||
CHECK(unsigned char, 0x1ff, 1);
|
||||
CHECK(unsigned char, -1, 0);
|
||||
CHECK(unsigned char, 1, 1);
|
||||
CHECK(unsigned char, 0x7f, 1);
|
||||
CHECK(unsigned char, 0x80, 1);
|
||||
CHECK(unsigned char, 0xff, 1);
|
||||
CHECK(unsigned char, 0x1ff, 0);
|
||||
|
||||
CHECK(unsigned short, -1, 1);
|
||||
CHECK(unsigned short, 1, 0);
|
||||
CHECK(unsigned short, 0x7fff, 0);
|
||||
CHECK(unsigned short, 0x8000, 0);
|
||||
CHECK(unsigned short, 0xffff, 0);
|
||||
CHECK(unsigned short, 0x1ffff, 1);
|
||||
CHECK(unsigned short, -1, 0);
|
||||
CHECK(unsigned short, 1, 1);
|
||||
CHECK(unsigned short, 0x7fff, 1);
|
||||
CHECK(unsigned short, 0x8000, 1);
|
||||
CHECK(unsigned short, 0xffff, 1);
|
||||
CHECK(unsigned short, 0x1ffff, 0);
|
||||
|
||||
CHECK(unsigned int, -1, 1);
|
||||
CHECK(unsigned int, 1, 0);
|
||||
CHECK(unsigned int, 0x7fffffff, 0);
|
||||
CHECK(unsigned int, 0x80000000, 0);
|
||||
CHECK(unsigned int, 0xffffffff, 0);
|
||||
CHECK(unsigned int, 0x1ffffffffLL, 1);
|
||||
CHECK(unsigned int, -1, 0);
|
||||
CHECK(unsigned int, 1, 1);
|
||||
CHECK(unsigned int, 0x7fffffff, 1);
|
||||
CHECK(unsigned int, 0x80000000, 1);
|
||||
CHECK(unsigned int, 0xffffffff, 1);
|
||||
CHECK(unsigned int, 0x1ffffffffLL, 0);
|
||||
|
||||
CHECK(unsigned long long, -1, 1);
|
||||
CHECK(unsigned long long, 1, 0);
|
||||
CHECK(unsigned long long, 0x7fffffffffffffffULL, 0);
|
||||
CHECK(unsigned long long, 0x8000000000000000ULL, 0);
|
||||
CHECK(unsigned long long, 0xffffffffffffffffULL, 0);
|
||||
CHECK(unsigned long long, -1, 0);
|
||||
CHECK(unsigned long long, 1, 1);
|
||||
CHECK(unsigned long long, 0x7fffffffffffffffULL, 1);
|
||||
CHECK(unsigned long long, 0x8000000000000000ULL, 1);
|
||||
CHECK(unsigned long long, 0xffffffffffffffffULL, 1);
|
||||
|
||||
#undef CHECK
|
||||
}
|
||||
|
125
dist/include/sys/t_pslist.c
vendored
Normal file
125
dist/include/sys/t_pslist.c
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
/* $NetBSD: t_pslist.c,v 1.1 2016/04/09 04:39:47 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* 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/pslist.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
/*
|
||||
* XXX This is a limited test to make sure the operations behave as
|
||||
* described on a sequential machine. It does nothing to test the
|
||||
* pserialize-safety of any operations.
|
||||
*/
|
||||
|
||||
ATF_TC(misc);
|
||||
ATF_TC_HEAD(misc, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "pserialize-safe list tests");
|
||||
}
|
||||
ATF_TC_BODY(misc, tc)
|
||||
{
|
||||
struct pslist_head h = PSLIST_INITIALIZER;
|
||||
struct element {
|
||||
unsigned i;
|
||||
struct pslist_entry entry;
|
||||
} elements[] = {
|
||||
{ .i = 0, .entry = PSLIST_ENTRY_INITIALIZER },
|
||||
{ .i = 1 },
|
||||
{ .i = 2 },
|
||||
{ .i = 3 },
|
||||
{ .i = 4 },
|
||||
{ .i = 5 },
|
||||
{ .i = 6 },
|
||||
{ .i = 7 },
|
||||
};
|
||||
struct element *element;
|
||||
unsigned i;
|
||||
|
||||
/* Check PSLIST_INITIALIZER is destroyable. */
|
||||
PSLIST_DESTROY(&h);
|
||||
PSLIST_INIT(&h);
|
||||
|
||||
/* Check PSLIST_ENTRY_INITIALIZER is destroyable. */
|
||||
PSLIST_ENTRY_DESTROY(&elements[0], entry);
|
||||
|
||||
for (i = 0; i < __arraycount(elements); i++)
|
||||
PSLIST_ENTRY_INIT(&elements[i], entry);
|
||||
|
||||
PSLIST_WRITER_INSERT_HEAD(&h, &elements[4], entry);
|
||||
PSLIST_WRITER_INSERT_BEFORE(&elements[4], &elements[2], entry);
|
||||
PSLIST_WRITER_INSERT_BEFORE(&elements[4], &elements[3], entry);
|
||||
PSLIST_WRITER_INSERT_BEFORE(&elements[2], &elements[1], entry);
|
||||
PSLIST_WRITER_INSERT_HEAD(&h, &elements[0], entry);
|
||||
PSLIST_WRITER_INSERT_AFTER(&elements[4], &elements[5], entry);
|
||||
PSLIST_WRITER_INSERT_AFTER(&elements[5], &elements[7], entry);
|
||||
PSLIST_WRITER_INSERT_AFTER(&elements[5], &elements[6], entry);
|
||||
|
||||
PSLIST_WRITER_REMOVE(&elements[0], entry);
|
||||
ATF_CHECK(elements[0].entry.ple_next != NULL);
|
||||
PSLIST_ENTRY_DESTROY(&elements[0], entry);
|
||||
|
||||
PSLIST_WRITER_REMOVE(&elements[4], entry);
|
||||
ATF_CHECK(elements[4].entry.ple_next != NULL);
|
||||
PSLIST_ENTRY_DESTROY(&elements[4], entry);
|
||||
|
||||
PSLIST_ENTRY_INIT(&elements[0], entry);
|
||||
PSLIST_WRITER_INSERT_HEAD(&h, &elements[0], entry);
|
||||
|
||||
PSLIST_ENTRY_INIT(&elements[4], entry);
|
||||
PSLIST_WRITER_INSERT_AFTER(&elements[3], &elements[4], entry);
|
||||
|
||||
i = 0;
|
||||
PSLIST_WRITER_FOREACH(element, &h, struct element, entry) {
|
||||
ATF_CHECK_EQ(i, element->i);
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
PSLIST_READER_FOREACH(element, &h, struct element, entry) {
|
||||
ATF_CHECK_EQ(i, element->i);
|
||||
i++;
|
||||
}
|
||||
|
||||
while ((element = PSLIST_WRITER_FIRST(&h, struct element, entry))
|
||||
!= NULL) {
|
||||
PSLIST_WRITER_REMOVE(element, entry);
|
||||
PSLIST_ENTRY_DESTROY(element, entry);
|
||||
}
|
||||
|
||||
PSLIST_DESTROY(&h);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, misc);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
4
dist/include/sys/t_socket.c
vendored
4
dist/include/sys/t_socket.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_socket.c,v 1.3 2013/10/19 17:45:00 christos Exp $ */
|
||||
/* $NetBSD: t_socket.c,v 1.4 2015/02/27 08:30:30 martin Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
@ -74,7 +74,7 @@ ATF_TC(cmsg_sendfd);
|
||||
ATF_TC_HEAD(cmsg_sendfd, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Checks that fd passing works");
|
||||
atf_tc_set_md_var(tc, "timeout", "2");
|
||||
atf_tc_set_md_var(tc, "timeout", "10");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(cmsg_sendfd, tc)
|
||||
|
24
dist/include/t_paths.c
vendored
24
dist/include/t_paths.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_paths.c,v 1.13 2014/02/09 21:26:07 jmmv Exp $ */
|
||||
/* $NetBSD: t_paths.c,v 1.16 2015/05/07 06:23:23 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
@ -29,7 +29,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: t_paths.c,v 1.13 2014/02/09 21:26:07 jmmv Exp $");
|
||||
__RCSID("$NetBSD: t_paths.c,v 1.16 2015/05/07 06:23:23 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
@ -42,12 +42,12 @@ __RCSID("$NetBSD: t_paths.c,v 1.13 2014/02/09 21:26:07 jmmv Exp $");
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <atf-c/config.h>
|
||||
|
||||
#define PATH_DEV __BIT(0) /* A device node */
|
||||
#define PATH_DIR __BIT(1) /* A directory */
|
||||
#define PATH_FILE __BIT(2) /* A file */
|
||||
#define PATH_ROOT __BIT(3) /* Access for root only */
|
||||
#define PATH_OPT __BIT(3) /* Optional, ENODEV if not supported */
|
||||
|
||||
static const struct {
|
||||
const char *path;
|
||||
@ -83,7 +83,7 @@ static const struct {
|
||||
{ _PATH_MIXER, PATH_DEV },
|
||||
{ _PATH_MIXER0, PATH_DEV },
|
||||
{ _PATH_NOLOGIN, PATH_FILE },
|
||||
{ _PATH_POWER, PATH_DEV | PATH_ROOT },
|
||||
{ _PATH_POWER, PATH_DEV | PATH_ROOT | PATH_OPT },
|
||||
{ _PATH_PRINTCAP, PATH_FILE },
|
||||
{ _PATH_PUD, PATH_DEV | PATH_ROOT },
|
||||
{ _PATH_PUFFS, PATH_DEV | PATH_ROOT },
|
||||
@ -93,12 +93,13 @@ static const struct {
|
||||
{ _PATH_SKEYKEYS, PATH_FILE | PATH_ROOT },
|
||||
{ _PATH_SOUND, PATH_DEV },
|
||||
{ _PATH_SOUND0, PATH_DEV },
|
||||
{ _PATH_SYSMON, PATH_DEV },
|
||||
{ _PATH_SYSMON, PATH_DEV | PATH_OPT },
|
||||
{ _PATH_TTY, PATH_DEV },
|
||||
{ _PATH_UNIX, PATH_FILE | PATH_ROOT },
|
||||
{ _PATH_URANDOM, PATH_DEV },
|
||||
{ _PATH_VIDEO, PATH_DEV },
|
||||
{ _PATH_VIDEO0, PATH_DEV },
|
||||
{ _PATH_WATCHDOG, PATH_DEV | PATH_OPT },
|
||||
|
||||
{ _PATH_DEV, PATH_DIR },
|
||||
{ _PATH_DEV_PTS, PATH_DIR },
|
||||
@ -144,13 +145,22 @@ ATF_TC_BODY(paths, tc)
|
||||
|
||||
switch (errno) {
|
||||
|
||||
case ENODEV:
|
||||
if ((paths[i].flags & PATH_OPT) == 0) {
|
||||
|
||||
atf_tc_fail("Required path %s does "
|
||||
"not exist", paths[i].path);
|
||||
}
|
||||
break;
|
||||
|
||||
case EPERM: /* FALLTHROUGH */
|
||||
case EACCES: /* FALLTHROUGH */
|
||||
|
||||
if ((paths[i].flags & PATH_ROOT) == 0) {
|
||||
|
||||
atf_tc_fail("UID %u failed to open %s",
|
||||
(uint32_t)uid, paths[i].path);
|
||||
atf_tc_fail("UID %u failed to open %s, "
|
||||
"error %d", (uint32_t)uid,
|
||||
paths[i].path, errno);
|
||||
}
|
||||
|
||||
case EBUSY: /* FALLTHROUGH */
|
||||
|
6
dist/ipf/expected/n14
vendored
6
dist/ipf/expected/n14
vendored
@ -11,9 +11,9 @@ RDR 10.1.1.253 80 <- -> 203.1.1.1 80 [10.2.2.6 2000]
|
||||
RDR 10.1.1.254 80 <- -> 203.1.1.1 80 [10.2.2.5 2000]
|
||||
|
||||
Hostmap table:
|
||||
10.2.2.7,203.1.1.1 -> 254.1.1.10,0.0.0.0 (use = 1)
|
||||
10.2.2.6,203.1.1.1 -> 253.1.1.10,0.0.0.0 (use = 1)
|
||||
10.2.2.5,203.1.1.1 -> 254.1.1.10,0.0.0.0 (use = 1)
|
||||
10.2.2.7,203.1.1.1 -> 10.1.1.254,0.0.0.0 (use = 1)
|
||||
10.2.2.6,203.1.1.1 -> 10.1.1.253,0.0.0.0 (use = 1)
|
||||
10.2.2.5,203.1.1.1 -> 10.1.1.254,0.0.0.0 (use = 1)
|
||||
List of active state sessions:
|
||||
List of configured pools
|
||||
List of configured hash tables
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user