1Sys::SigAction(3)     User Contributed Perl Documentation    Sys::SigAction(3)
2
3
4

NAME

6       Sys::SigAction - Perl extension for Consistent Signal Handling
7

SYNOPSYS

9          #do something non-interrupt 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-interrupt 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             eval {
23                alarm(2)
24                ... do something you want to timeout
25                alarm(0);
26             };
27             alarm(0);
28             die $@ if $@;
29          }; #signal handler is reset when $h goes out of scope
30          if ( $@ ) ...
31
32       or
33
34          use Sys::SigAction;
35          my $alarm = 0;
36          eval {
37             my $h = Sys::SigAction::set_sig_handler( 'ALRM' ,sub { $alarm = 1; } );
38             eval {
39                alarm(2)
40                ... do something you want to timeout
41                alarm(0);
42             };
43             alarm(0);
44             die $@ if $@;
45          }; #signal handler is reset when $h goes out of scope
46          if ( $@ or $alarm ) ...
47
48       or
49
50          use Sys::SigAction;
51          my $alarm = 0;
52          Sys::SigAction::set_sig_handler( 'TERM' ,sub { "DUMMY" } );
53          #code from here on uses new handler.... (old handler is forgotten)
54
55       or
56
57          use Sys::SigAction qw( timeout_call );
58          if ( timeout_call( 5 ,sub { $retval = DoSomething( @args ); } )
59          {
60             print "DoSomething() timed out\n" ;
61          }
62
63       or
64
65          #use a floating point (fractional seconds) in timeout_call
66          use Sys::SigAction qw( timeout_call );
67          if ( timeout_call( 0.1 ,sub { $retval = DoSomething( @args ); } )
68          {
69             print "DoSomething() timed out\n" ;
70          }
71

ABSTRACT

73       This module implements "set_sig_handler()", which sets up a signal
74       handler and (optionally) returns an object which causes the signal
75       handler to be reset to the previous value, when it goes out of scope.
76
77       Also implemented is "timeout_call()" which takes a timeout value, a
78       code reference and optional arguments, and executes the code reference
79       wrapped with an alarm timeout. timeout_call accepts seconds in floating
80       point format, so you can time out call with a resolution of 0.000001
81       seconds. If "Time::HiRes" is not loadable or "Time::HiRes::ualarm()"
82       does not work, then the factional part of the time value passed to
83       "timeout_call()" will be raise to the next higher integer with
84       POSIX::ceil(). This means that the shortest a timeout can be in 1
85       second.
86
87       Finally, two convenience routines are defined which allow one to get
88       the signal name from the number -- "sig_name()", and get the signal
89       number from the name -- "sig_number()".
90

DESCRIPTION

92       Prior to version 5.8.0 perl implemented 'unsafe' signal handling.  The
93       reason it is consider unsafe, is that there is a risk that a signal
94       will arrive, and be handled while perl is changing internal data
95       structures.  This can result in all kinds of subtle and not so subtle
96       problems.  For this reason it has always been recommended that one do
97       as little as possible in a signal handler, and only variables that
98       already exist be manipulated.
99
100       Perl 5.8.0 and later versions implements 'safe' signal handling on
101       platforms which support the POSIX sigaction() function.  This is
102       accomplished by having perl note that a signal has arrived, but
103       deferring the execution of the signal handler until such time as it is
104       safe to do so.  Unfortunately these changes can break some existing
105       scripts, if they depended on a system routine being interrupted by the
106       signal's arrival.  The perl 5.8.0 implementation was modified further
107       in version 5.8.2.
108
109       From the perl 5.8.2 perlvar man page:
110
111          The default delivery policy of signals changed in Perl 5.8.0
112          from immediate (also known as "unsafe") to deferred, also
113          known as "safe signals".
114
115       The implementation of this changed the "sa_flags" with which the signal
116       handler is installed by perl, and it causes some system routines (like
117       connect()) to return EINTR, instead of another error when the signal
118       arrives.  The problem comes when the code that made the system call
119       sees the EINTR code and decides it's going to call it again before
120       returning. Perl doesn't do this but some libraries do, including for
121       instance, the Oracle OCI library.
122
123       Thus the 'deferred signal' approach (as implemented by default in perl
124       5.8 and later) results in some system calls being retried prior to the
125       signal handler being called by perl.  This breaks timeout logic for
126       DBD-Oracle which works with earlier versions of perl.  This can be
127       particularly vexing, when, for instance, the host on which a database
128       resides is not available:  "DBI->connect()" hangs for minutes before
129       returning an error (and cannot even be interrupted with control-C, even
130       when the intended timeout is only seconds).  This is because SIGINT
131       appears to be deferred as well.  The result is that it is impossible to
132       implement open timeouts with code that looks like this in perl 5.8.0
133       and later:
134
135          eval {
136             eval {
137                local $SIG{ALRM} = sub { die "timeout" };
138                alarm 2;
139                $sth = DBI->connect(...);
140                alarm 0;
141             };
142             alarm 0;
143             die if $@;
144          };
145
146       Or as the author of bug #50628 pointed out, might probably better be
147       written as:
148
149          eval {
150             local $SIG{ALRM} = sub { die "timeout" };
151             eval {
152                alarm 2;
153                $sth = DBI->connect(...);
154                alarm 0;
155             };
156             alarm 0;
157             die if $@;
158          };
159
160       The solution, if your system has the POSIX sigaction() function, is to
161       use perl's "POSIX::sigaction()" to install the signal handler.  With
162       "sigaction()", one gets control over both the signal mask, and the
163       "sa_flags" that are used to install the handler.  Further, with perl
164       5.8.2 and later, a 'safe' switch is provided which can be used to ask
165       for safe(r) signal handling.
166
167       Using sigaction() ensures that the system call won't be resumed after
168       it's interrupted, so long as die is called within the signal handler.
169       This is no longer the case when one uses $SIG{name} to set signal
170       handlers in perls >= 5.8.0.
171
172       The usage of sigaction() is not well documented however, and in perl
173       versions less than 5.8.0, it does not work at all. (But that's OK,
174       because just setting $SIG does work in that case.)  Using sigaction()
175       requires approximately 4 or 5 lines of code where previously one only
176       had to set a code reference into the %SIG hash.
177
178       Unfortunately, at least with perl 5.8.0, the result is that doing this
179       effectively reverts to the 'unsafe' signals behavior.  It is not clear
180       whether this would be the case in perl 5.8.2, since the safe flag can
181       be used to ask for safe signal handling.  I suspect this separates the
182       logic which uses the "sa_flags" to install the handler, and whether
183       deferred signal handling is used.
184
185       The reader should also note, that the behavior of the 'safe' attribute
186       is not consistent with what this author expected.  Specifically, it
187       appears to disable signal masking. This can be examined further in the
188       t/safe.t and the t/mask.t regression tests.  Never-the-less,
189       Sys::SigAction provides an easy mechanism for the user to recover the
190       pre-5.8.0 behavior for signal handling, and the mask attribute clearly
191       works. (see t/mask.t) If one is looking for specific safe signal
192       handling behavior that is considered broken, and the breakage can be
193       demonstrated, then a patch to t/safe.t would be most welcome.
194
195       This module wraps up the POSIX:: routines and objects necessary to call
196       sigaction() in a way that is as efficient from a coding perspective as
197       just setting a localized $SIG{SIGNAL} with a code reference.  Further,
198       the user has control over the "sa_flags" passed to sigaction().  By
199       default, if no additional args are passed to sigaction(), then the
200       signal handler will be called when a signal (such as SIGALRM) is
201       delivered.
202
203       Since sigaction() is not fully functional in perl versions less than
204       5.8, this module implements equivalent behavior using the standard %SIG
205       array.  The version checking and implementation of the 'right' code is
206       handled by this module, so the user does not have to write perl version
207       dependent code.  The attrs hashref argument to set_sig_handler() is
208       silently ignored, in perl versions less than 5.8.  When this module was
209       developed it was tested on perl 5.005 on solaris.  That was in 2004.
210       Now only perl versions >= 5.6 are supported. If you want this to work
211       on perl 5.5 you will have comment out "use warnings" everywhere.
212
213       It is hoped that with the use of this module, your signal handling
214       behavior can be coded in a way that does not change from one perl
215       version to the next, and that sigaction() will be easier for you to
216       use.
217

Note on "Double evals"

219       CPAN bug #50628 which was filed against Sys::SigAction-0.11 noting that
220       the sample code was "buggy" because the evals that wrapped the code we
221       wanted to timeout might die for an unanticipated reason, before the
222       alarm could be cleared.  In that case, as the bug writer noted, if the
223       alarm expires before the final alarm(0) can be called, either the code
224       will completely die because there is no SIGALRM handler in place to
225       catch the signal, or the wrong handler (not the local handler) will be
226       called.
227
228       All the code samples in this module have been modified to account for
229       this.  Additionally we have made the same change in timeout_call()
230       which could have exhibited this behavior, though the AUTHOR never
231       knowing experienced it.
232

FUNCTIONS

234   set_sig_handler()
235          $sig ,$handler ,$attrs
236
237       Install a new signal handler and (if not called in a void context)
238       returning a Sys::SigAction object containing the old signal handler,
239       which will be restored on object destruction.
240
241          $sig     is a signal name (without the 'SIG') or number.
242
243          $handler is either the name (string) of a signal handler
244                   function or a subroutine CODE reference.
245
246          $attrs   if defined is a hash reference containing the
247                   following keys:
248
249                   flags => the flags the passed sigaction
250
251                      ex: SA_RESTART (defined in your signal.h)
252
253                   mask  => the array reference: signals you
254                            do not want delivered while the signal
255                            handler is executing
256
257                      ex: [ SIGINT SIGUSR1 ] or
258                      ex: [ qw( INT USR1 ]
259
260                   safe  => A boolean value requesting 'safe' signal
261                            handling (only in 5.8.2 and greater)
262                            earlier versions will issue a warning if
263                            you use this
264
265                            NOTE: This breaks the signal masking
266
267   timeout_call()
268          $timeout, $coderef, @args
269
270       Given a code reference, and a timeout value (in seconds),
271       timeout_call() will (in an eval) setup a signal handler for SIGALRM
272       (which will die), set an alarm clock, and execute the code reference
273       with optional arguments @args. $timeout (seconds) may be expressed as a
274       floating point number.
275
276       If Time::HiRes is present and useable, timeout_call() can be used with
277       a timer resolution of 0.000001 seconds. If HiRes is not loadable,
278       Sys::SigAction will "do the right thing" and convert the factional
279       seconds to the next higher integer value using the posix ceil()
280       function.
281
282       If the alarm goes off the code will be interrupted.  The alarm is
283       canceled if the code returns before the alarm is fired.  The routine
284       returns true if the code being executed timed out. (was interrupted).
285       Exceptions thrown by the code executed are propagated out.
286
287       The original signal handler is restored, prior to returning to the
288       caller.
289
290   sig_alarm()
291       ex:
292
293          sig_alarm( 1.2 );
294
295       sig_alarm() is a drop in replacement for the standard alarm() function.
296       The argument may be expressed as a floating point number.
297
298       If Time::HiRes is present and useable, the alarm timers will be set to
299       the floating point value with a resolution of 0.000001 seconds.  If
300       Time::HiRes is not available then the a fractional value in the
301       argument will be raised to the next higher integer value.
302
303   sig_name()
304       Return the signal name (string) from a signal number.
305
306       ex:
307
308          sig_name( SIGINT ) returns 'INT'
309
310   sig_number()
311       Return the signal number (integer) from a signal name (minus the SIG
312       part).
313
314       ex:
315
316          sig_number( 'INT' ) returns the integer value of SIGINT;
317

MULTITHREADED PERL

319       Sys::SigAction works just fine on perls built with multithread support
320       in single threaded perl applications. However, please note that using
321       Signals in a multi-thread perl application is unsupported.
322
323       Read the following from perldoc perlthrtut:
324
325          ... mixing signals and threads may be problematic.
326          Implementations are platform-dependent, and even the POSIX semantics
327          may not be what you expect (and Perl doesn't even give you the full
328          POSIX API).  For example, there is no way to guarantee that a signal
329          sent to a multi-threaded Perl application will get intercepted by
330          any particular thread.
331
332       That said, perl documentation for perl threading discusses a a way of
333       emulating signals in multi-threaded applications, when safe signals is
334       in effect. See perldoc threads and search for THREAD SIGNALLING.  I
335       have no test of multithreading and this module.  If you think they
336       could be used compatibly and would provide value, patches are welcome.
337

AUTHOR

339          Lincoln A. Baxter <lab-at-lincolnbaxter-dot-com>
340
342          Copyright (c) 2004-2016 Lincoln A. Baxter
343          All rights reserved.
344
345          You may distribute under the terms of either the GNU General Public
346          License or the Artistic License, as specified in the Perl README file,
347

SEE ALSO

349          perldoc perlvar
350          perldoc POSIX
351
352
353
354perl v5.30.1                      2020-01-30                 Sys::SigAction(3)
Impressum