Re: [PATCH] Attempt at improving the perlipc docs

[email protected] (Maik Hentsche)
Newsgroups perl.perl5.porters
Message-ID <[email protected]>
Hi,
after being back from vacation I see no further improvement suggestions
for my doc patch. I implemented those I did receive before. Please find
the updated patch attached. It applies to the current git HEAD. For
those of you who do not fully remember the topic here comes a
description of the issue I'm trying to solve.

I was recently confused by the way signal handlers using wait() behave
in collaboration with qx() or system().

When you have a signal handler for SIGCHLD that calls wait() and use
qx() or system() in your parent, the signal handler will be called.
Yet, because qx/system already wait()ed for their child the wait in the
signal handler would block. I doubt everyone will understand this in
the first place. Thus, I wrote an improvement for the documentation to
tell people about this issue.

so long
Maik

-- 
Maik Hentsche <[email protected]>
Tel.:0177/6875926

http://chemnitzer.linux-tage.de
0001-Improve-documentation-for-SIGCHLD-handling.patch (text/x-patch, 2.3 KB)
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index ccffcdb..69cc64a 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -6747,6 +6747,10 @@ When C<system>'s arguments are executed indirectly by the shell,
 results and return codes are subject to its quirks.
 See L<perlop/"`STRING`"> and L</exec> for details.
 
+Since C<system> does a C<fork> and C<wait> it may affect C<SIGCHLD> handler.
+See L<perlipc> for details.
+
+
 =item syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
 X<syswrite>
 
@@ -7606,6 +7610,9 @@ and C<${^CHILD_ERROR_NATIVE}>.
 Note that a return value of C<-1> could mean that child processes are
 being automatically reaped, as described in L<perlipc>.
 
+If you use wait in your handler for $SIG{CHLD} it may accidently wait for the
+child created by qx() or system(). See L<perlipc> for details.
+
 =item waitpid PID,FLAGS
 X<waitpid>
 
diff --git a/pod/perlipc.pod b/pod/perlipc.pod
index 4f6c0f0..319989d 100644
--- a/pod/perlipc.pod
+++ b/pod/perlipc.pod
@@ -150,6 +150,42 @@ or better still:
     $SIG{CHLD} = \&REAPER;
     # do something that forks...
 
+Note: qx(), system() and some modules for calling external commands do a
+fork() and wait() for the result. Thus, your signal handler (REAPER in the
+example) will be called. Since wait() was already called by system() or qx()
+the wait() in the signal handler will not see any more zombies and therefore
+block.
+
+The best way to prevent this issue is to use waitpid as in the following 
+example.
+
+    use POSIX ":sys_wait_h"; # for nonblocking read
+
+    my %children;
+
+    $SIG{CHLD} = sub {
+    # don't change $! and $? outside handler
+            local ($!,$?);
+            my $pid = waitpid(-1, WNOHANG);
+            return if $pid == -1;
+        return unless defined $children{$pid};
+        delete $children{$pid};
+            cleanup_child($pid, $?);
+    };
+
+    while(1){
+            my $pid = fork();
+            if ($pid == 0){
+                ...
+                exit 0;
+            } else {
+            $children{$pid}=1;
+                ...
+                system($command);
+                ...
+           }
+    }
+
 Signal handling is also used for timeouts in Unix,   While safely
 protected within an C<eval{}> block, you set a signal handler to trap
 alarm signals and then schedule to have one delivered to you in some
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.