=head1 NAME
-perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocceses, sockets, and semaphores)
+perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocesses, sockets, and semaphores)
=head1 DESCRIPTION
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 an another process, or
+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.
-Notice how all we do is set with a global variable and then raise an
+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, so calling any print() functions (or even anything that needs to
malloc(3) more memory) could in theory trigger a memory fault
But that will be problematic for the more complicated handlers that need
to re-install themselves. Because Perl's signal mechanism is currently
-based on the signal(3) function from the C library, you may somtimes be so
+based on the signal(3) function from the C library, you may sometimes be so
misfortunate as to run on systems where that function is "broken", that
is, it behaves in the old unreliable SysV way rather than the newer, more
reasonable BSD and POSIX fashion. So you'll see defensive people writing
or even the more elaborate:
- use POSIX "wait_h";
+ use POSIX ":wait_h";
sub REAPER {
my $child;
$SIG{CHLD} = \&REAPER; # loathe sysV
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 a child process you
+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")
next if /^(tcp|udp)/;
print;
}
- close SPOOLER || die "bad netstat: $! $?";
+ close STATUS || die "bad netstat: $! $?";
If one can be sure that a particular program is a Perl script that is
expecting filenames in @ARGV, the clever programmer can write something
Another common use for this construct is when you need to execute
something without the shell's interference. With system(), it's
-straigh-forward, but you can't use a pipe open or backticks safely.
+straightforward, but you can't use a pipe open or backticks safely.
That's because there's no way to stop the shell from getting its hands on
your arguments. Instead, use lower-level control to call exec() directly.
Note that these operations are full Unix forks, which means they may not be
correctly implemented on alien systems. Additionally, these are not true
multithreading. If you'd like to learn more about threading, see the
-F<modules> file mentioned below in the L<SEE ALSO> section.
+F<modules> file mentioned below in the SEE ALSO section.
=head2 Bidirectional Communication
program you're using. The F<Comm> library also has expect()
and interact() functions. Find the library (and hopefully its
successor F<IPC::Chat>) at your nearest CPAN archive as detailed
-in the L<SEE ALSO> section below.
+in the SEE ALSO section below.
=head1 Sockets: Client/Server Communication
While not limited to Unix-derived operating systems (e.g. WinSock on PCs
provides socket support, as do some VMS libraries), you may not have
-sockets on your system, in which this section probably isn't going to do
+sockets on your system, in which case this section probably isn't going to do
you much good. With sockets, you can do both virtual circuits (i.e. TCP
streams) and datagrams (i.e. UDP packets). You may be able to do even more
depending on your system.
inet_ntoa($iaddr), "]
at port $port";
- print CLIENT "Hello there, $name, it's now ",
+ print Client "Hello there, $name, it's now ",
scalar localtime, "\n";
}
my $port = shift || 2345;
my $proto = getprotobyname('tcp');
+ $port = $1 if $port =~ /(\d+)/; # untaint port number
+
socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,
pack("l", 1)) || die "setsockopt: $!";
=head2 Unix-Domain TCP Clients and Servers
-That's fine for Internet-domain clients and servers, but what local
+That's fine for Internet-domain clients and servers, but what about local
communications? While you can use the same setup, sometimes you don't
want to. Unix-domain sockets are local to the current host, and are often
used internally to implement pipes. Unlike Internet domain sockets, UNIX
die if !defined($key);
print "$key\n";
-Put this code in a separate file to be run in more that one process
+Put this code in a separate file to be run in more than one process.
Call the file F<take>:
# create a semaphore
semop($key,$opstring) || die "$!";
-Put this code in a separate file to be run in more that one process
+Put this code in a separate file to be run in more than one process.
Call this file F<give>:
# 'give' the semaphore
If you are running under version 5.000 (dubious) or 5.001, you can still
use most of the examples in this document. You may have to remove the
C<use strict> and some of the my() statements for 5.000, and for both
-you'll have to load in version 1.2 of the F<Socket.pm> module, which
-was/is/shall-be included in I<perl5.001o>.
+you'll have to load in version 1.2 or older of the F<Socket.pm> module, which
+is included in I<perl5.002>.
Most of these routines quietly but politely return C<undef> when they fail
instead of causing your program to die right then and there due to an
uncaught exception. (Actually, some of the new I<Socket> conversion
functions croak() on bad arguments.) It is therefore essential
-that you should check the return values fo these functions. Always begin
+that you should check the return values of these functions. Always begin
your socket programs this way for optimal success, and don't forget to add
B<-T> taint checking flag to the pound-bang line for servers:
elsewhere, Perl is at the mercy of your C libraries for much of its system
behaviour. It's probably safest to assume broken SysV semantics for
signals and to stick with simple TCP and UDP socket operations; e.g. don't
-try to pass open filedescriptors over a local UDP datagram socket if you
+try to pass open file descriptors over a local UDP datagram socket if you
want your code to stand a chance of being portable.
Because few vendors provide C libraries that are safely