Integrate with Sarathy.
[p5sagit/p5-mst-13.2.git] / pod / perlipc.pod
index 09b011e..e687304 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()
@@ -266,7 +276,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 +307,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 +326,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 *
+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: $!";
+    }
 
-Ignore hangup signals in case you're running on a shell that doesn't
-automatically no-hup you:
+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.
 
-    $SIG{HUP} = 'IGNORE';      # or whatever you'd like
-
-=back
+Non-Unix users should check their Your_OS::Process module for other
+solutions.
 
 =head2 Safe Pipe Opens
 
@@ -476,7 +472,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>;
 
@@ -506,6 +501,12 @@ and interact() functions.  Find the library (and we hope its
 successor F<IPC::Chat>) at your nearest CPAN archive as detailed
 in the SEE ALSO section below.
 
+The newer Expect.pm module from CPAN also addresses this kind of thing.
+This module requires two other modules from CPAN: IO::Pty and IO::Stty.
+It sets up a pseudo-terminal to interact with programs that insist on
+using talking to the terminal device driver.  If your system is 
+amongst those supported, this may be your best bet.
+
 =head2 Bidirectional Communication with Yourself
 
 If you want, you may make low-level pipe() and fork()
@@ -1156,7 +1157,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
@@ -1188,7 +1189,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
 
@@ -1300,29 +1301,33 @@ you weren't wanting it to.
 
 Here's a small example showing shared memory usage.
 
-    $IPC_PRIVATE = 0;
-    $IPC_RMID = 0;
+    use IPC::SysV qw(IPC_PRIVATE IPC_RMID S_IRWXU S_IRWXG S_IRWXO);
+
     $size = 2000;
-    $key = shmget($IPC_PRIVATE, $size , 0777 );
-    die unless defined $key;
+    $key = shmget(IPC_PRIVATE, $size, S_IRWXU|S_IRWXG|S_IRWXO) || die "$!";
+    print "shm key $key\n";
 
     $message = "Message #1";
-    shmwrite($key, $message, 0, 60 ) || die "$!";
-    shmread($key,$buff,0,60) || die "$!";
+    shmwrite($key, $message, 0, 60) || die "$!";
+    print "wrote: '$message'\n";
+    shmread($key, $buff, 0, 60) || die "$!";
+    print "read : '$buff'\n";
 
-    print $buff,"\n";
+    # the buffer of shmread is zero-character end-padded.
+    substr($buff, index($buff, "\0")) = '';
+    print "un" unless $buff eq $message;
+    print "swell\n";
 
-    print "deleting $key\n";
-    shmctl($key ,$IPC_RMID, 0) || die "$!";
+    print "deleting shm $key\n";
+    shmctl($key, IPC_RMID, 0) || die "$!";
 
 Here's an example of a semaphore:
 
+    use IPC::SysV qw(IPC_CREAT);
+
     $IPC_KEY = 1234;
-    $IPC_RMID = 0;
-    $IPC_CREATE = 0001000;
-    $key = semget($IPC_KEY, $nsems , 0666 | $IPC_CREATE );
-    die if !defined($key);
-    print "$key\n";
+    $key = semget($IPC_KEY, 10, 0666 | IPC_CREAT ) || die "$!";
+    print "shm key $key\n";
 
 Put this code in a separate file to be run in more than one process.
 Call the file F<take>:
@@ -1369,9 +1374,8 @@ Call this file F<give>:
     semop($key,$opstring) || die "$!";
 
 The SysV IPC code above was written long ago, and it's definitely
-clunky looking.  It should at the very least be made to C<use strict>
-and C<require "sys/ipc.ph">.  Better yet, check out the IPC::SysV modules
-on CPAN.
+clunky looking.  For a more modern look, see the IPC::SysV module
+which is included with Perl starting from Perl 5.005.
 
 =head1 NOTES