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 done
|
9 | ## STDOUT:
|
10 | done
|
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 INT, sleep, SIGINT: non-interactively
|
250 |
|
251 | # mksh behaves differently in CI -- maybe when it's not connected to a
|
252 | # terminal?
|
253 |
|
254 | case $SH in mksh) echo mksh; exit ;; esac
|
255 |
|
256 | # Without this, it succeeds in CI?
|
257 | case $SH in *osh) echo osh; exit ;; esac
|
258 |
|
259 | $SH -c 'trap "echo int" INT; sleep 0.1' &
|
260 | /usr/bin/kill -INT $!
|
261 | wait
|
262 |
|
263 | # Only mksh shows 'int'?
|
264 | # OSH shows "done"
|
265 |
|
266 | ## STDOUT:
|
267 | ## END
|
268 | ## OK mksh STDOUT:
|
269 | mksh
|
270 | ## END
|