etc/protocols - sync with NetBSD-8
[minix.git] / tests / bin / sh / t_set_e.sh
blob8dfe6e411746215dcf6b047922cae8b0c52e41b7
1 # $NetBSD: t_set_e.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
3 # Copyright (c) 2007 The NetBSD Foundation, Inc.
4 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
15 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 # POSSIBILITY OF SUCH DAMAGE.
28 # references:
29 # http://www.opengroup.org/onlinepubs/009695399/utilities/set.html
30 # http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
32 # the implementation of "sh" to test
33 : ${TEST_SH:="sh"}
35 failwith()
37 case "$SH_FAILS" in
38 "") SH_FAILS=`echo "$1"`;;
39 *) SH_FAILS="$SH_FAILS"`echo; echo "$1"`;;
40 esac
43 check1()
45 #echo "$TEST_SH -c $1"
46 result=`$TEST_SH -c "$1" 2>/dev/null | tr '\n' ' ' | sed 's/ *$//'`
47 if [ "$result" != "$2" ]; then
48 MSG=`printf "%-56s %-8s %s" "$3" "$result" "$2"`
49 failwith "$MSG"
50 failcount=`expr $failcount + 1`
52 count=`expr $count + 1`
55 # direct check: try the given expression.
56 dcheck()
58 check1 "$1" "$2" "$1"
61 # eval check: indirect through eval.
62 # as of this writing, this changes the behavior pretty drastically and
63 # is thus important to test. (PR bin/29861)
64 echeck()
66 check1 'eval '"'($1)'" "$2" "eval '($1)'"
69 atf_test_case all
70 all_head() {
71 atf_set "descr" "Tests that 'set -e' works correctly"
73 all_body() {
74 count=0
75 failcount=0
77 # make sure exiting from a subshell behaves as expected
78 dcheck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1'
79 echeck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1'
81 # first, check basic functioning.
82 # The ERR shouldn't print; the result of the () should be 1.
83 # Henceforth we'll assume that we don't need to check $?.
84 dcheck '(set -e; false; echo ERR$?); echo -n OK$?' 'OK1'
85 echeck '(set -e; false; echo ERR$?); echo -n OK$?' 'OK1'
87 # these cases should be equivalent to the preceding.
88 dcheck '(set -e; /nonexistent; echo ERR); echo OK' 'OK'
89 echeck '(set -e; /nonexistent; echo ERR); echo OK' 'OK'
90 dcheck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK'
91 echeck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK'
92 dcheck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK'
93 echeck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK'
94 dcheck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK'
95 echeck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK'
97 # but! with set -e, the false should cause an *immediate* exit.
98 # The return form should not, as such, but there's no way to
99 # distinguish it.
100 dcheck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK'
101 echeck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK'
103 # set is not scoped, so these should not exit at all.
104 dcheck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK'
105 echeck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK'
107 # according to the standard, only failing *simple* commands
108 # cause an exit under -e. () is not a simple command.
109 # Correct (per POSIX):
110 #dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK'
111 #echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK'
112 # Wrong current behavior:
113 dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK'
114 echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK'
116 # make sure an inner nested shell does exit though.
117 dcheck '(set -e; (false; echo ERR)); echo OK' 'OK'
119 # The left hand side of an || or && is explicitly tested and
120 # thus should not cause an exit. Furthermore, because a || or
121 # && expression is not a simple command, there should be no
122 # exit even if the overall result is false.
123 dcheck '(set -e; false || true; echo OK); echo OK' 'OK OK'
124 echeck '(set -e; false || true; echo OK); echo OK' 'OK OK'
125 dcheck '(set -e; false && true; echo OK); echo OK' 'OK OK'
126 echeck '(set -e; false && true; echo OK); echo OK' 'OK OK'
128 # However, the right hand side is not tested, so a failure
129 # there *should* cause an exit, regardless of whether it
130 # appears inside a non-simple command.
132 # Note that in at least one place the standard does not
133 # distinguish between the left and right hand sides of
134 # logical operators. It is possible that for strict
135 # compliance these need to not exit; however, if so that
136 # should probably be limited to when some strict-posix setting
137 # is in effect and tested accordingly.
139 dcheck '(set -e; false || false; echo ERR); echo OK' 'OK'
140 dcheck '(set -e; true && false; echo ERR); echo OK' 'OK'
141 echeck '(set -e; false || false; echo ERR); echo OK' 'OK'
142 echeck '(set -e; true && false; echo ERR); echo OK' 'OK'
144 # correct:
145 #dcheck '(set -e; false && false; echo ERR); echo OK' 'OK'
146 #echeck '(set -e; false && false; echo ERR); echo OK' 'OK'
148 # wrong current behavior:
149 dcheck '(set -e; false && false; echo ERR); echo OK' 'ERR OK'
150 echeck '(set -e; false && false; echo ERR); echo OK' 'ERR OK'
152 # A failure that is not reached because of short-circuit
153 # evaluation should not cause an exit, however.
154 dcheck '(set -e; true || false; echo OK); echo OK' 'OK OK'
155 echeck '(set -e; true || false; echo OK); echo OK' 'OK OK'
157 # For completeness, test the other two combinations.
158 dcheck '(set -e; true || true; echo OK); echo OK' 'OK OK'
159 dcheck '(set -e; true && true; echo OK); echo OK' 'OK OK'
160 echeck '(set -e; true || true; echo OK); echo OK' 'OK OK'
161 echeck '(set -e; true && true; echo OK); echo OK' 'OK OK'
163 # likewise, none of these should exit.
164 dcheck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK'
165 dcheck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK'
166 # problematic :-)
167 #dcheck '(set -e; until false; do :; done; echo OK); echo OK' 'OK OK'
168 dcheck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \
169 'OK OK'
170 echeck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK'
171 echeck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK'
172 echeck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \
173 'OK OK'
175 # the bang operator tests its argument and thus the argument
176 # should not cause an exit. it is also not a simple command (I
177 # believe) so it also shouldn't exit even if it yields a false
178 # result.
179 dcheck '(set -e; ! false; echo OK); echo OK' 'OK OK'
180 dcheck '(set -e; ! true; echo OK); echo OK' 'OK OK'
181 echeck '(set -e; ! false; echo OK); echo OK' 'OK OK'
182 echeck '(set -e; ! true; echo OK); echo OK' 'OK OK'
184 # combined case with () and &&; the inner expression is false
185 # but does not itself exit, and the () should not cause an
186 # exit even when failing.
187 # correct:
188 #dcheck '(set -e; (false && true); echo OK); echo OK' 'OK OK'
189 #echeck '(set -e; (false && true); echo OK); echo OK' 'OK OK'
190 # wrong current behavior:
191 dcheck '(set -e; (false && true); echo OK); echo OK' 'OK'
192 echeck '(set -e; (false && true); echo OK); echo OK' 'OK'
194 # pipelines. only the right-hand end is significant.
195 dcheck '(set -e; false | true; echo OK); echo OK' 'OK OK'
196 echeck '(set -e; false | true; echo OK); echo OK' 'OK OK'
197 dcheck '(set -e; true | false; echo ERR); echo OK' 'OK'
198 echeck '(set -e; true | false; echo ERR); echo OK' 'OK'
200 dcheck '(set -e; while true | false; do :; done; echo OK); echo OK' \
201 'OK OK'
202 dcheck '(set -e; if true | false; then :; fi; echo OK); echo OK' \
203 'OK OK'
206 # According to dsl@ in PR bin/32282, () is not defined as a
207 # subshell, only as a grouping operator [and a scope, I guess]
208 # so the nested false ought to cause the whole shell to exit,
209 # not just the subshell. dholland@ would like to see C&V,
210 # because that seems like a bad idea. (Among other things, it
211 # would break all the above test logic, which relies on being
212 # able to isolate set -e behavior inside ().) However, I'm
213 # going to put these tests here to make sure the issue gets
214 # dealt with sometime.
216 # XXX: the second set has been disabled in the name of making
217 # all tests "pass".
219 # 1. error if the whole shell exits (current behavior)
220 dcheck 'echo OK; (set -e; false); echo OK' 'OK OK'
221 echeck 'echo OK; (set -e; false); echo OK' 'OK OK'
222 # 2. error if the whole shell does not exit (dsl's suggested behavior)
223 #dcheck 'echo OK; (set -e; false); echo ERR' 'OK'
224 #echeck 'echo OK; (set -e; false); echo ERR' 'OK'
226 # The current behavior of the shell is that it exits out as
227 # far as -e is set and then stops. This is probably a
228 # consequence of it handling () wrong, but it's a somewhat
229 # curious compromise position between 1. and 2. above.
230 dcheck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK'
231 echeck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK'
233 # backquote expansion (PR bin/17514)
235 # correct
236 #dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK'
237 #dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK'
238 #dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK'
239 #dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK'
240 # wrong current behavior
241 dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK'
242 dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK'
243 dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK'
244 dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK'
246 dcheck '(set -e; x=`false`; echo ERR); echo OK' 'OK'
247 dcheck '(set -e; x=$(false); echo ERR); echo OK' 'OK'
248 dcheck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK'
249 dcheck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK'
251 # correct
252 #echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK'
253 #echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK'
254 #echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK'
255 #echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK'
257 # wrong current behavior
258 echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK'
259 echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK'
260 echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK'
261 echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK'
263 echeck '(set -e; x=`false`; echo ERR); echo OK' 'OK'
264 echeck '(set -e; x=$(false); echo ERR); echo OK' 'OK'
265 echeck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK'
266 echeck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK'
268 # shift (PR bin/37493)
269 # correct
270 #dcheck '(set -e; shift || true; echo OK); echo OK' 'OK OK'
271 #echeck '(set -e; shift || true; echo OK); echo OK' 'OK OK'
272 # wrong current behavior
273 dcheck '(set -e; shift || true; echo OK); echo OK' 'OK'
274 echeck '(set -e; shift || true; echo OK); echo OK' 'OK'
276 # Done.
278 if [ "x$SH_FAILS" != x ]; then
279 printf '%-56s %-8s %s\n' "Expression" "Result" "Should be"
280 echo "$SH_FAILS"
281 atf_fail "$failcount of $count failed cases"
282 else
283 atf_pass
287 atf_init_test_cases() {
288 atf_add_test_case all