=head1 Signals
-Perl uses a simple signal handling model: the %SIG hash contains names or
-references of user-installed signal handlers. These handlers will be called
-with an argument which is the name of the signal that triggered it. A
-signal may be generated intentionally from a particular keyboard sequence like
-control-C or control-Z, sent to you from another process, or
-triggered automatically by the kernel when special events transpire, like
-a child process exiting, your process running out of stack space, or
-hitting file size limit.
+Perl uses a simple signal handling model: the %SIG hash contains names
+or references of user-installed signal handlers. These handlers will
+be called with an argument which is the name of the signal that
+triggered it. A signal may be generated intentionally from a
+particular keyboard sequence like control-C or control-Z, sent to you
+from another process, or triggered automatically by the kernel when
+special events transpire, like a child process exiting, your process
+running out of stack space, or hitting file size limit.
For example, to trap an interrupt signal, set up a handler like this:
$SIG{INT} = 'catch_zap'; # could fail in modules
$SIG{INT} = \&catch_zap; # best strategy
-Prior to perl5.7.3 it was necessary to do as little as you possibly can in your handler;
-notice how all we do is set a global variable and then raise an exception. That's because on
-most systems, libraries are not re-entrant; particularly, memory allocation and I/O
-routines are not. That meant that doing nearly I<anything> in your handler could in theory
-trigger a memory fault and subsequent core dump - see L<Deferred Signals> below.
+Prior to Perl 5.7.3 it was necessary to do as little as you possibly
+could in your handler; notice how all we do is set a global variable
+and then raise an exception. That's because on most systems,
+libraries are not re-entrant; particularly, memory allocation and I/O
+routines are not. That meant that doing nearly I<anything> in your
+handler could in theory trigger a memory fault and subsequent core
+dump - see L<Deferred Signals> below.
The names of the signals are the ones listed out by C<kill -l> on your
system, or you can retrieve them from the Config module. Set up an
=head2 Deferred Signals
-In perls before perl5.7.3 by installing Perl code to deal with signals, you were exposing
-yourself to danger from two things. First, few system library functions are
-re-entrant. If the signal interrupts while Perl is executing one function
-(like malloc(3) or printf(3)), and your signal handler then calls the
-same function again, you could get unpredictable behavior--often, a
-core dump. Second, Perl isn't itself re-entrant at the lowest levels.
-If the signal interrupts Perl while Perl is changing its own internal
-data structures, similarly unpredictable behaviour may result.
+In Perls before Perl 5.7.3 by installing Perl code to deal with
+signals, you were exposing yourself to danger from two things. First,
+few system library functions are re-entrant. If the signal interrupts
+while Perl is executing one function (like malloc(3) or printf(3)),
+and your signal handler then calls the same function again, you could
+get unpredictable behavior--often, a core dump. Second, Perl isn't
+itself re-entrant at the lowest levels. If the signal interrupts Perl
+while Perl is changing its own internal data structures, similarly
+unpredictable behaviour may result.
There were two things you could do, knowing this: be paranoid or be
pragmatic. The paranoid approach was to do as little as possible in your
convenience'', and to do anything you wanted in your signal handler,
and be prepared to clean up core dumps now and again.
-In perl5.7.3 and later to avoid these problems signals are "deferred" - that is when the
-signal is delivered to the process by the system (to the C code that implements perl) a flag
-is set, and the handler returns immediately. Then at strategic "safe" points in the perl
-interpreter (e.g. when it is about to execute a new opcode) the flags are checked
-and the perl level handler from %SIG is executed. The "deferred" scheme allows much more
-flexibility in the coding of signal handler as we know perl interpreter is in a
-safe state, and that we are not in a system library function when the handler is called.
-However the implementation does differ from previous perls in the following ways:
+In Perl 5.7.3 and later to avoid these problems signals are
+"deferred"-- that is when the signal is delivered to the process by
+the system (to the C code that implements Perl) a flag is set, and the
+handler returns immediately. Then at strategic "safe" points in the
+Perl interpreter (e.g. when it is about to execute a new opcode) the
+flags are checked and the Perl level handler from %SIG is
+executed. The "deferred" scheme allows much more flexibility in the
+coding of signal handler as we know Perl interpreter is in a safe
+state, and that we are not in a system library function when the
+handler is called. However the implementation does differ from
+previous Perls in the following ways:
=over 4
=item Long running opcodes
-As perl interpreter only looks at the signal flags when it about to execute a new
-opcode if a signal arrives during a long running opcode (e.g. a regular expression
-operation on a very large string) then signal will not be seen until operation completes.
+As Perl interpreter only looks at the signal flags when it about to
+execute a new opcode if a signal arrives during a long running opcode
+(e.g. a regular expression operation on a very large string) then
+signal will not be seen until operation completes.
=item Interrupting IO
-When a signal is delivered (e.g. INT control-C) the operating system breaks into
-IO operations like C<read> (used to implement perls E<lt>E<gt> operator). On
-older perls the handler was called immediately (and as C<read> is not "unsafe" this
-worked well). With the "deferred" scheme the handler is not called immediately,
-and if perl is using system's C<stdio> library that library may re-start the C<read>
-without returning to perl and giving it a chance to call the %SIG handler. If this
-happens on your system the solution is to use C<:perlio> layer to do IO - at least
-on those handles which you want to be able to break into with signals. (The C<:perlio>
-layer checks the signal flags and calls %SIG handlers before resuming IO operation.)
+When a signal is delivered (e.g. INT control-C) the operating system
+breaks into IO operations like C<read> (used to implement Perls
+E<lt>E<gt> operator). On older Perls the handler was called
+immediately (and as C<read> is not "unsafe" this worked well). With
+the "deferred" scheme the handler is not called immediately, and if
+Perl is using system's C<stdio> library that library may re-start the
+C<read> without returning to Perl and giving it a chance to call the
+%SIG handler. If this happens on your system the solution is to use
+C<:perlio> layer to do IO - at least on those handles which you want
+to be able to break into with signals. (The C<:perlio> layer checks
+the signal flags and calls %SIG handlers before resuming IO operation.)
+
+Note that the default in Perl 5.7.3 and later is to automatically use
+the C<:perlio> layer.
=item Signals as "faults"
-Certain signals e.g. SEGV, ILL, BUS are generated as a result of virtual memory or
-other "faults". These are normally fatal and there is little a perl-level handler
-can do with them. (In particular the old signal scheme was particularly unsafe
-in such cases.) However if a %SIG handler is set the new scheme simply sets a flag
-and returns as described above. This may cause the operating system to try the
-offending machine instruction again and - as nothing has changed - it will generate
-the signal again. The result of this is a rather odd "loop". In future perl's signal
-mechanism may be changed to avoid this - perhaps by simply disallowing %SIG handlers
-on signals of that type. Until then the work-round is not to set a %SIG handler on
-those signals. (Which signals they are is operating system dependant.)
+Certain signals e.g. SEGV, ILL, BUS are generated as a result of
+virtual memory or other "faults". These are normally fatal and there
+is little a Perl-level handler can do with them. (In particular the
+old signal scheme was particularly unsafe in such cases.) However if
+a %SIG handler is set the new scheme simply sets a flag and returns as
+described above. This may cause the operating system to try the
+offending machine instruction again and - as nothing has changed - it
+will generate the signal again. The result of this is a rather odd
+"loop". In future Perl's signal mechanism may be changed to avoid this
+- perhaps by simply disallowing %SIG handlers on signals of that
+type. Until then the work-round is not to set a %SIG handler on those
+signals. (Which signals they are is operating system dependant.)
=item Signals triggered by operating system state
-On some operating systems certain signal handlers are supposed to "do something"
-before returning. One example can be CHLD or CLD which indicates a child process
-has completed. On some operating systems the signal handler is expected to C<wait>
-for the completed child process. On such systems the deferred signal scheme will
-not work for those signals (it does not do the C<wait>). Again the failure will
-look like a loop as the operating system will re-issue the signal as there are
-un-waited-for completed child processes.
+On some operating systems certain signal handlers are supposed to "do
+something" before returning. One example can be CHLD or CLD which
+indicates a child process has completed. On some operating systems the
+signal handler is expected to C<wait> for the completed child
+process. On such systems the deferred signal scheme will not work for
+those signals (it does not do the C<wait>). Again the failure will
+look like a loop as the operating system will re-issue the signal as
+there are un-waited-for completed child processes.
=back 4
=head1 Using open() for IPC
-Perl's basic open() statement can also be used for unidirectional interprocess
-communication by either appending or prepending a pipe symbol to the second
-argument to open(). Here's how to start something up in a child process you
-intend to write to:
+Perl's basic open() statement can also be used for unidirectional
+interprocess communication by either appending or prepending a pipe
+symbol to the second argument to open(). Here's how to start
+something up in a child process you intend to write to:
open(SPOOLER, "| cat -v | lpr -h 2>/dev/null")
|| die "can't fork: $!";