| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | =head1 NAME | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | IO::FDPass - pass a file descriptor over a socket | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | use IO::FDPass; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | IO::FDPass::send fileno $socket, fileno $fh_to_pass | 
| 10 |  |  |  |  |  |  | or die "send failed: $!"; | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | my $fd = IO::FDPass::recv fileno $socket; | 
| 13 |  |  |  |  |  |  | $fd >= 0 or die "recv failed: $!"; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | This small low-level module only has one purpose: pass a file descriptor | 
| 18 |  |  |  |  |  |  | to another process, using a (streaming) unix domain socket (on POSIX | 
| 19 |  |  |  |  |  |  | systems) or any (streaming) socket (on WIN32 systems). The ability to pass | 
| 20 |  |  |  |  |  |  | file descriptors on windows is currently the unique selling point of this | 
| 21 |  |  |  |  |  |  | module. Have I mentioned that it is really small, too? | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | =over 4 | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | =cut | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | package IO::FDPass; | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | BEGIN { | 
| 32 | 3 |  |  | 3 |  | 7764 | $VERSION = 1.2; | 
| 33 |  |  |  |  |  |  |  | 
| 34 | 3 |  |  |  |  | 12 | require XSLoader; | 
| 35 | 3 |  |  |  |  | 946 | XSLoader::load (__PACKAGE__, $VERSION); | 
| 36 |  |  |  |  |  |  | } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | =item $bool = IO::FDPass::send $socket_fd, $fd_to_pass | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | Sends the file descriptor given by C<$fd_to_pass> over the socket | 
| 41 |  |  |  |  |  |  | C<$socket_fd>. Return true if it worked, false otherwise. | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | Note that I parameters must be file descriptors, not handles. | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | When used on non-blocking sockets, this function might fail with C<$!> | 
| 46 |  |  |  |  |  |  | set to C or equivalent, in which case you are free to try. It | 
| 47 |  |  |  |  |  |  | should succeed if called on a socket that indicates writability (e.g. via | 
| 48 |  |  |  |  |  |  | C | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | Example: pass a file handle over an open socket. | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | IO::FDPass::send fileno $socket, fileno $fh | 
| 53 |  |  |  |  |  |  | or die "unable to pass file handle: $!"; | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | =item $fd = IO::FDPass::recv $socket_fd | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | Receive a file descriptor from the socket and return it if successful. On | 
| 58 |  |  |  |  |  |  | errors, return C<-1>. | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | Note that I C<$socket_fd> and the returned file descriptor are, in | 
| 61 |  |  |  |  |  |  | fact, file descriptors, not handles. | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | When used on non-blocking sockets, this function might fail with C<$!> set | 
| 64 |  |  |  |  |  |  | to C or equivalent, in which case you are free to try again. It | 
| 65 |  |  |  |  |  |  | should succeed if called on a socket that indicates readability (e.g. via | 
| 66 |  |  |  |  |  |  | C | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | Example: receive a file descriptor from a blocking socket and convert it | 
| 69 |  |  |  |  |  |  | to a file handle. | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | my $fd = IO::FDPass::recv fileno $socket; | 
| 72 |  |  |  |  |  |  | $fd >= 0 or die "unable to receive file handle: $!"; | 
| 73 |  |  |  |  |  |  | open my $fh, "+<&=$fd" | 
| 74 |  |  |  |  |  |  | or die "unable to convert file descriptor to handle: $!"; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | =back | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | =head1 PORTABILITY NOTES | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | This module has been tested on GNU/Linux x86 and amd64, NetBSD 6, OS X | 
| 81 |  |  |  |  |  |  | 10.5, Windows 2000 ActivePerl 5.10, Solaris 10, OpenBSD 4.4, 4.5, 4.8 and | 
| 82 |  |  |  |  |  |  | 5.0, DragonFly BSD, FreeBSD 7, 8 and 9, Windows 7 + ActivePerl 5.16.3 32 | 
| 83 |  |  |  |  |  |  | and 64 bit and Strawberry Perl 5.16.3 32 and 64 bit, and found to work, | 
| 84 |  |  |  |  |  |  | although ActivePerl 32 bit needed a newer MinGW version (that supports XP | 
| 85 |  |  |  |  |  |  | and higher). | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | However, windows doesn't support asynchronous file descriptor passing, so | 
| 88 |  |  |  |  |  |  | the source process must still be around when the destination process wants | 
| 89 |  |  |  |  |  |  | to receive the file handle. Also, if the target process fails to fetch the | 
| 90 |  |  |  |  |  |  | handle for any reason (crashes, fails to call C etc.), the handle | 
| 91 |  |  |  |  |  |  | will leak, so never do that. | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | Also, on windows, the receiving process must have the PROCESS_DUP_HANDLE | 
| 94 |  |  |  |  |  |  | access right on the sender process for this module to work. | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | Cygwin is not supported at the moment, as file descriptor passing in | 
| 97 |  |  |  |  |  |  | cygwin is not supported, and cannot be rolled on your own as cygwin has no | 
| 98 |  |  |  |  |  |  | (working) method of opening a handle as fd. That is, it has one, but that | 
| 99 |  |  |  |  |  |  | one isn't exposed to programs, and only used for stdin/out/err. Sigh. | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | =head1 OTHER MODULES | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | At the time of this writing, the author of this module was aware of two | 
| 104 |  |  |  |  |  |  | other file descriptor passing modules on CPAN: L and | 
| 105 |  |  |  |  |  |  | L. | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | The former hasn't seen any release for over a decade, isn't 64 bit clean | 
| 108 |  |  |  |  |  |  | and it's author didn't respond to my mail with the fix, so doesn't work on | 
| 109 |  |  |  |  |  |  | many 64 bit machines. It does, however, support a number of pre-standard | 
| 110 |  |  |  |  |  |  | unices, basically everything of relevance at the time it was written. | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | The latter seems to have similar support for antique unices, and doesn't | 
| 113 |  |  |  |  |  |  | seem to suffer from 64 bit bugs, but inexplicably has a large perl | 
| 114 |  |  |  |  |  |  | part, doesn't support mixing data and file descriptors, and requires | 
| 115 |  |  |  |  |  |  | AnyEvent. Presumably that makes it much more user friendly than this | 
| 116 |  |  |  |  |  |  | module (skimming the manpage shows that a lot of thought has gone into | 
| 117 |  |  |  |  |  |  | it, and you are well advised to read it and maybe use it before trying a | 
| 118 |  |  |  |  |  |  | low-level module such as this one). In fact, the manpage discusses even | 
| 119 |  |  |  |  |  |  | more file descriptor passing modules on CPAN. | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | Neither seems to support native win32 perls. | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | =head1 AUTHOR | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | Marc Lehmann | 
| 126 |  |  |  |  |  |  | http://home.schmorp.de/ | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | =cut | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | 1 | 
| 131 |  |  |  |  |  |  |  |