1*ff906b15Skre# $NetBSD: t_redircloexec.sh,v 1.5 2017/05/27 13:11:50 kre Exp $ 2239c3355Schristos# 3239c3355Schristos# Copyright (c) 2016 The NetBSD Foundation, Inc. 4239c3355Schristos# All rights reserved. 5239c3355Schristos# 6239c3355Schristos# This code is derived from software contributed to The NetBSD Foundation 7239c3355Schristos# by Christos Zoulas. 8239c3355Schristos# 9239c3355Schristos# Redistribution and use in source and binary forms, with or without 10239c3355Schristos# modification, are permitted provided that the following conditions 11239c3355Schristos# are met: 12239c3355Schristos# 1. Redistributions of source code must retain the above copyright 13239c3355Schristos# notice, this list of conditions and the following disclaimer. 14239c3355Schristos# 2. Redistributions in binary form must reproduce the above copyright 15239c3355Schristos# notice, this list of conditions and the following disclaimer in the 16239c3355Schristos# documentation and/or other materials provided with the distribution. 17239c3355Schristos# 18239c3355Schristos# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19239c3355Schristos# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20239c3355Schristos# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21239c3355Schristos# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22239c3355Schristos# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23239c3355Schristos# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24239c3355Schristos# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25239c3355Schristos# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26239c3355Schristos# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27239c3355Schristos# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28239c3355Schristos# POSSIBILITY OF SUCH DAMAGE. 29239c3355Schristos# 30239c3355Schristos# the implementation of "sh" to test 31239c3355Schristos: ${TEST_SH:="/bin/sh"} 32239c3355Schristos 33239c3355Schristosmkhelper() { 34e04f666aSchristos name=$1 35e04f666aSchristos fd=$2 36239c3355Schristos shift 2 37e04f666aSchristos 38e04f666aSchristos echo "$@" > ./"${name}1" 39e04f666aSchristos echo "echo ${name}2" ">&${fd}" > ./"${name}2" 40239c3355Schristos} 41239c3355Schristos 42239c3355Schristoscleanhelper() { 43e04f666aSchristos # not really needed, atf cleans up... 44e04f666aSchristos rm -f ./"${1}1" ./"${1}2" out 45239c3355Schristos} 46239c3355Schristos 47239c3355Schristosatf_test_case exec_redir_closed 48239c3355Schristosexec_redir_closed_head() { 49239c3355Schristos atf_set "descr" "Tests that redirections created by exec are closed on exec" 50239c3355Schristos} 51239c3355Schristosexec_redir_closed_body() { 52e04f666aSchristos 53*ff906b15Skre [ -n "${POSIXLY_CORRECT+set}" ] && atf_skip "tests non-posix behaviour" 54*ff906b15Skre 55e04f666aSchristos mkhelper exec 6 \ 56e04f666aSchristos "exec 6> out; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-" 57e04f666aSchristos 58e04f666aSchristos atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} ./exec1 59e04f666aSchristos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -e ./exec1 60e04f666aSchristos 61e04f666aSchristos mkhelper exec 9 \ 62e04f666aSchristos "exec 9> out; echo exec1 >&9; ${TEST_SH} exec2" 63e04f666aSchristos 64e04f666aSchristos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} ./exec1 65e04f666aSchristos 66e04f666aSchristos mkhelper exec 8 \ 67e04f666aSchristos "exec 8> out; printf OK; echo exec1 >&8;" \ 68e04f666aSchristos "printf OK; ${TEST_SH} exec2; printf ERR" 69e04f666aSchristos 70e04f666aSchristos atf_check -s not-exit:0 -o match:OKOK -o not-match:ERR -e not-empty \ 71e04f666aSchristos ${TEST_SH} -e ./exec1 72e04f666aSchristos 73e04f666aSchristos mkhelper exec 7 \ 74e04f666aSchristos "exec 7> out; printf OK; echo exec1 >&7;" \ 75e04f666aSchristos "printf OK; ${TEST_SH} exec2 || printf ERR" 76e04f666aSchristos 77e04f666aSchristos atf_check -s exit:0 -o match:OKOKERR -e not-empty \ 78e04f666aSchristos ${TEST_SH} ./exec1 79e04f666aSchristos 80239c3355Schristos cleanhelper exec 81239c3355Schristos} 82239c3355Schristos 83b752c813Skreatf_test_case exec_redir_open 84b752c813Skreexec_redir_open_head() { 85b752c813Skre atf_set "descr" "Tests that redirections created by exec can remain open" 86b752c813Skre} 87b752c813Skreexec_redir_open_body() { 88b752c813Skre 89b752c813Skre mkhelper exec 6 \ 90b752c813Skre "exec 6> out 6>&6; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-" 91b752c813Skre 92b752c813Skre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 93b752c813Skre atf_check -s exit:0 -o empty -e empty ${TEST_SH} -e ./exec1 94b752c813Skre 95b752c813Skre mkhelper exec 9 \ 96b752c813Skre "exec 9> out ; echo exec1 >&9; ${TEST_SH} exec2 9>&9" 97b752c813Skre 98b752c813Skre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 99b752c813Skre 100b752c813Skre mkhelper exec 8 \ 101b752c813Skre "exec 8> out; printf OK; exec 8>&8; echo exec1 >&8;" \ 102b752c813Skre "printf OK; ${TEST_SH} exec2; printf OK" 103b752c813Skre 104b752c813Skre atf_check -s exit:0 -o match:OKOKOK -e empty \ 105b752c813Skre ${TEST_SH} -e ./exec1 106b752c813Skre 107b752c813Skre mkhelper exec 7 \ 108b752c813Skre "exec 7> out; printf OK; echo exec1 >&7;" \ 109b752c813Skre "printf OK; ${TEST_SH} 7>&7 exec2; printf OK" 110b752c813Skre 111b752c813Skre atf_check -s exit:0 -o match:OKOKOK -e empty \ 112b752c813Skre ${TEST_SH} -e ./exec1 113b752c813Skre 114b752c813Skre cleanhelper exec 115b752c813Skre} 116b752c813Skre 117239c3355Schristosatf_test_case loop_redir_open 118239c3355Schristosloop_redir_open_head() { 119239c3355Schristos atf_set "descr" "Tests that redirections in loops don't close on exec" 120239c3355Schristos} 121239c3355Schristosloop_redir_open_body() { 122e04f666aSchristos mkhelper for 3 "for x in x; do ${TEST_SH} ./for2; done 3>out" 123239c3355Schristos atf_check -s exit:0 \ 124239c3355Schristos -o empty \ 125239c3355Schristos -e empty \ 126e04f666aSchristos ${TEST_SH} ./for1 127239c3355Schristos cleanhelper for 128239c3355Schristos} 129239c3355Schristos 130239c3355Schristosatf_test_case compound_redir_open 131239c3355Schristoscompound_redir_open_head() { 132239c3355Schristos atf_set "descr" "Tests that redirections in compound statements don't close on exec" 133239c3355Schristos} 134239c3355Schristoscompound_redir_open_body() { 135e04f666aSchristos mkhelper comp 3 "{ ${TEST_SH} ./comp2; } 3>out" 136239c3355Schristos atf_check -s exit:0 \ 137239c3355Schristos -o empty \ 138239c3355Schristos -e empty \ 139e04f666aSchristos ${TEST_SH} ./comp1 140239c3355Schristos cleanhelper comp 141239c3355Schristos} 142239c3355Schristos 143239c3355Schristosatf_test_case simple_redir_open 144239c3355Schristossimple_redir_open_head() { 145239c3355Schristos atf_set "descr" "Tests that redirections in simple commands don't close on exec" 146239c3355Schristos} 147239c3355Schristossimple_redir_open_body() { 148e04f666aSchristos mkhelper simp 4 "${TEST_SH} ./simp2 4>out" 149239c3355Schristos atf_check -s exit:0 \ 150239c3355Schristos -o empty \ 151239c3355Schristos -e empty \ 152e04f666aSchristos ${TEST_SH} ./simp1 153239c3355Schristos cleanhelper simp 154239c3355Schristos} 155239c3355Schristos 156e04f666aSchristosatf_test_case subshell_redir_open 157e04f666aSchristossubshell_redir_open_head() { 158e04f666aSchristos atf_set "descr" "Tests that redirections on subshells don't close on exec" 159e04f666aSchristos} 160e04f666aSchristossubshell_redir_open_body() { 161e04f666aSchristos mkhelper comp 5 "( ${TEST_SH} ./comp2; ${TEST_SH} ./comp2 ) 5>out" 162e04f666aSchristos atf_check -s exit:0 \ 163e04f666aSchristos -o empty \ 164e04f666aSchristos -e empty \ 165e04f666aSchristos ${TEST_SH} ./comp1 166e04f666aSchristos cleanhelper comp 167e04f666aSchristos} 168e04f666aSchristos 169c70ddc9bSkreatf_test_case posix_exec_redir 170c70ddc9bSkreposix_exec_redir_head() { 171c70ddc9bSkre atf_set "descr" "Tests that redirections created by exec" \ 172c70ddc9bSkre " in posix mode are not closed on exec" 173c70ddc9bSkre} 174c70ddc9bSkreposix_exec_redir_body() { 175c70ddc9bSkre 176c70ddc9bSkre # This test mostly just expects the opposite results than 177c70ddc9bSkre # exec_redir_closed ... 178c70ddc9bSkre 179c70ddc9bSkre # First work out how to get shell into posix mode 180c70ddc9bSkre POSIX= 181c70ddc9bSkre 182c70ddc9bSkre # This should succeed only if "set -o posix" succeeds. 183c70ddc9bSkre # If it fails, whether it fails and exits the shell, or 184c70ddc9bSkre # just returns a "false" from set (exit != 0), with or 185c70ddc9bSkre # without errs on stderr, should not matter 186c70ddc9bSkre 187c70ddc9bSkre if ${TEST_SH} -c "set -o posix && exit 0 || exit 1" 2>/dev/null 188c70ddc9bSkre then 189c70ddc9bSkre # If we have this method, use it, as we can expect 190c70ddc9bSkre # this really should mean the shell is in posix mode. 191c70ddc9bSkre 192c70ddc9bSkre POSIX='set -o posix;' 193c70ddc9bSkre 194c70ddc9bSkre else 195c70ddc9bSkre # This one is just a guess, and there is no assurance 196c70ddc9bSkre # that it will do anything at all. What's more, since 197c70ddc9bSkre # we do not know what the shell being tested does 198c70ddc9bSkre # differently in posix and non-posix modes, if it 199c70ddc9bSkre # even has that concept, there's nothing we can test 200c70ddc9bSkre # to find out. 201c70ddc9bSkre 202c70ddc9bSkre # A shell that always operates in posix mode (at least 203c70ddc9bSkre # with regard to redirects on exec and close-on-exec 204c70ddc9bSkre # should pass this test, in any case. 205c70ddc9bSkre 206c70ddc9bSkre POSIXLY_CORRECT=true ; export POSIXLY_CORRECT 207c70ddc9bSkre 208c70ddc9bSkre fi 209c70ddc9bSkre 210c70ddc9bSkre mkhelper exec 6 \ 211c70ddc9bSkre "${POSIX} exec 6> out; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-" 212c70ddc9bSkre 213c70ddc9bSkre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 214c70ddc9bSkre atf_check -s exit:0 -o empty -e empty ${TEST_SH} -e ./exec1 215c70ddc9bSkre 216c70ddc9bSkre mkhelper exec 9 \ 217c70ddc9bSkre "${POSIX} exec 9> out; echo exec1 >&9; ${TEST_SH} exec2" 218c70ddc9bSkre 219c70ddc9bSkre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 220c70ddc9bSkre 221c70ddc9bSkre mkhelper exec 8 \ 222c70ddc9bSkre "${POSIX}" \ 223c70ddc9bSkre "exec 8> out; printf OK; echo exec1 >&8;" \ 224c70ddc9bSkre "printf OK; ${TEST_SH} exec2; printf GOOD" 225c70ddc9bSkre 226c70ddc9bSkre atf_check -s exit:0 -o match:OKOKGOOD -e empty \ 227c70ddc9bSkre ${TEST_SH} -e ./exec1 228c70ddc9bSkre 229c70ddc9bSkre mkhelper exec 7 \ 230c70ddc9bSkre "${POSIX}" \ 231c70ddc9bSkre "exec 7> out; printf OK; echo exec1 >&7;" \ 232c70ddc9bSkre "printf OK; ${TEST_SH} exec2 || printf ERR" 233c70ddc9bSkre 234c70ddc9bSkre atf_check -s exit:0 -o match:OKOK -o not-match:ERR -e empty \ 235c70ddc9bSkre ${TEST_SH} ./exec1 236c70ddc9bSkre 237c70ddc9bSkre cleanhelper exec 238c70ddc9bSkre} 239c70ddc9bSkre 240239c3355Schristosatf_init_test_cases() { 241239c3355Schristos atf_add_test_case exec_redir_closed 242b752c813Skre atf_add_test_case exec_redir_open 243239c3355Schristos atf_add_test_case loop_redir_open 244239c3355Schristos atf_add_test_case compound_redir_open 245239c3355Schristos atf_add_test_case simple_redir_open 246e04f666aSchristos atf_add_test_case subshell_redir_open 247c70ddc9bSkre atf_add_test_case posix_exec_redir 248239c3355Schristos} 249