Document the UTF-8 env issue. Now NI-S just needs
[p5sagit/p5-mst-13.2.git] / pod / perlipc.pod
index 3535db4..2df556f 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
@@ -166,6 +168,68 @@ module.  Lamentably, this is almost entirely undocumented, but
 the F<t/lib/posix.t> file from the Perl source distribution has some
 examples in it.
 
+=head2 Handling the SIGHUP Signal in Daemons
+
+A process that usually starts when the system boots and shuts down
+when the system is shut down is called a daemon (Disk And Execution
+MONitor). If a daemon process has a configuration file which is
+modified after the process has been started, there should be a way to
+tell that process to re-read its configuration file, without stopping
+the process. Many daemons provide this mechanism using the C<SIGHUP>
+signal handler. When you want to tell the daemon to re-read the file
+you simply send it the C<SIGHUP> signal.
+
+Not all platforms automatically reinstall their (native) signal
+handlers after a signal delivery.  This means that the handler works
+only the first time the signal is sent. The solution to this problem
+is to use C<POSIX> signal handlers if available, their behaviour
+is well-defined.
+
+The following example implements a simple daemon, which restarts
+itself every time the C<SIGHUP> signal is received. The actual code is
+located in the subroutine C<code()>, which simply prints some debug
+info to show that it works and should be replaced with the real code.
+
+  #!/usr/bin/perl -w
+  
+  use POSIX ();
+  use FindBin ();
+  use File::Basename ();
+  use File::Spec::Functions;
+  
+  $|=1;
+  
+  # make the daemon cross-platform, so exec always calls the script
+  # itself with the right path, no matter how the script was invoked.
+  my $script = File::Basename::basename($0);
+  my $SELF = catfile $FindBin::Bin, $script;
+  
+  # POSIX unmasks the sigprocmask properly
+  my $sigset = POSIX::SigSet->new();
+  my $action = POSIX::SigAction->new('sigHUP_handler',
+                                     $sigset,
+                                     &POSIX::SA_NODEFER);
+  POSIX::sigaction(&POSIX::SIGHUP, $action);
+  
+  sub sigHUP_handler {
+      print "got SIGHUP\n";
+      exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
+  }
+  
+  code();
+  
+  sub code {
+      print "PID: $$\n";
+      print "ARGV: @ARGV\n";
+      my $c = 0;
+      while (++$c) {
+          sleep 2;
+          print "$c\n";
+      }
+  }
+  __END__
+
+
 =head1 Named Pipes
 
 A named pipe (often referred to as a FIFO) is an old Unix IPC
@@ -217,14 +281,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 +302,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
+=back
 
 =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: $!";