FU: Implement --monitor, add some docs; FU::Util: add fdpass functions

This commit is contained in:
Yorhel 2025-02-15 14:58:00 +01:00
parent 09fe50d2a2
commit 3e84a4f4d3
8 changed files with 480 additions and 99 deletions

View file

@ -4,7 +4,10 @@ use v5.36;
use FU::XS;
use Exporter 'import';
our @EXPORT_OK = qw/json_format json_parse/;
our @EXPORT_OK = qw/
json_format json_parse
fdpass_send fdpass_recv
/;
1;
__END__
@ -150,3 +153,45 @@ unnecessary features and C<#ifdef>s to support ancient perls and esoteric
configurations. Still, if you need anything not provided by these functions,
L<JSON::PP> and L<Cpanel::JSON::XS> are perfectly fine alternatives.
L<JSON::SIMD> and L<Mojo::JSON> also look like good and maintained candidates.)
=head2 File Descriptor Passing
UNIX sockets (see L<IO::Socket::UNIX>) have the fancy property of letting you
send file descriptors over them, allowing you to pass, for example, a socket
from one process to another. This is a pretty low-level operation and not
something you'll often need, but two functions to use that feature are provided
here anyway because the L<FU> supervisor uses them:
=over
=item fdpass_send($send_fd, $pass_fd, $message)
Send a message and a file descriptor (C<$pass_fd>) over the given socket
(<$send_fd>). C<$message> must not be empty, even if you don't intend to do
anything with it on receipt. Both C<$send_fd> and C<$pass_fd> must be numeric
file descriptors, as obtained by C<fileno()>.
=item ($fd, $message) = fdpass_recv($recv_fd, $max_message_len)
Read a file descriptor and message from the given C<$recv_fd>, which must be
the numeric file descriptor of a socket. This function can be used as a
replacement for C<sysread()>: the returned C<$fd> is undef if no file
descriptor was received. The returned C<$message> is undef on error or an empty
string on EOF.
Like regular socket I/O, a single C<fdpass_send()> message may be split across
multiple C<fdpass_recv()> calls; in that case the C<$fd> will only be received
on the first call.
Don't use this function if the sender may include multiple file descriptors in
a single message, weird things can happen. File descriptors received this way
do not have the C<CLOEXEC> flag and will thus survive a call to C<exec()>.
Refer to L<this wonderful
discussion|https://gist.github.com/kentonv/bc7592af98c68ba2738f4436920868dc>
for more weirdness and edge cases.
=back
See also L<IO::FDPass> for a more portable solution, although that one does not
support passing along regular data.