about summary refs log tree commit homepage
path: root/lib/PublicInbox/IO.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-11-13 13:15:41 +0000
committerEric Wong <e@80x24.org>2023-11-13 21:55:00 +0000
commit2d3699d2ce8cbee21485c8b31b1f681d2bb5def5 (patch)
tree675eea9a3c112b7cf584295cac2e62fae489c9c1 /lib/PublicInbox/IO.pm
parentc560ab9e67476ce7b4438f8323d8ae9e775e790e (diff)
downloadpublic-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.pm18
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 ($) {