move the big AVAILABILITY list to perlport as Supported Platforms
[p5sagit/p5-mst-13.2.git] / pod / perlipc.pod
index 59c5ad9..a9c7e48 100644 (file)
@@ -56,7 +56,17 @@ So to check whether signal 17 and SIGALRM were the same, do just this:
 
 You may also choose to assign the strings C<'IGNORE'> or C<'DEFAULT'> as
 the handler, in which case Perl will try to discard the signal or do the
-default thing.  Some signals can be neither trapped nor ignored, such as
+default thing.
+
+On most Unix platforms, the C<CHLD> (sometimes also known as C<CLD>) signal
+has special behavior with respect to a value of C<'IGNORE'>.
+Setting C<$SIG{CHLD}> to C<'IGNORE'> on such a platform has the effect of
+not creating zombie processes when the parent process fails to C<wait()>
+on its child processes (i.e. child processes are automatically reaped).
+Calling C<wait()> with C<$SIG{CHLD}> set to C<'IGNORE'> usually returns
+C<-1> on such platforms.
+
+Some signals can be neither trapped nor ignored, such as
 the KILL and STOP (but not the TSTP) signals.  One strategy for
 temporarily ignoring signals is to use a local() statement, which will be
 automatically restored once your block is exited.  (Remember that local()
@@ -116,7 +126,7 @@ or even the more elaborate:
     use POSIX ":sys_wait_h";
     sub REAPER {
        my $child;
-        while ($child = waitpid(-1,WNOHANG)) {
+        while (($child = waitpid(-1,WNOHANG)) > 0) {
            $Kid_Status{$child} = $?;
        }
        $SIG{CHLD} = \&REAPER;  # still loathe sysV
@@ -142,6 +152,10 @@ Here's an example:
     };
     if ($@ and $@ !~ /alarm clock restart/) { die }
 
+If the operation being timed out is system() or qx(), this technique
+is liable to generate zombies.    If this matters to you, you'll
+need to do your own fork() and exec(), and kill the errant child process.
+
 For more complex signal handling, you might see the standard POSIX
 module.  Lamentably, this is almost entirely undocumented, but
 the F<t/lib/posix.t> file from the Perl source distribution has some
@@ -266,7 +280,7 @@ same effect as opening a pipe for reading:
 
 While this is true on the surface, it's much more efficient to process the
 file one line or record at a time because then you don't have to read the
-whole thing into memory at once. It also gives you finer control of the
+whole thing into memory at once.  It also gives you finer control of the
 whole process, letting you to kill off the child process early if you'd
 like.
 
@@ -297,8 +311,7 @@ To catch it, you could use this:
 
 Both the main process and any child processes it forks share the same
 STDIN, STDOUT, and STDERR filehandles.  If both processes try to access
-them at once, strange things can happen.  You'll certainly want to any
-stdio flush output buffers before forking.  You may also want to close
+them at once, strange things can happen.  You may also want to close
 or reopen the filehandles for the child.  You can get around this by
 opening your pipe with open(), but on some systems this means that the
 child process cannot outlive the parent.
@@ -317,46 +330,33 @@ details).
 =head2 Complete Dissociation of Child from Parent
 
 In some cases (starting server processes, for instance) you'll want to
-complete dissociate the child process from the parent.    The easiest 
-way is to use:
-
-    use POSIX qw(setsid);
-    setsid()           or die "Can't start a new session: $!";
-
-However, you may not be on POSIX.  The following process is reported
-to work on most Unixish systems.  Non-Unix users should check their
-Your_OS::Process module for other solutions.
-
-=over 4
-
-=item *
-
-Open /dev/tty and use the TIOCNOTTY ioctl on it.  See L<tty(4)>
-for details.
-
-=item *
-
-Change directory to /
-
-=item *
-
-Reopen STDIN, STDOUT, and STDERR so they're not connected to the old
-tty.
-
-=item *
-
-Background yourself like this:
-
-    fork && exit;
-
-=item *
-
-Ignore hangup signals in case you're running on a shell that doesn't
-automatically no-hup you:
+completely dissociate the child process from the parent.  This is
+often called daemonization.  A well behaved daemon will also chdir()
+to the root directory (so it doesn't prevent unmounting the filesystem
+containing the directory from which it was launched) and redirect its
+standard file descriptors from and to F</dev/null> (so that random
+output doesn't wind up on the user's terminal).
+
+    use POSIX 'setsid';
+
+    sub daemonize {
+       chdir '/'               or die "Can't chdir to /: $!";
+       open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
+       open STDOUT, '>/dev/null'
+                               or die "Can't write to /dev/null: $!";
+       defined(my $pid = fork) or die "Can't fork: $!";
+       exit if $pid;
+       setsid                  or die "Can't start a new session: $!";
+       open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+    }
 
-    $SIG{HUP} = 'IGNORE';      # or whatever you'd like
+The fork() has to come before the setsid() to ensure that you aren't a
+process group leader (the setsid() will fail if you are).  If your
+system doesn't have the setsid() function, open F</dev/tty> and use the
+C<TIOCNOTTY> ioctl() on it instead.  See L<tty(4)> for details.
 
-=back
+Non-Unix users should check their Your_OS::Process module for other
+solutions.
 
 =head2 Safe Pipe Opens
 
@@ -453,8 +453,8 @@ doesn't actually work:
 
     open(PROG_FOR_READING_AND_WRITING, "| some program |")
 
-and if you forget to use the B<-w> flag, then you'll miss out
-entirely on the diagnostic message:
+and if you forget to use the C<use warnings> pragma or the B<-w> flag,
+then you'll miss out entirely on the diagnostic message:
 
     Can't do bidirectional pipe at -e line 1.
 
@@ -476,7 +476,6 @@ Here's an example of using open2():
     use FileHandle;
     use IPC::Open2;
     $pid = open2(*Reader, *Writer, "cat -u -n" );
-    Writer->autoflush(); # default here, actually
     print Writer "stuff\n";
     $got = <Reader>;
 
@@ -1025,7 +1024,7 @@ something to the server before fetching the server's response.
 The web server handing the "http" service, which is assumed to be at
 its standard port, number 80.  If your the web server you're trying to
 connect to is at a different port (like 1080 or 8080), you should specify
-as the named-parameter pair, C<PeerPort =E<gt> 8080>.  The C<autoflush>
+as the named-parameter pair, C<< PeerPort => 8080 >>.  The C<autoflush>
 method is used on the socket because otherwise the system would buffer
 up the output we sent it.  (If you're on a Mac, you'll also need to
 change every C<"\n"> in your code that sends data over the network to
@@ -1143,7 +1142,7 @@ well.
 As always, setting up a server is little bit more involved than running a client.
 The model is that the server creates a special kind of socket that
 does nothing but listen on a particular port for incoming connections.
-It does this by calling the C<IO::Socket::INET-E<gt>new()> method with
+It does this by calling the C<< IO::Socket::INET->new() >> method with
 slightly different arguments than the client did.
 
 =over
@@ -1162,7 +1161,7 @@ server. (Under Unix, ports under 1024 are restricted to the
 superuser.)  In our sample, we'll use port 9000, but you can use
 any port that's not currently in use on your system.  If you try
 to use one already in used, you'll get an "Address already in use"
-message. Under Unix, the C<netstat -a> command will show
+message.  Under Unix, the C<netstat -a> command will show
 which services current have servers.
 
 =item Listen
@@ -1194,7 +1193,7 @@ you'll have to use the C<sysread> variant of the interactive client above.
 This server accepts one of five different commands, sending output
 back to the client.  Note that unlike most network servers, this one
 only handles one incoming client at a time.  Multithreaded servers are
-covered in Chapter 6 of the Camel as well as later in this manpage.
+covered in Chapter 6 of the Camel.
 
 Here's the code.  We'll