OILS / spec / stateful / trap.sh View on Github | oilshell.org

148 lines, 75 significant
1#!/usr/bin/env bash
2#
3# Demo of traps.
4
5# BUG: OSH doesn't run the trap because of KeyboardInterrupt!
6
7# BUG interactively too:
8#
9# osh$ trap 'echo INT' SIGINT; sleep 5 & wait
10
11sigint-batch() {
12 trap 'echo [got SIGINT]' INT
13 echo "Registered SIGINT trap. Hit Ctrl-C or Run 'kill -INT $$' to see a message."
14 sleep 5
15}
16
17sigterm-batch() {
18 trap 'echo [got SIGTERM]' TERM
19 echo "Registered SIGTERM trap. Run 'kill -TERM $$' to see a message."
20 sleep 5
21}
22
23# BUG: OSH gets two sigterms?
24sigterm-then-kill-test() {
25 local sh=${1:-bash}
26 #### SIGTERM trap should run upon 'kill'
27 $sh -c 'echo "> PID $$ started";
28 echo $$ > _tmp/pid.txt;
29 trap "echo SIGTERM" TERM;
30 sleep 1;
31 echo "< PID $$ done"' &
32
33 sleep 0.5
34 local pid=$(cat _tmp/pid.txt)
35 echo "killing $pid"
36 kill -TERM $pid
37 wait
38 echo status=$?
39}
40
41sigterm() {
42 echo "sigterm [$@] $?"
43 # quit the process -- otherwise we resume!
44 exit
45}
46
47child() {
48 trap 'sigterm x y' SIGTERM
49 echo child
50 for i in $(seq 5); do
51 sleep 1
52 done
53}
54
55
56readonly SH=bash
57#readonly SH=dash # bad trap
58#readonly SH=mksh
59#readonly SH=zsh
60
61child2() {
62 $SH -c '
63 sigterm() {
64 echo "sigterm [$@] $?"
65 # quit the process -- otherwise we resume!
66 exit
67 }
68
69 trap "sigterm x y" SIGTERM
70 trap -p
71 echo child
72 for i in $(seq 5); do
73 sleep 1
74 done
75 ' &
76}
77
78start-and-kill() {
79 $0 child &
80
81 #child2
82
83 echo "started $!"
84 sleep 0.1 # a little race to allow things to be printed
85
86 # NOTE: The process only dies after one second. The "sleep 1" is run until
87 # completion, and then the signal handler is run, which calls "exit".
88
89 echo "killing $!"
90 kill -s SIGTERM $!
91 wait $!
92 echo status=$?
93}
94
95num_signals=0
96
97ignore-n-times() {
98 (( num_signals++ ))
99
100 if [[ $num_signals -le 2 ]]; then
101 echo "Received signal $num_signals -- IGNORING"
102 else
103 echo "Removing this signal handler; next one will be the default"
104 trap - TERM
105 fi
106}
107
108# In bash: Run this and hit Ctrl-C four times to see the handler in action!
109#
110# NOTE: Ctrl-C doesn't work in Python because Python does stuff with SIGINT!
111# We could disable KeyboardInterrupt entirely in the OVM build? But still need
112# the signal module!
113
114sleep-and-ignore() {
115 trap ignore-n-times TERM
116 for i in $(seq 10); do
117 echo $i
118 sleep 0.2
119 done
120}
121
122# NOTE: osh has EINTR problems here!
123#
124# File "/home/andy/git/oilshell/oil/bin/../core/process.py", line 440, in WaitUntilDone
125# if not waiter.Wait():
126# File "/home/andy/git/oilshell/oil/bin/../core/process.py", line 632, in Wait
127# pid, status = os.wait()
128# OSError: [Errno 4] Interrupted system call
129
130kill-sleep-and-ignore() {
131 sleep-and-ignore &
132 local last_pid=$!
133
134 echo "Started $last_pid"
135
136 # Hm sometimes the signal gets ignored? You can't just kill it 3 times?
137 for i in $(seq 5); do
138 kill -s SIGTERM $last_pid
139 echo kill status=$?
140 sleep 0.1
141 done
142
143 wait
144 echo wait status=$?
145}
146
147"$@"
148