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