Merijn Broeren wrote:

>Hello,
>
>This simple program exhibits the difference in behaviour between 0.32
>and 0.31 :
>
>    use POE;
>
>    my $rc = system("/bin/true");
>
>    if ($rc == -1) {
>        print "failed to execute: $!\n";
>    } else {
>        print "executed just fine\n";
>    }
>
>Reading perldoc perlvar on $?:
>
>   If you have installed a signal handler for "SIGCHLD", the value of $?
>   will usually be wrong outside that handler.
>
>This happens because the import of POE.pm does an eval of use POE::Kernel.
>Its import in turn executes a POE::Kernel::->new, which then does
>amongst much other stuff a $self->_data_sig_initialize(); Which calls
>loop_ignore_signal. This has changed between 0.31 and 0.32 :
>
>@@ -53,6 +53,7 @@
>
>   # Child process has stopped.
>   if ($signal eq 'CHLD' or $signal eq 'CLD') {
>+    $SIG{$signal} = "DEFAULT";
>     $self->_data_sig_begin_polling();
>     return;
>   }
>@@ -72,6 +73,13 @@
>
>   if ($signal eq 'CHLD' or $signal eq 'CLD') {
>     $self->_data_sig_cease_polling();
>+    $SIG{$signal} = "IGNORE";
>+    return;
>+  }
>+
>+  if ($signal eq 'PIPE') {
>+    $SIG{$signal} = "IGNORE";
>+    return;
>   }
>
>   $SIG{$signal} = "DEFAULT";
>
>So effectivelly all system calls in POE programs that want to check the
>result status of their calls cannot do so anymore directly. Or you have
>to install a SIGCHLD handler yourself. Much of our code has the above 
>idiom, where we check immediately. Much unhappiness with 0.32 as it
>returns -1 now. 
>
>Is this a desired change in behaviour? 
>
>Cheers,
>  
>
As a side note though, I just threw this bit of code together that
should make the concept of a system() call safe under POE.

DISCLAIMER: This code will attract the attention of ninjas and pirates.
Expect to be in the middle of something bad if you use it.

sub mysystem {
        my $command = shift;
        my $return;

        {
                local $SIG{CHLD} = "DEFAULT";
                $return = system( $command );
        }

        ref( $SIG{CHLD} ) eq 'CODE' and $SIG{CHLD}->();
        return $return;
}

mysystem( 'command' );

Adjust as necessary.

--Jonathan

Reply via email to