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-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

ABSTRACT

58       This module implements "set_sig_handler()", which sets up a signal han‐
59       dler and (optionally) returns an object which causes the signal handler
60       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

DESCRIPTION

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 struc‐
74       tures.  This can result in all kinds of subtle and not so subtle prob‐
75       lems.  For this reason it has always been recommended that one do as
76       little as possible in a signal handler, and only variables that already
77       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 accom‐
81       plished by having perl note that a signal has arrived, but deferring
82       the execution of the signal handler until such time as it is safe to do
83       so.  Unfortunately these changes can break some existing scripts, if
84       they depended on a system routine being interupted by the signal's
85       arrival.  The perl 5.8.0 implementation was modified further in version
86       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 par‐
106       ticularly vexing, the host on which a database resides is not avail‐
107       able:  "DBI->connect()" hangs for minutes before returning an error
108       (and cannot even be interupted with control-C, even when the intended
109       timeout is only seconds).  This is because SIGINT appears to be
110       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 han‐
132       dlers 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 han‐
154       dling 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 sig‐
162       nal handler will be called when a signal (such as SIGALRM) is deliv‐
163       ered.
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 ver‐
175       sion to the next, and that sigaction() will be easier for you to use.
176

FUNCTIONS

178       set_sig_handler()
179
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       timeout_call()
211
212          $timeout ,$coderef
213
214       Given a code reference, and a timeout value (in seconds), timeout()
215       will (in an eval) setup a signal handler for SIGALRM (which will die),
216       set an alarm clock, and execute the code reference.
217
218       If the alarm goes off the code will be interupted.  The alarm is can‐
219       celed if the code returns before the alarm is fired.  The routine
220       returns true if the code being executed timed out. (was interrupted).
221       Exceptions thrown by the code executed are propagated out.
222
223       The original signal handler is restored, prior to returning to the
224       caller.
225
226       sig_name()
227
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
236       Return the signal number (integer) from a signal name (minus the SIG
237       part).
238
239       ex:
240
241          sig_number( 'INT' ) returns the integer value of SIGINT;
242

AUTHOR

244          Lincoln A. Baxter <lab@lincolnbaxter.com.make.me.VALID>
245
247          Copyright (c) 2004 Lincoln A. Baxter
248          All rights reserved.
249
250          You may distribute under the terms of either the GNU General Public
251          License or the Artistic License, as specified in the Perl README file,
252          with the exception that it cannot be placed on a CD-ROM or similar media
253          for commercial distribution without the prior approval of the author.
254

SEE ALSO

256          perldoc perlvar
257          perldoc POSIX
258
259       The dbd-oracle-timeout.pod file included with this module. This
260       includes a DBD-Oracle test script, which illustrates the use of this
261       module with the DBI with the DBD-Oracle driver.
262
263
264
265perl v5.8.8                       2006-10-24                 Sys::SigAction(3)
Impressum