| Sprocket documentation | Contained in the Sprocket distribution. |
Sprocket::Util::FDpasser - Pass File Descripters using File::FDpasser
my $passer = Sprocket::Util::FDpasser->new(
EndpointFile => '/tmp/fdpasser',
Connect => 0
);
$passer->attach_hook( 'sprocket.fdpasser.accept', sub {
my $event = shift;
warn "received filehandle: $event->{fh}";
} );
# send a file handle
$passer->send_fd( *STDIN{IO} );
This module provides a session that watches File::FDpasser's filehandle for readability, and emits an event for received file handles.
This module is a subclass of Sprocket::Util::Observable and inherits all of its methods.
Create a new FD passer object
A path to an FDpasser endpoint.
Connect to (true) or create (false) the endpoint
Emitted on $self and $sprocket, in that order. $event->{fh} is the filehandle received.
David Davis <xantus@cpan.org>
Copyright 2006-2007 by David Davis
See Sprocket for license information.
| Sprocket documentation | Contained in the Sprocket distribution. |
package Sprocket::Util::FDpasser; use strict; use warnings; use Sprocket qw( Util::Observable ); use base qw( Sprocket::Util::Observable ); use Carp qw( croak ); use File::FDpasser; BEGIN { $sprocket->register_hook( 'sprocket.fdpasser.accept' ); } sub new { my $class = shift; croak "$class requires an even number of parameters" if @_ % 2; my %opts = &adjust_params; die "EndpointFile is mandatory for ".__PACKAGE__ unless ( $opts{endpoint_file} ); my $self = $class->SUPER::new( %opts ); if ( $opts{connect} ) { $self->{endpoint_fh} = endp_connect( $opts{endpoint_file} ) || die "Can't call File::FDpasser::endp_connect in ".__PACKAGE__.": $!\n"; } else { $self->{endpoint_fh} = endp_create( $opts{endpoint_file} ) || die "Can't call File::FDpasser::endp_create in ".__PACKAGE__.": $!\n"; # XXX eval { chmod( 0770, $opts{endpoint_file} ); }; } $self->register_hook( 'sprocket.fdpasser.accept' ); POE::Session->create( object_states => [ $self => [qw( _start endpoint_readable shutdown )] ] ); return $self; } sub _start { my ( $self, $kernel, $session ) = @_[ OBJECT, KERNEL, SESSION ]; $self->{session_id} = $session->ID; $kernel->select_read( $self->{endpoint_fh} => 'endpoint_readable' ); $sprocket->attach_hook( 'sprocket.shutdown', $sprocket->callback( $session => 'shutdown' ) ); return; } sub endpoint_readable { my ( $self, $kernel, $session ) = @_[ OBJECT, KERNEL ]; # XXX what is this uid for? my $uid = 0; my $sfh = serv_accept_fh( $self->{endpoint_fh}, $uid ); unless ( $sfh ) { warn "$!"; return; } my $fh = recv_fh( $sfh ); return unless ( $fh ); $self->broadcast( 'sprocket.fdpasser.accept', { source => $self, fh => $fh, } ); $sprocket->broadcast( 'sprocket.fdpasser.accept', { source => $self, fh => $fh, } ); return; } sub send_fd { my ( $self, $fh ) = @_; return send_file( $self->{endpoint_fh}, $fh ); } sub shutdown { my $self = shift; $poe_kernel->select_read( $self->{endpoint_fh} ) if ( $self->{endpoint_fh} ); return; } 1; __END__