Proc-Lite

 view release on metacpan or  search on metacpan

lib/Proc/Hevy/Reader.pm  view on Meta::CPAN

    or confess "$self->{name}: dup2: $!\n"
      if $std_h != $handle;
}

sub parent {
  my ( $self, $select ) = @_;

  unless( defined $self->{pipe} ) {
    delete $self->{buffer}
      if defined $self->{buffer};

    return;
  }

  $self->{scratch} = undef;

  my $handle = $self->{pipe}->reader;
  $handle->blocking( 0 );

  $select->add( $handle );
  $self->{select} = $select;

  return ( $handle, $self );
}

sub read {
  my ( $self ) = @_;

  my $handle = $self->{pipe};
  my $rc     = $handle->sysread( my $data, 4096 );

  if( not defined $rc ) {
    if( $! != EWOULDBLOCK ) {
      $self->_flush( $self->{scratch} );
      confess "$self->{name}: sysread: $!\n";
    }
  }
  elsif( $rc == 0 ) {
    $self->_flush( $self->{scratch} );

    $self->{select}->remove( $handle );
    $handle->close
      or confess "$self->{name}: close: $!\n";
  }
  else {
    $self->_pack( $data );
  }
}

sub _pack {
  my ( $self, $data ) = @_;

  if( ref $self->{buffer} eq 'SCALAR' ) {
    ${ $self->{buffer} } .= $data;
  }
  else {
    my $scratch = ( defined $self->{scratch} ? $self->{scratch} : '' ) . $data;

    if( defined $/ ) {
      while( index( $scratch, $/ ) != -1 ) {
        ( my $line, $scratch ) = split m#$/#, $scratch, 2;
        $self->_flush( $line );
      }
    }

    $self->{scratch} = length $scratch ? $scratch : undef;
  }
}

sub _flush {
  my ( $self, $data ) = @_;

  return
    unless defined $data;

  my $buffer = $self->{buffer};

  if( ref $buffer eq 'ARRAY' ) {
    push @$buffer, $data;
  }
  elsif( ref $buffer eq 'CODE' ) {
    $buffer->( $data );
  }
  else {
    confess "$self->{name}: API error\n";
  }
}


1
__END__

=pod

=head1 NAME

Proc::Hevy::Reader - A reader pipe implementation for Proc::Hevy

=head1 DESCRIPTION

Proc::Heavy::Reader implements a reader pipe that reads
data from a child process handle to a provided buffer.  This is
used when capturing C<STDOUT> and C<STDERR> data from a child process.

=head1 INTERFACE

=head2 new( $name, $buffer )

Creates a new C<Proc::Hevy::Reader> object.  C<$name> is a
symbolic name for the reader.  C<$buffer> is the storage mechanism
to be used for data read from the child process.  It can either
be a simple scalar, an C<ARRAY> reference, a C<CODE> reference or a
C<GLOB> reference.

=head2 child( $handle )

Performs actions suitable when running as part of the child process.
This includes re-opening the provided C<$handle> to a filehandle
that is created based on the type of storage buffer configured
in C<new()>.  If no buffer was configured, C<'/dev/null'> is
opened for writing.



( run in 2.207 seconds using v1.01-cache-2.11-cpan-71847e10f99 )