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

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