diff options
author | Eric Wong <e@80x24.org> | 2023-11-13 13:15:41 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-11-13 21:55:00 +0000 |
commit | 2d3699d2ce8cbee21485c8b31b1f681d2bb5def5 (patch) | |
tree | 675eea9a3c112b7cf584295cac2e62fae489c9c1 /lib/PublicInbox/IO.pm | |
parent | c560ab9e67476ce7b4438f8323d8ae9e775e790e (diff) | |
download | public-inbox-2d3699d2ce8cbee21485c8b31b1f681d2bb5def5.tar.gz |
read_all can be expanded to support FIFOs/pipes/sockets where read-until-EOF behavior is desired. We can also rely on wantarray to support splitting on EOL markers, but it's hard-coded to support only `$/ eq "\n"' since (AFAIK) it's the only way we use the wantarray form `readline'.
Diffstat (limited to 'lib/PublicInbox/IO.pm')
-rw-r--r-- | lib/PublicInbox/IO.pm | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/PublicInbox/IO.pm b/lib/PublicInbox/IO.pm index 0d303500..11ce9be1 100644 --- a/lib/PublicInbox/IO.pm +++ b/lib/PublicInbox/IO.pm @@ -62,13 +62,21 @@ sub poll_in ($;$) { IO::Poll::_poll($_[1] // -1, fileno($_[0]), my $ev = POLLIN); } -sub read_all ($;$$) { +sub read_all ($;$$$) { # pass $len=0 to read until EOF for :utf8 handles use autodie qw(read); - my ($io, $len, $bref) = @_; + my ($io, $len, $bref, $off) = @_; $bref //= \(my $buf); - my $r = read($io, $$bref, $len //= -s $io); - croak("read($io) ($r != $len)") if $len != $r; - $$bref; + $off //= 0; + my $r = 0; + if (my $left = $len //= -s $io) { # known size (binmode :raw/:unix) + do { # retry for binmode :unix + $r = read($io, $$bref, $left, $off += $r) or croak( + "read($io) premature EOF ($left/$len remain)"); + } while ($left -= $r); + } else { # read until EOF + while (($r = read($io, $$bref, 65536, $off += $r))) {} + } + wantarray ? split(/^/sm, $$bref) : $$bref } sub try_cat ($) { |