1 | ## compare_shells: dash bash mksh ash
|
2 | ## oils_failures_allowed: 1
|
3 |
|
4 | # builtin-trap.test.sh
|
5 |
|
6 | #### trap accepts/ignores --
|
7 | trap -- 'echo hi' EXIT
|
8 | echo ok
|
9 | ## STDOUT:
|
10 | ok
|
11 | hi
|
12 | ## END
|
13 |
|
14 | #### Register invalid trap
|
15 | trap 'foo' SIGINVALID
|
16 | ## status: 1
|
17 |
|
18 | #### Remove invalid trap
|
19 | trap - SIGINVALID
|
20 | ## status: 1
|
21 |
|
22 | #### SIGINT and INT are aliases
|
23 | trap - SIGINT
|
24 | echo $?
|
25 | trap - INT
|
26 | echo $?
|
27 | ## STDOUT:
|
28 | 0
|
29 | 0
|
30 | ## END
|
31 | ## N-I dash STDOUT:
|
32 | 1
|
33 | 0
|
34 | ## END
|
35 |
|
36 | #### trap without args prints traps, like trap -p
|
37 | case $SH in dash) exit ;; esac
|
38 |
|
39 | if false; then
|
40 | # bash breaks the display across lines
|
41 | trap "true
|
42 | false" EXIT
|
43 | fi
|
44 |
|
45 | $SH -c '
|
46 |
|
47 | trap "true" EXIT
|
48 |
|
49 | echo status=$?
|
50 | trap | grep EXIT
|
51 | echo status=$?
|
52 | '
|
53 |
|
54 | ## STDOUT:
|
55 | status=0
|
56 | trap -- 'true' EXIT
|
57 | status=0
|
58 | ## END
|
59 |
|
60 | ## BUG mksh/ash STDOUT:
|
61 | status=0
|
62 | status=1
|
63 | ## END
|
64 |
|
65 | ## N-I dash STDOUT:
|
66 | ## END
|
67 |
|
68 |
|
69 | #### trap 'echo hi' KILL (regression test, caught by smoosh suite)
|
70 | trap 'echo hi' 9
|
71 | echo status=$?
|
72 |
|
73 | trap 'echo hi' KILL
|
74 | echo status=$?
|
75 |
|
76 | trap 'echo hi' STOP
|
77 | echo status=$?
|
78 |
|
79 | trap 'echo hi' TERM
|
80 | echo status=$?
|
81 |
|
82 | ## STDOUT:
|
83 | status=0
|
84 | status=0
|
85 | status=0
|
86 | status=0
|
87 | ## END
|
88 | ## OK osh STDOUT:
|
89 | status=1
|
90 | status=1
|
91 | status=1
|
92 | status=0
|
93 | ## END
|
94 |
|
95 | #### Invalid trap invocation
|
96 | trap 'foo'
|
97 | echo status=$?
|
98 | ## STDOUT:
|
99 | status=2
|
100 | ## END
|
101 | ## OK dash/ash STDOUT:
|
102 | status=1
|
103 | ## END
|
104 | ## BUG mksh STDOUT:
|
105 | status=0
|
106 | ## END
|
107 |
|
108 | #### exit 1 when trap code string is invalid
|
109 | # All shells spew warnings to stderr, but don't actually exit! Bad!
|
110 | trap 'echo <' EXIT
|
111 | echo status=$?
|
112 | ## STDOUT:
|
113 | status=1
|
114 | ## END
|
115 |
|
116 | ## BUG mksh status: 1
|
117 | ## BUG mksh STDOUT:
|
118 | status=0
|
119 | ## END
|
120 |
|
121 | ## BUG ash status: 2
|
122 | ## BUG ash STDOUT:
|
123 | status=0
|
124 | ## END
|
125 |
|
126 | ## BUG dash/bash status: 0
|
127 | ## BUG dash/bash STDOUT:
|
128 | status=0
|
129 | ## END
|
130 |
|
131 |
|
132 | #### trap EXIT calling exit
|
133 | cleanup() {
|
134 | echo "cleanup [$@]"
|
135 | exit 42
|
136 | }
|
137 | trap 'cleanup x y z' EXIT
|
138 | ## stdout: cleanup [x y z]
|
139 | ## status: 42
|
140 |
|
141 | #### trap EXIT return status ignored
|
142 | cleanup() {
|
143 | echo "cleanup [$@]"
|
144 | return 42
|
145 | }
|
146 | trap 'cleanup x y z' EXIT
|
147 | ## stdout: cleanup [x y z]
|
148 | ## status: 0
|
149 |
|
150 | #### trap EXIT with PARSE error
|
151 | trap 'echo FAILED' EXIT
|
152 | for
|
153 | ## stdout: FAILED
|
154 | ## status: 2
|
155 | ## OK mksh status: 1
|
156 |
|
157 | #### trap EXIT with PARSE error and explicit exit
|
158 | trap 'echo FAILED; exit 0' EXIT
|
159 | for
|
160 | ## stdout: FAILED
|
161 | ## status: 0
|
162 |
|
163 | #### trap EXIT with explicit exit
|
164 | trap 'echo IN TRAP; echo $stdout' EXIT
|
165 | stdout=FOO
|
166 | exit 42
|
167 |
|
168 | ## status: 42
|
169 | ## STDOUT:
|
170 | IN TRAP
|
171 | FOO
|
172 | ## END
|
173 |
|
174 | #### trap EXIT with command sub / subshell / pipeline
|
175 | trap 'echo EXIT TRAP' EXIT
|
176 |
|
177 | echo $(echo command sub)
|
178 |
|
179 | ( echo subshell )
|
180 |
|
181 | echo pipeline | cat
|
182 |
|
183 | ## STDOUT:
|
184 | command sub
|
185 | subshell
|
186 | pipeline
|
187 | EXIT TRAP
|
188 | ## END
|
189 |
|
190 | #### trap 0 is equivalent to EXIT
|
191 | # not sure why this is, but POSIX wants it.
|
192 | trap 'echo EXIT' 0
|
193 | echo status=$?
|
194 | trap - EXIT
|
195 | echo status=$?
|
196 | ## status: 0
|
197 | ## STDOUT:
|
198 | status=0
|
199 | status=0
|
200 | ## END
|
201 |
|
202 | #### trap 1 is equivalent to SIGHUP; HUP is equivalent to SIGHUP
|
203 | trap 'echo HUP' SIGHUP
|
204 | echo status=$?
|
205 | trap 'echo HUP' HUP
|
206 | echo status=$?
|
207 | trap 'echo HUP' 1
|
208 | echo status=$?
|
209 | trap - HUP
|
210 | echo status=$?
|
211 | ## status: 0
|
212 | ## STDOUT:
|
213 | status=0
|
214 | status=0
|
215 | status=0
|
216 | status=0
|
217 | ## END
|
218 | ## N-I dash STDOUT:
|
219 | status=1
|
220 | status=0
|
221 | status=0
|
222 | status=0
|
223 | ## END
|
224 |
|
225 | #### eval in the exit trap (regression for issue #293)
|
226 | trap 'eval "echo hi"' 0
|
227 | ## STDOUT:
|
228 | hi
|
229 | ## END
|
230 |
|
231 |
|
232 | #### exit codes for traps are isolated
|
233 |
|
234 | trap 'echo USR1 trap status=$?; ( exit 42 )' USR1
|
235 |
|
236 | echo before=$?
|
237 |
|
238 | # Equivalent to 'kill -USR1 $$' except OSH doesn't have "kill" yet.
|
239 | # /bin/kill doesn't exist on Debian unless 'procps' is installed.
|
240 | sh -c "kill -USR1 $$"
|
241 | echo after=$?
|
242 |
|
243 | ## STDOUT:
|
244 | before=0
|
245 | USR1 trap status=0
|
246 | after=0
|
247 | ## END
|
248 |
|
249 | #### traps are cleared in subshell (started with &)
|
250 |
|
251 | # Test with SIGURG because the default handler is SIG_IGN
|
252 | #
|
253 | # If we use SIGUSR1, I think the shell reverts to killing the process
|
254 |
|
255 | # https://man7.org/linux/man-pages/man7/signal.7.html
|
256 |
|
257 | trap 'echo SIGURG' URG
|
258 |
|
259 | kill -URG $$
|
260 |
|
261 | # Hm trap doesn't happen here
|
262 | { echo begin child; sleep 0.1; echo end child; } &
|
263 | kill -URG $!
|
264 | wait
|
265 | echo "wait status $?"
|
266 |
|
267 | # In the CI, mksh sometimes gives:
|
268 | #
|
269 | # USR1
|
270 | # begin child
|
271 | # done
|
272 | #
|
273 | # leaving off 'end child'. This seems like a BUG to me?
|
274 |
|
275 | ## STDOUT:
|
276 | SIGURG
|
277 | begin child
|
278 | end child
|
279 | wait status 0
|
280 | ## END
|
281 |
|
282 | #### trap USR1, sleep, SIGINT: non-interactively
|
283 |
|
284 | $REPO_ROOT/spec/testdata/builtin-trap-usr1.sh
|
285 |
|
286 | ## STDOUT:
|
287 | usr1
|
288 | status=0
|
289 | ## END
|
290 |
|
291 | #### trap INT, sleep, SIGINT: non-interactively
|
292 |
|
293 | # mksh behaves differently in CI -- maybe when it's not connected to a
|
294 | # terminal?
|
295 | case $SH in mksh) echo mksh; exit ;; esac
|
296 |
|
297 | $REPO_ROOT/spec/testdata/builtin-trap-int.sh
|
298 |
|
299 | ## STDOUT:
|
300 | status=0
|
301 | ## END
|
302 |
|
303 | ## OK mksh STDOUT:
|
304 | mksh
|
305 | ## END
|
306 |
|
307 | # Not sure why other shells differ here, but running the trap is consistent
|
308 | # with interactive cases in test/bugs.sh
|
309 |
|
310 | ## OK osh STDOUT:
|
311 | int
|
312 | status=0
|
313 | ## END
|
314 |
|
315 | #### trap EXIT, sleep, SIGINT: non-interactively
|
316 |
|
317 | $REPO_ROOT/spec/testdata/builtin-trap-exit.sh
|
318 |
|
319 | ## STDOUT:
|
320 | on exit
|
321 | status=0
|
322 | ## END
|
323 |
|
324 | #### Remove trap with an unsigned integer
|
325 |
|
326 | $SH -e -c '
|
327 | trap "echo noprint" EXIT
|
328 | trap 0 EXIT
|
329 | echo ok0
|
330 | '
|
331 | echo
|
332 |
|
333 | $SH -e -c '
|
334 | trap "echo noprint" EXIT
|
335 | trap " 42 " EXIT
|
336 | echo ok42space
|
337 | '
|
338 | echo
|
339 |
|
340 | # corner case: sometimes 07 is treated as octal, but not here
|
341 | $SH -e -c '
|
342 | trap "echo noprint" EXIT
|
343 | trap 07 EXIT
|
344 | echo ok07
|
345 | '
|
346 | echo
|
347 |
|
348 | $SH -e -c '
|
349 | trap "echo trap-exit" EXIT
|
350 | trap -1 EXIT
|
351 | echo bad
|
352 | '
|
353 | if test $? -ne 0; then
|
354 | echo failure
|
355 | fi
|
356 |
|
357 | ## STDOUT:
|
358 | ok0
|
359 |
|
360 | ok42space
|
361 |
|
362 | ok07
|
363 |
|
364 | trap-exit
|
365 | failure
|
366 | ## END
|