IO::Handle::Record - IO::Handle extension to pass perl data structures
use IO::Socket::UNIX; use IO::Handle::Record; ($p, $c)=IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ); while( !defined( $pid=fork ) ) {sleep 1} if( $pid ) { close $c; undef $c; $p->fds_to_send=[\*STDIN, \*STDOUT]; $p->record_opts={send_CODE=>1}; $p->write_record( {a=>'b', c=>'d'}, sub { $_[0]+$_[1] }, [qw/this is a test/] ); } else { close $p; undef $p; $c->record_opts={receive_CODE=>sub {eval $_[0]}}; ($hashref, $coderef, $arrayref)=$c->read_record; readline $c->received_fds->[0]; # reads from the parent's STDIN }
IO::Handle::Record extends the IO::Handle class. Since many classes derive from IO::Handle these extensions can be used with IO::File, IO::Socket, IO::Pipe, etc.
IO::Handle::Record
IO::Handle
IO::File
IO::Socket
IO::Pipe
The methods provided read and write lists of perl data structures. They can pass anything that can be serialized with Storable even subroutines between processes.
Storable
The following methods are added:
This lvalue method expects a hash reference with options as parameter. The send_CODE and receive_CODE options correspond to localized versions of $Storable::Deparse and $Storable::Eval respectively. Using them Perl code can be passed over a connection. See the Storable manpage for further information.
send_CODE
receive_CODE
$Storable::Deparse
$Storable::Eval
Further, setting forgive_me sets $Storable::forgive_me before freeze()ing anything. That way GLOB values are stored as strings.
forgive_me
$Storable::forgive_me
freeze()
In a few cases IO::Handle::Record passes binary data over the connection. Normally network byte order is used there. You can save a few CPU cycles if you set the local_encoding option to true. In this case the byte order of the local machine is used.
local_encoding
Example:
$handle->record_opts={send_CODE=>1, receive_CODE=>1, local_encoding=>1};
Called before write_record sets a list of file handles that are passed to the other end of a UNIX domain stream socket. The next write_record transfers them as open files. So the other process can read or write to them.
write_record
This is the counterpart to fds_to_send. After a successful read_record the receiving process can fetch the transferred handles from this list. The handles are GLOBs blessed to one of:
fds_to_send
read_record
according to their type. IO::Handle is used as kind of catchall type. Open devices are received as such. IO::Handle::Record does not load all of these modules. That's up to you.
writes a list of perl data structures.
write_record returns 1 if the record has been transmitted. undef is returned if $handle is non blocking and a EAGAIN condition is met. In this case reinvoke the operation without parameters (just $handle->write_record) when the handle becomes ready. Otherwise it throws an exception IO::Handle::Record: syswrite error. Check $! in this case.
undef
$handle
$handle->write_record
IO::Handle::Record: syswrite error
$!
EINTR is handled internally.
$handle->write_record( [1,2], sub {$_[0]+$_[1]}, { list=>[1,2,3], hash=>{a=>'b'}, code=>sub {print "test\n";} } );
reads one record of perl data structures.
On success it returns the record as list. An empty list is returned if $handle is in non blocking mode and not enough data has been read. Check $!==EAGAIN to catch this condition. When the handle becomes ready just repeat the operation to read the next data chunk. If a complete record has arrived it is returned.
On EOF an empty list is returned. To distinguish this from the non blocking empty list return check $handle->end_of_input.
$handle->end_of_input
($array, $sub, $hash)=$handle->read_record;
When an end of file condition is read this is set to true.
ONLY FOR UNIX DOMAIN SOCKETS ON LINUX
Return the PID, eUID and eGID of the peer at the time of the connect.
these methods are used internally to provide a read and write buffer for non blocking operations.
IO::Handle::Record: sysread
thrown in read_record. Check $! for more information.
IO::Handle::Record: premature end of file
thrown in read_record on end of file if according to the internal protocol more input is expected.
IO::Handle::Record: busy
thrown in write_record if a non-blocking write is not yet finished. There may be only one write operation at a time. If that hits you organise a queue.
IO::Handle::Record: syswrite
thrown in write_record on an error of the underlying transport method. Check $! for more information.
Other exceptions
thrown in read_record and write_record if something cannot be encoded or decoded by the Storable module. If that hits you the Storable module at one side is probably too old.
None.
The Perl data is serialized using Storable::freeze or Storable::nfreeze. Storable::freeze is used if the local_encoding option is set, Storable::nfreeze otherwise.
The length in bytes of this data chunk and the number of file handles that are passed along with the data are then each pack()ed as a 4 byte binary value using the L or N template. L is used of local_encoding is in effect.
pack()
L
N
If there are file descriptors to be passed they are sent by a separate sendmsg call along with 2 length fields only.
Both fields is the prepended to the data chunk:
+-----------------+------------------------+ | data length (N) | number of file handles | | 4 bytes | 4 bytes | +-----------------+------------------------+ | | | | | | | | | data | | | | N bytes | | | | | | | | | | | +------------------------------------------+
WARNING: The transfer format has changed in version 0.07 (never made it to CPAN) and again in version 0.08.
Torsten Foertsch, <torsten.foertsch@gmx.net<gt>
Copyright (C) 2005-2009 by Torsten Foertsch
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install IO::Handle::Record, copy and paste the appropriate command in to your terminal.
cpanm
cpanm IO::Handle::Record
CPAN shell
perl -MCPAN -e shell install IO::Handle::Record
For more information on module installation, please visit the detailed CPAN module installation guide.