X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlipc.pod;h=f57cec706c1ff84d51952e4d5fa99a75292df873;hb=1109a39207d99bf49cb02471368620d4a38731b2;hp=c75fa958d09dca8687f63365e731d7c36540bc14;hpb=ca585e4dbaf85f4268cfbda9a6899be6dec77130;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlipc.pod b/pod/perlipc.pod index c75fa95..f57cec7 100644 --- a/pod/perlipc.pod +++ b/pod/perlipc.pod @@ -35,7 +35,7 @@ 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 in your handler could in theory trigger a memory fault and subsequent core -dump - see L below. +dump - see L below. The names of the signals are the ones listed out by C on your system, or you can retrieve them from the Config module. Set up an @@ -95,13 +95,22 @@ it doesn't kill itself): } Another interesting signal to send is signal number zero. This doesn't -actually affect another process, but instead checks whether it's alive +actually affect a child process, but instead checks whether it's alive or has changed its UID. unless (kill 0 => $kid_pid) { warn "something wicked happened to $kid_pid"; } +When directed at a process whose UID is not identical to that +of the sending process, signal number zero may fail because +you lack permission to send the signal, even though the process is alive. +You may be able to determine the cause of failure using C<%!>. + + unless (kill 0 => $pid or $!{EPERM}) { + warn "$pid looks dead"; + } + You might also want to employ anonymous functions for simple signal handlers: @@ -191,33 +200,33 @@ located in the subroutine C, 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"; @@ -279,7 +288,7 @@ to find out whether anyone (or anything) has accidentally removed our fifo. sleep 2; # to avoid dup signals } -=head2 Deferred Signals +=head2 Deferred Signals (Safe Signals) 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, @@ -340,6 +349,32 @@ 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. +Note that some networking library functions like gethostbyname() are +known to have their own implementations of timeouts which may conflict +with your timeouts. If you are having problems with such functions, +you can try using the POSIX sigaction() function, which bypasses the +Perl safe signals (note that this means subjecting yourself to +possible memory corruption, as described above). Instead of setting +C<$SIG{ALRM}> try something like the following: + + use POSIX; + sigaction SIGALRM, new POSIX::SigAction sub { die "alarm\n" } + or die "Error setting SIGALRM handler: $!\n"; + +=item Restartable system calls + +On systems that supported it, older versions of Perl used the +SA_RESTART flag when installing %SIG handlers. This meant that +restartable system calls would continue rather than returning when +a signal arrived. In order to deliver deferred signals promptly, +Perl 5.7.3 and later do I use SA_RESTART. Consequently, +restartable system calls can fail (with $! set to C) in places +where they previously would have succeeded. + +Note that the default C<:perlio> layer will retry C, C +and C as described above and that interrupted C and +C calls will always be retried. + =item Signals as "faults" Certain signals e.g. SEGV, ILL, BUS are generated as a result of @@ -368,6 +403,10 @@ there are un-waited-for completed child processes. =back +If you want the old signal behaviour back regardless of possible +memory corruption, set the environment variable C to +C<"unsafe"> (a new feature since Perl 5.8.1). + =head1 Using open() for IPC Perl's basic open() statement can also be used for unidirectional @@ -555,7 +594,7 @@ And here's a safe pipe open for writing: # add error processing as above $pid = open(KID_TO_WRITE, "|-"); - $SIG{ALRM} = sub { die "whoops, $program pipe broke" }; + $SIG{PIPE} = sub { die "whoops, $program pipe broke" }; if ($pid) { # parent for (@data) { @@ -991,7 +1030,7 @@ Here's a sample Unix-domain client: use strict; my ($rendezvous, $line); - $rendezvous = shift || '/tmp/catsock'; + $rendezvous = shift || 'catsock'; socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; connect(SOCK, sockaddr_un($rendezvous)) || die "connect: $!"; while (defined($line = )) { @@ -1012,7 +1051,7 @@ to be on the localhost, and thus everything works right. sub spawn; # forward declaration sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } - my $NAME = '/tmp/catsock'; + my $NAME = 'catsock'; my $uaddr = sockaddr_un($NAME); my $proto = getprotobyname('tcp'); @@ -1388,7 +1427,7 @@ Here's the code. We'll $client->autoflush(1); print $client "Welcome to $0; type help for command list.\n"; $hostinfo = gethostbyaddr($client->peeraddr); - printf "[Connect from %s]\n", $hostinfo->name || $client->peerhost; + printf "[Connect from %s]\n", $hostinfo ? $hostinfo->name : $client->peerhost; print $client "Command? "; while ( <$client>) { next unless /\S/; # blank line @@ -1571,7 +1610,7 @@ A small example demonstrating SysV message queues: my $id = msgget(IPC_PRIVATE, IPC_CREAT | S_IRWXU); my $sent = "message"; - my $type = 1234; + my $type_sent = 1234; my $rcvd; my $type_rcvd; @@ -1638,10 +1677,11 @@ version and suggestions from the Perl Porters. There's a lot more to networking than this, but this should get you started. -For intrepid programmers, the indispensable textbook is I by W. Richard Stevens (published by Addison-Wesley). Note -that most books on networking address networking from the perspective of -a C programmer; translation to Perl is left as an exercise for the reader. +For intrepid programmers, the indispensable textbook is I by W. Richard Stevens +(published by Prentice-Hall). Note that most books on networking +address the subject from the perspective of a C programmer; translation +to Perl is left as an exercise for the reader. The IO::Socket(3) manpage describes the object library, and the Socket(3) manpage describes the low-level interface to sockets. Besides the obvious