Slight reformatting; tiny tweaks.
Jarkko Hietaniemi [Sun, 26 May 2002 15:18:27 +0000 (15:18 +0000)]
p4raw-id: //depot/perl@16796

pod/perlipc.pod

index 3535db4..58e063f 100644 (file)
@@ -10,14 +10,14 @@ IPC calls.  Each is used in slightly different situations.
 
 =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:
 
@@ -29,11 +29,13 @@ 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
@@ -217,14 +219,15 @@ to find out whether anyone (or anything) has accidentally removed our fifo.
 
 =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
@@ -237,66 +240,78 @@ The pragmatic approach was to say ``I know the risks, but prefer the
 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: $!";