Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • IPC::Run [cpan.org] does it by opening a pipe() to sync to the child, fork()ing, and marking it as close on exit with a fcntl(). Here are some snippets glued together from pieces of IPC::Run:
       ( $sync_reader_fd, $self->{SYNC_WRITER_FD} ) = _pipe ;
       $kid->{PID} = fork() ;
       croak "$! during fork" unless defined $kid->{PID} ;

       unless ( $kid->{PID} ) {
          eval {   
             open $s1, ">&=$self->{SYNC_WRITER_FD}"
                or croak "$! setting filehandle to fd SYNC_WRITER_FD" ;
             fcntl $s1, F_SETFD, 1 ;
             die "exec failed: simulating exec() failure"
                if $self->{_simulate_exec_failure} ;

             _exec $kid->{PATH}, @{$kid->{VAL}}[1..$#{$kid->{VAL}}] ;

             croak "exec failed: $!" ;
          } ;
          if ( $@ ) {
             _write $self->{SYNC_WRITER_FD}, $@ ;
          ## Avoid DESTROY.
             POSIX::exit 1  ;
          }
       }

       _debug "fork() = ", $kid->{PID} if _debugging_details ;

       ## Wait for kid to get to it's exec() and see if it fails.
       _close $self->{SYNC_WRITER_FD} ;
       my $sync_pulse = _read $sync_reader_fd ;
       _close $sync_reader_fd ;

       if ( ! defined $sync_pulse || length $sync_pulse ) {
          if ( waitpid( $kid->{PID}, 0 ) >= 0 ) {
             $kid->{RESULT} = $? ;
          }
          else {
             $kid->{RESULT} = -1 ;
          }
          $sync_pulse =
             "error reading synchronization pipe for $kid->{NUM}, pid $kid->{PID}"
             unless length $sync_pulse ;
          croak $sync_pulse ;
       }
       return $kid->{PID} ;

    - Barrie