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