File-FDpasser
view release on metacpan or search on metacpan
FDpasser.pm view on Meta::CPAN
$rc=send_file($fh,*FH{IO});
$fh=endp_connect("/tmp/openserver") || die "endp_connect: $!\n";
$newfh=recv_fh($fh);
=head1 DESCRIPTION
File::FDpasser is a module for passing open filedescriptors
to and from other scripts or even other programs.
An endpoint is just a Filehandle that can be used to
send and receive filehandles over. To create two endpoints
before forking spipe() is used - it returns two endpoints
or undef on failiure.
If the processes are unrelated or can not use spipe() for
some reason, it is possible to create a 'server endpoint'
in the filesystem by calling endp_create(). That endpoint
can be polled for incomming connections similar to how sockets
are polled for incomming connection. To accept an incomming
connection serv_accept_fh() is used. It returns a filehandle
or undef on failiure.
To connect to a server endpoint from a client program
endp_connect() is used. It returns a filehandle to an
open connection.
Irregardless of how the endpoints were created send_file()
is used to send an open filehandle to the process who has
other end of the pipe or socket. The first argument to
send_file is the connection to send the open handle over.
The second argument is the actual handle to send.
Similarly recv_fh() is always used to receive an open
filehandle. Both return false on failiure.
=head1 How does it work
Under BSD derived systems open filedescriptors are passed over
unix domain sockets. SysV systems however pass them over streams.
This means to create that under BSD socketpair() is used to
create the socket endpoints. While SysV uses pipe() since
pipe on SysV creates a bidirectional stream based pipe.
This is all nice and dandy if you are going to fork later on
since both child and parent are going to have an endpoint to
read from or write to.
endp_create() is used to create a server endpoint that can
be polled for incomming connections with poll or select.
Under BSD the perl call socket() is used to create a Unix Domain
Socket in the filesystem. Under SysV the perl function pipe()
is called followed by an XS function that pushes the conn_ld module
on one end of the stream pipe and then calles fattach to attach
the pipe end to a point in the filesystem.
To connect to a server endpoint in BSD a socket is created (but not
bound to any point in the filesystem) and a connect call is made.
In SysV a normal open() in perl is made.
The actuall sending of filedescriptors is done with XS functions
that under BSD use sendmsg for sending and recvmsg for reciving.
SysV uses an ioctl call to send and receive (getmsg is actually
a wrapper for receiving the fd - a uid of the connecting process is
discarded since it's not reliably avaliable for BSD system too).
=head1 AUTHOR
}
if (write(clifd, buf, 2) != 2) return(-1);
if (fd >= 0) if (ioctl(clifd, I_SENDFD, fd) < 0) return(-1);
return(0);
}
/* Create a client endpoint and connect to a server.
* returns fd if all OK, <0 on error */
int
cli_conn(const char *name) {
int fd;
if ( (fd = open(name, O_RDWR)) < 0) return(-1); /* open the mounted stream */
if (isastream(fd) == 0) return(-2);
return(fd);
}
( run in 0.451 second using v1.01-cache-2.11-cpan-2b1a40005be )