OILS / spec / builtin-trap.test.sh View on Github | oils.pub

609 lines, 297 significant
1## compare_shells: dash bash mksh ash
2## oils_failures_allowed: 2
3
4#### traps are not active inside subshells $() () trap | cat
5
6# TODO: should we change this? We're not compatible with bash or busybox ash
7
8trap 'echo bye' EXIT
9
10# NOT a subshell
11trap > traps.txt
12wc -l traps.txt
13
14echo '( )'
15( trap )
16
17echo '$(trap)'
18echo $(trap)
19
20echo 'trap | cat'
21trap | cat
22
23## STDOUT:
241 traps.txt
25( )
26$(trap)
27
28trap | cat
29bye
30## END
31## BUG bash STDOUT:
321 traps.txt
33( )
34trap -- 'echo bye' EXIT
35$(trap)
36trap -- 'echo bye' EXIT
37trap | cat
38trap -- 'echo bye' EXIT
39bye
40## END
41## BUG-2 ash STDOUT:
421 traps.txt
43( )
44$(trap)
45trap -- 'echo bye' EXIT
46trap | cat
47bye
48## END
49
50
51#### trap accepts/ignores --
52trap -- 'echo hi' EXIT
53echo ok
54## STDOUT:
55ok
56hi
57## END
58
59#### Register invalid trap, remove invalid trap
60trap 'foo' SIGINVALID
61if test $? -ne 0; then
62 echo ok
63fi
64
65trap - SIGINVALID
66if test $? -ne 0; then
67 echo ok
68fi
69
70## STDOUT:
71ok
72ok
73## END
74
75#### trap foo gives non-zero error
76trap 'foo'
77if test $? -ne 0; then
78 echo ok
79fi
80## STDOUT:
81ok
82## END
83## BUG mksh STDOUT:
84## END
85
86#### SIGINT and INT are aliases
87trap - SIGINT
88echo $?
89trap - INT
90echo $?
91## STDOUT:
920
930
94## END
95## N-I dash STDOUT:
961
970
98## END
99
100#### trap without args prints traps
101trap 'echo exit' EXIT
102echo status=$?
103
104trap
105echo status=$?
106
107## STDOUT:
108status=0
109trap -- 'echo exit' EXIT
110status=0
111exit
112## END
113
114#### print trap handler with multiple lines
115trap 'echo 1
116echo 2
117echo 3' INT
118
119trap
120## STDOUT:
121trap -- 'echo 1
122echo 2
123echo 3' SIGINT
124## END
125## OK dash/ash STDOUT:
126trap -- 'echo 1
127echo 2
128echo 3' INT
129## END
130## OK mksh STDOUT:
131trap -- $'echo 1\necho 2\necho 3' INT
132## END
133
134#### trap -p is like trap: it prints the handlers and full signal names
135case $SH in dash) exit ;; esac
136trap "echo INT" INT
137trap "echo EXIT" EXIT
138trap -p
139## STDOUT:
140trap -- 'echo EXIT' EXIT
141trap -- 'echo INT' SIGINT
142EXIT
143## END
144## N-I mksh status: 1
145## N-I ash status: 2
146## N-I mksh/ash STDOUT:
147EXIT
148## END
149## N-I dash STDOUT:
150## END
151
152#### Register the same handler for multiple signals
153trap 'echo test' TERM 2 EXIT
154trap
155## STDOUT:
156trap -- 'echo test' EXIT
157trap -- 'echo test' SIGINT
158trap -- 'echo test' SIGTERM
159test
160## END
161## OK dash/mksh/ash STDOUT:
162trap -- 'echo test' EXIT
163trap -- 'echo test' INT
164trap -- 'echo test' TERM
165test
166## END
167
168#### Remove multiple handlers with trap -
169trap "echo int" INT
170trap "echo e" EXIT
171trap - int 0 3
172trap
173
174echo ---
175trap "echo int" INT
176trap "echo e" EXIT
177trap - int 0 -99
178if test $? -ne 0; then
179 echo ok
180fi
181## STDOUT:
182---
183ok
184## END
185
186#### trap EXIT clears the EXIT trap
187trap "echo INT" INT
188trap "echo EXIT" EXIT
189trap
190echo ---
191trap EXIT
192trap
193echo ---
194trap INT
195trap
196## STDOUT:
197trap -- 'echo EXIT' EXIT
198trap -- 'echo INT' SIGINT
199---
200trap -- 'echo INT' SIGINT
201---
202## END
203## OK dash/ash STDOUT:
204trap -- 'echo EXIT' EXIT
205trap -- 'echo INT' INT
206---
207trap -- 'echo INT' INT
208---
209## END
210## BUG mksh STDOUT:
211trap -- 'echo EXIT' EXIT
212trap -- 'echo INT' INT
213---
214trap -- 'echo EXIT' EXIT
215trap -- 'echo INT' INT
216---
217trap -- 'echo EXIT' EXIT
218trap -- 'echo INT' INT
219EXIT
220## END
221
222#### trap 0 is equivalent to trap EXIT
223trap "echo INT" INT
224trap "echo EXIT" 0 # EXIT
225trap
226echo ---
227trap 0
228trap
229## STDOUT:
230trap -- 'echo EXIT' EXIT
231trap -- 'echo INT' SIGINT
232---
233trap -- 'echo INT' SIGINT
234## END
235## OK dash/ash/mksh STDOUT:
236trap -- 'echo EXIT' EXIT
237trap -- 'echo INT' INT
238---
239trap -- 'echo INT' INT
240## END
241
242#### trap 1 is equivalent to SIGHUP; HUP is equivalent to SIGHUP
243trap 'echo HUP' SIGHUP
244echo status=$?
245trap 'echo HUP' HUP
246echo status=$?
247trap 'echo HUP' 1
248echo status=$?
249trap - HUP
250echo status=$?
251## status: 0
252## STDOUT:
253status=0
254status=0
255status=0
256status=0
257## END
258## N-I dash STDOUT:
259status=1
260status=0
261status=0
262status=0
263## END
264
265#### trap 0 2 resets EXIT AND SIGINT
266
267trap "echo EXIT" EXIT
268echo ---
269trap
270echo ---
271trap 0 2
272trap
273echo ---
274trap "echo INT" INT
275trap "echo EXIT" EXIT
276trap 2 EXIT
277trap
278
279## STDOUT:
280---
281trap -- 'echo EXIT' EXIT
282---
283---
284## END
285
286#### trap '' EXIT - printing state
287
288trap 'echo exit' EXIT
289trap
290echo
291
292trap '' EXIT
293trap
294echo
295
296trap '# comment' EXIT
297trap
298
299## STDOUT:
300trap -- 'echo exit' EXIT
301
302trap -- '' EXIT
303
304trap -- '# comment' EXIT
305## END
306## BUG mksh STDOUT:
307trap -- 'echo exit' EXIT
308
309trap -- EXIT
310
311trap -- '# comment' EXIT
312## END
313
314#### trap 'echo hi' KILL (regression test, caught by smoosh suite)
315trap 'echo hi' 9
316echo status=$?
317
318trap 'echo hi' KILL
319echo status=$?
320
321trap 'echo hi' STOP
322echo status=$?
323
324trap 'echo hi' TERM
325echo status=$?
326
327## STDOUT:
328status=0
329status=0
330status=0
331status=0
332## END
333## OK osh STDOUT:
334status=2
335status=2
336status=2
337status=0
338## END
339
340#### exit 1 when trap code string is invalid
341# All shells spew warnings to stderr, but don't actually exit! Bad!
342trap 'echo <' EXIT
343echo status=$?
344## STDOUT:
345status=1
346## END
347
348## BUG mksh status: 1
349## BUG mksh STDOUT:
350status=0
351## END
352
353## BUG ash status: 2
354## BUG ash STDOUT:
355status=0
356## END
357
358## BUG dash/bash status: 0
359## BUG dash/bash STDOUT:
360status=0
361## END
362
363
364#### trap EXIT calling exit
365cleanup() {
366 echo "cleanup [$@]"
367 exit 42
368}
369trap 'cleanup x y z' EXIT
370## stdout: cleanup [x y z]
371## status: 42
372
373#### trap EXIT return status ignored
374cleanup() {
375 echo "cleanup [$@]"
376 return 42
377}
378trap 'cleanup x y z' EXIT
379## stdout: cleanup [x y z]
380## status: 0
381
382#### trap EXIT with PARSE error
383trap 'echo FAILED' EXIT
384for
385## stdout: FAILED
386## status: 2
387## OK mksh status: 1
388
389#### trap EXIT with PARSE error and explicit exit
390trap 'echo FAILED; exit 0' EXIT
391for
392## stdout: FAILED
393## status: 0
394
395#### trap EXIT with explicit exit
396trap 'echo IN TRAP; echo $stdout' EXIT
397stdout=FOO
398exit 42
399
400## status: 42
401## STDOUT:
402IN TRAP
403FOO
404## END
405
406#### trap EXIT with command sub / subshell / pipeline
407trap 'echo EXIT TRAP' EXIT
408
409echo $(echo command sub)
410
411( echo subshell )
412
413echo pipeline | cat
414
415## STDOUT:
416command sub
417subshell
418pipeline
419EXIT TRAP
420## END
421
422#### eval in the exit trap (regression for issue #293)
423trap 'eval "echo hi"' 0
424## STDOUT:
425hi
426## END
427
428
429#### exit codes for traps are isolated
430
431trap 'echo USR1 trap status=$?; ( exit 42 )' USR1
432
433echo before=$?
434
435# Equivalent to 'kill -USR1 $$' except OSH doesn't have "kill" yet.
436# /bin/kill doesn't exist on Debian unless 'procps' is installed.
437sh -c "kill -USR1 $$"
438echo after=$?
439
440## STDOUT:
441before=0
442USR1 trap status=0
443after=0
444## END
445
446#### traps are cleared in subshell (started with &)
447
448# Test with SIGURG because the default handler is SIG_IGN
449#
450# If we use SIGUSR1, I think the shell reverts to killing the process
451
452# https://man7.org/linux/man-pages/man7/signal.7.html
453
454trap 'echo SIGURG' URG
455
456kill -URG $$
457
458# Hm trap doesn't happen here
459{ echo begin child; sleep 0.1; echo end child; } &
460kill -URG $!
461wait
462echo "wait status $?"
463
464# In the CI, mksh sometimes gives:
465#
466# USR1
467# begin child
468# done
469#
470# leaving off 'end child'. This seems like a BUG to me?
471
472## STDOUT:
473SIGURG
474begin child
475end child
476wait status 0
477## END
478
479#### trap USR1, sleep, SIGINT: non-interactively
480
481$REPO_ROOT/spec/testdata/builtin-trap-usr1.sh
482
483## STDOUT:
484usr1
485status=0
486## END
487
488#### trap INT, sleep, SIGINT: non-interactively
489
490# mksh behaves differently in CI -- maybe when it's not connected to a
491# terminal?
492case $SH in mksh) echo mksh; exit ;; esac
493
494$REPO_ROOT/spec/testdata/builtin-trap-int.sh
495
496## STDOUT:
497status=0
498## END
499
500## OK mksh STDOUT:
501mksh
502## END
503
504# Not sure why other shells differ here, but running the trap is consistent
505# with interactive cases in test/bugs.sh
506
507## OK osh STDOUT:
508int
509status=0
510## END
511
512#### trap EXIT, sleep, SIGINT: non-interactively
513
514$REPO_ROOT/spec/testdata/builtin-trap-exit.sh
515
516## STDOUT:
517on exit
518status=0
519## END
520
521#### Remove trap with an unsigned integer
522
523$SH -e -c '
524trap "echo noprint" EXIT
525trap 0 EXIT
526echo ok0
527'
528echo
529
530$SH -e -c '
531trap "echo noprint" EXIT
532trap " 42 " EXIT
533echo ok42space
534'
535echo
536
537# corner case: sometimes 07 is treated as octal, but not here
538$SH -e -c '
539trap "echo noprint" EXIT
540trap 07 EXIT
541echo ok07
542'
543echo
544
545$SH -e -c '
546trap "echo trap-exit" EXIT
547trap -1 EXIT
548echo bad
549'
550if test $? -ne 0; then
551 echo failure
552fi
553
554## STDOUT:
555ok0
556
557ok42space
558
559ok07
560
561trap-exit
562failure
563## END
564
565#### trap '' sets handler to empty string (SIG_IGN)
566
567trap '' USR1
568trap
569
570## STDOUT:
571trap -- '' SIGUSR1
572## END
573
574#### trap '' with multiple signals
575
576trap '' USR1 USR2
577trap
578
579## STDOUT:
580trap -- '' SIGUSR1
581trap -- '' SIGUSR2
582## END
583
584#### trap '' rejects hooks
585
586trap '' EXIT
587echo should not get here
588
589## STDOUT:
590## END
591## status: 2
592
593#### trap '' rejects STOP signal
594
595trap '' STOP
596echo should not get here
597
598## STDOUT:
599## END
600## status: 2
601
602#### trap '' rejects KILL signal
603
604trap '' KILL
605echo should not get here
606
607## STDOUT:
608## END
609## status: 2