1Sys::SigAction(3) User Contributed Perl Documentation Sys::SigAction(3)
2
3
4
6 Sys::SigAction - Perl extension for Consistent Signal Handling
7
9 #do something non-interupt able
10 use Sys::SigAction qw( set_sig_handler );
11 {
12 my $h = set_sig_handler( 'INT' ,'mysubname' ,{ flags => SA_RESTART } );
13 ... do stuff non-interupt able
14 } #signal handler is reset when $h goes out of scope
15
16 or
17
18 #timeout a system call:
19 use Sys::SigAction qw( set_sig_handler );
20 eval {
21 my $h = set_sig_handler( 'ALRM' ,\&mysubname ,{ mask=>[ 'ALRM' ] ,safe=>1 } );
22 alarm(2)
23 ... do something you want to timeout
24 alarm(0);
25 }; #signal handler is reset when $h goes out of scope
26 alarm(0);
27 if ( $@ ) ...
28
29 or
30
31 use Sys::SigAction;
32 my $alarm = 0;
33 eval {
34 my $h = Sys::SigAction::set_sig_handler( 'ALRM' ,sub { $alarm = 1; } );
35 alarm(2)
36 ... do something you want to timeout
37 alarm(0);
38 };
39 alarm(0);
40 if ( $@ or $alarm ) ...
41
42 or
43
44 use Sys::SigAction;
45 my $alarm = 0;
46 Sys::SigAction::set_sig_handler( 'TERM' ,sub { "DUMMY" } );
47 #code from here on uses new handler.... (old handler is forgotten)
48
49 or
50
51 use Sys::SigAction qw( timeout_call );
52 if ( timeout_call( 5 ,sub { $retval = DoSomething( @args ); } )
53 {
54 print "DoSomething() timed out\n" ;
55 }
56
58 This module implements "set_sig_handler()", which sets up a signal
59 handler and (optionally) returns an object which causes the signal
60 handler to be reset to the previous value, when it goes out of scope.
61
62 Also implemented is "timeout_call()" which takes a timeout value and a
63 code reference, and executes the code reference wrapped with an alarm
64 timeout.
65
66 Finally, two convenience routines are defined which allow one to get
67 the signal name from the number -- "sig_name()", and get the signal
68 number from the name -- "sig_number()".
69
71 Prior to version 5.8.0 perl implemented 'unsafe' signal handling. The
72 reason it is consider unsafe, is that there is a risk that a signal
73 will arrive, and be handled while perl is changing internal data
74 structures. This can result in all kinds of subtle and not so subtle
75 problems. For this reason it has always been recommended that one do
76 as little as possible in a signal handler, and only variables that
77 already exist be manipulated.
78
79 Perl 5.8.0 and later versions implements 'safe' signal handling on
80 platforms which support the POSIX sigaction() function. This is
81 accomplished by having perl note that a signal has arrived, but
82 deferring the execution of the signal handler until such time as it is
83 safe to do so. Unfortunately these changes can break some existing
84 scripts, if they depended on a system routine being interupted by the
85 signal's arrival. The perl 5.8.0 implementation was modified further
86 in version 5.8.2.
87
88 From the perl 5.8.2 perlvar man page:
89
90 The default delivery policy of signals changed in Perl 5.8.0
91 from immediate (also known as "unsafe") to deferred, also
92 known as "safe signals".
93
94 The implementation of this changed the "sa_flags" with which the signal
95 handler is installed by perl, and it causes some system routines (like
96 connect()) to return EINTR, instead of another error when the signal
97 arrives. The problem comes when the code that made the system call
98 sees the EINTR code and decides it's going to call it again before
99 returning. Perl doesn't do this but some libraries do, including for
100 instance, the Oracle OCI library.
101
102 Thus the 'deferred signal' approach (as implemented by default in perl
103 5.8 and later) results in some system calls being retried prior to the
104 signal handler being called by perl. This breaks timeout logic for
105 DBD-Oracle which works with earlier versions of perl. This can be
106 particularly vexing, the host on which a database resides is not
107 available: "DBI->connect()" hangs for minutes before returning an
108 error (and cannot even be interupted with control-C, even when the
109 intended timeout is only seconds). This is because SIGINT appears to
110 be deferred as well. The result is that it is impossible to implement
111 open timeouts with code that looks like this in perl 5.8.0 and later:
112
113 eval {
114 local $SIG{ALRM} = sub { die "timeout" };
115 alarm 2;
116 $sth = DBI->connect(...);
117 alarm 0;
118 };
119 alarm 0;
120 die if $@;
121
122 The solution, if your system has the POSIX sigaction() function, is to
123 use perl's "POSIX::sigaction()" to install the signal handler. With
124 "sigaction()", one gets control over both the signal mask, and the
125 "sa_flags" that are used to install the handler. Further, with perl
126 5.8.2 and later, a 'safe' switch is provided which can be used to ask
127 for safe(r) signal handling.
128
129 Using sigaction() ensures that the system call won't be resumed after
130 it's interrupted, so long as die is called within the signal handler.
131 This is no longer the case when one uses $SIG{name} to set signal
132 handlers in perls >= 5.8.0.
133
134 The usage of sigaction() is not well documented however, and in perl
135 versions less than 5.8.0, it does not work at all. (But that's OK,
136 because just setting $SIG does work in that case.) Using sigaction()
137 requires approximately 4 or 5 lines of code where previously one only
138 had to set a code reference into the %SIG hash.
139
140 Unfortunately, at least with perl 5.8.0, the result is that doing this
141 effectively reverts to the 'unsafe' signals behavior. It is not clear
142 whether this would be the case in perl 5.8.2, since the safe flag can
143 be used to ask for safe signal handling. I suspect this separates the
144 logic which uses the "sa_flags" to install the handler, and whether
145 deferred signal handling is used.
146
147 The reader should also note, that the behavior of the 'safe' attribute
148 is not consistent with what this author expected. Specifically, it
149 appears to disable signal masking. This can be examined further in the
150 t/safe.t and the t/mask.t regression tests. Never-the-less,
151 Sys::SigAction provides an easy mechanism for the user to recover the
152 pre-5.8.0 behavior for signal handling, and the mask attribute clearly
153 works. (see t/mask.t) If one is looking for specific safe signal
154 handling behavior that is considered broken, and the breakage can be
155 demonstrated, then a patch to t/safe.t would be most welcome.
156
157 This module wraps up the POSIX:: routines and objects necessary to call
158 sigaction() in a way that is as efficient from a coding perspective as
159 just setting a localized $SIG{SIGNAL} with a code reference. Further,
160 the user has control over the "sa_flags" passed to sigaction(). By
161 default, if no additional args are passed to sigaction(), then the
162 signal handler will be called when a signal (such as SIGALRM) is
163 delivered.
164
165 Since sigaction() is not fully functional in perl versions less than
166 5.8, this module implements equivalent behavior using the standard %SIG
167 array. The version checking and implementation of the 'right' code is
168 handled by this module, so the user does not have to write perl version
169 dependent code. The attrs hashref argument to set_sig_handler() is
170 silently ignored, in perl versions less than 5.8. This module has been
171 tested with perls as old as 5.005 on solaris.
172
173 It is hoped that with the use of this module, your signal handling
174 behavior can be coded in a way that does not change from one perl
175 version to the next, and that sigaction() will be easier for you to
176 use.
177
179 set_sig_handler()
180 $sig ,$handler ,$attrs
181
182 Install a new signal handler and (if not called in a void context)
183 returning a Sys::SigAction object containing the old signal handler,
184 which will be restored on object destruction.
185
186 $sig is a signal name (without the 'SIG') or number.
187
188 $handler is either the name (string) of a signal handler
189 function or a subroutine CODE reference.
190
191 $attrs if defined is a hash reference containing the
192 following keys:
193
194 flags => the flags the passed sigaction
195
196 ex: SA_RESTART (defined in your signal.h)
197
198 mask => the array reference: signals you
199 do not want delivered while the signal
200 handler is executing
201
202 ex: [ SIGINT SIGUSR1 ] or
203 ex: [ qw( INT USR1 ]
204
205 safe => A boolean value requesting 'safe' signal
206 handling (only in 5.8.2 and greater)
207 earlier versions will issue a warning if
208 you use this
209
210 NOTE: This breaks the signal masking
211
212 timeout_call()
213 $timeout ,$coderef
214
215 Given a code reference, and a timeout value (in seconds), timeout()
216 will (in an eval) setup a signal handler for SIGALRM (which will die),
217 set an alarm clock, and execute the code reference.
218
219 If the alarm goes off the code will be interupted. The alarm is
220 canceled if the code returns before the alarm is fired. The routine
221 returns true if the code being executed timed out. (was interrupted).
222 Exceptions thrown by the code executed are propagated out.
223
224 The original signal handler is restored, prior to returning to the
225 caller.
226
227 sig_name()
228 Return the signal name (string) from a signal number.
229
230 ex:
231
232 sig_name( SIGINT ) returns 'INT'
233
234 sig_number()
235 Return the signal number (integer) from a signal name (minus the SIG
236 part).
237
238 ex:
239
240 sig_number( 'INT' ) returns the integer value of SIGINT;
241
243 Lincoln A. Baxter <lab-at-lincolnbaxter-dot-com>
244
246 Copyright (c) 2004-2009 Lincoln A. Baxter
247 All rights reserved.
248
249 You may distribute under the terms of either the GNU General Public
250 License or the Artistic License, as specified in the Perl README file,
251
253 perldoc perlvar
254 perldoc POSIX
255
256 The dbd-oracle-timeout.pod file included with this module. This
257 includes a DBD-Oracle test script, which illustrates the use of this
258 module with the DBI with the DBD-Oracle driver.
259
260
261
262perl v5.12.0 2009-01-24 Sys::SigAction(3)