]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
treewide: update read_all to avoid eof|close checks
authorEric Wong <e@80x24.org>
Mon, 13 Nov 2023 13:15:41 +0000 (13:15 +0000)
committerEric Wong <e@80x24.org>
Mon, 13 Nov 2023 21:55:00 +0000 (21:55 +0000)
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'.

lib/PublicInbox/CodeSearchIdx.pm
lib/PublicInbox/Gcf2.pm
lib/PublicInbox/IO.pm
lib/PublicInbox/LeiInput.pm
lib/PublicInbox/LeiMirror.pm
lib/PublicInbox/LeiToMail.pm
lib/PublicInbox/Spawn.pm
lib/PublicInbox/TestCommon.pm
script/public-inbox-learn
script/public-inbox-mda
script/public-inbox-purge

index ffd443e15ab04252f99a33a06e31a6ec65984a92..3601176c4b746fddf1f11ae01ec34c9cc6ba2e7b 100644 (file)
@@ -627,8 +627,7 @@ sub index_repo { # run_git cb
        my $repo = delete $git->{-repo} or return index_next($self);
        my $roots_fh = delete $repo->{roots_fh} // die 'BUG: no {roots_fh}';
        seek($roots_fh, 0, SEEK_SET);
-       chomp(my @roots = <$roots_fh>);
-       $roots_fh = eof($roots_fh) | close $roots_fh; # detect readline errors
+       chomp(my @roots = PublicInbox::IO::read_all $roots_fh);
        if (!@roots) {
                warn("E: $git->{git_dir} has no root commits\n");
                return index_next($self);
index 5490049d485b61b7a4d6bf0f3d450f1d4cc70c13..e0219b5559c2607c40b28998ceb91e5709be0286 100644 (file)
@@ -81,8 +81,7 @@ sub add_alt ($$) {
        #
        # See https://bugs.debian.org/975607
        if (open(my $fh, '<', "$objdir/info/alternates")) {
-               chomp(my @abs_alt = grep(m!^/!, <$fh>));
-               $fh = eof($fh) | close $fh; # detect readline errors
+               chomp(my @abs_alt = grep m!^/!, PublicInbox::IO::read_all $fh);
                $gcf2->add_alternate($_) for @abs_alt;
        }
        $gcf2->add_alternate($objdir);
index 0d30350049452d3f186b61c8192effb50a68f7bf..11ce9be1d4ccffa9a9c289c2e13ba1f5798837fe 100644 (file)
@@ -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 ($) {
index 68c3c4598da30b3d4c0161edb053e13a59201866..daba9a8ee7e53b760c3a9ca6b9d2144ad3298576 100644 (file)
@@ -79,12 +79,10 @@ sub input_net_cb { # imap_each, nntp_each cb
 sub input_fh {
        my ($self, $ifmt, $fh, $name, @args) = @_;
        if ($ifmt eq 'eml') {
-               my $buf = do { local $/; <$fh> };
-               my $ok = defined($buf) ? 1 : 0;
-               ++$ok if eof($fh);
-               ++$ok if $fh->close;
-               $ok == 3 or return $self->{lei}->child_error($?, <<"");
-error reading $name: $! (\$?=$?)
+               my $buf = eval { PublicInbox::IO::read_all $fh, 0 };
+               my $e = $@;
+               return $self->{lei}->child_error($?, <<"") if !$fh->close || $e;
+error reading $name: $! (\$?=$?) (\$@=$e)
 
                PublicInbox::Eml::strip_from($buf);
 
index 84266d03bcb2a69700b320d17261cff00633c8a9..e048a8070b8147f26c30415ae65c0d83f2e3c524 100644 (file)
@@ -307,10 +307,9 @@ sub fgrp_update {
        my $dstfh = delete $fgrp->{dstfh} or return;
        seek($srcfh, 0, SEEK_SET);
        seek($dstfh, 0, SEEK_SET);
-       my %src = map { chomp; split(/\0/) } (<$srcfh>);
-       my %dst = map { chomp; split(/\0/) } (<$dstfh>);
-       $srcfh = eof($srcfh) | close $srcfh; # detects readline errors
-       $dstfh = eof($dstfh) | close $dstfh; # ditto
+       my %src = map { chomp; split /\0/ } PublicInbox::IO::read_all $srcfh;
+       my %dst = map { chomp; split /\0/ } PublicInbox::IO::read_all $dstfh;
+       $srcfh = $dstfh = undef;
        my $w = start_update_ref($fgrp) or return;
        my $lei = $fgrp->{lei};
        my $ndel;
@@ -508,8 +507,7 @@ EOM
                my $l = File::Spec->abs2rel($alt, File::Spec->rel2abs($o));
                open my $fh, '+>>', my $f = "$o/info/alternates";
                seek($fh, 0, SEEK_SET); # Perl did SEEK_END when it saw '>>'
-               my $seen = grep(/\A\Q$l\E\n/, <$fh>); # error check with eof
-               eof($fh) or die "not at `$f' EOF ($!)"; # $! was set by readline
+               my $seen = grep /\A\Q$l\E\n/, PublicInbox::IO::read_all $fh;
                print $fh "$l\n" if !$seen;
                close $fh;
        }
index 0d2f586a73a5c0e6754c17c7c7e51d1beafd518e..2928be4535a271434fee4ac2cfb206ed56c53dc7 100644 (file)
@@ -687,8 +687,7 @@ sub _pre_augment_v2 {
        my $d = "$lei->{ale}->{git}->{git_dir}/objects";
        open my $fh, '+>>', my $f = "$dir/git/0.git/objects/info/alternates";
        seek($fh, 0, SEEK_SET); # Perl did SEEK_END when it saw '>>'
-       my $seen = grep(/\A\Q$d\E\n/, <$fh>);
-       eof($fh) or die "not at `$f' EOF ($!)"; # $! was set by readline
+       my $seen = grep /\A\Q$d\E\n/, PublicInbox::IO::read_all $fh;
        print $fh "$d\n" if !$seen;
        close $fh;
 }
index 8cc4dfaf7f18dd3df11fa8e0df423ea5e883a756..849438bca47705b3b31a09f644f7a2f7fe75f535 100644 (file)
@@ -396,14 +396,12 @@ sub popen_wr {
 
 sub read_out_err ($) {
        my ($opt) = @_;
-       local $/;
        for my $fd (1, 2) { # read stdout/stderr
                my $fh = delete($opt->{"fh.$fd"}) // next;
                seek($fh, 0, SEEK_SET);
                my $dst = $opt->{$fd};
                $dst = $opt->{$fd} = $dst->[1] if ref($dst) eq 'ARRAY';
-               $$dst .= <$fh>;
-               $fh = eof($fh) | close $fh; # detects readline errors
+               PublicInbox::IO::read_all $fh, 0, $dst, length($$dst);
        }
 }
 
index b84886a02827e73893fb0863e3285263681d5c19..caf709c28b12a90c86ba5e70750b23274d7cb216 100644 (file)
@@ -48,16 +48,16 @@ sub require_bsd (;$) {
 
 sub xbail (@) { BAIL_OUT join(' ', map { ref() ? (explain($_)) : ($_) } @_) }
 
-sub read_all ($;$$) {
+sub read_all ($;$$$) {
        require PublicInbox::IO;
-       PublicInbox::IO::read_all($_[0], $_[1], $_[2])
+       PublicInbox::IO::read_all($_[0], $_[1], $_[2], $_[3])
 }
 
 sub eml_load ($) {
        my ($path, $cb) = @_;
        open(my $fh, '<', $path);
        require PublicInbox::Eml;
-       PublicInbox::Eml->new(\(read_all($fh)));
+       PublicInbox::Eml->new(\(scalar read_all $fh));
 }
 
 sub tmpdir (;$) {
index 6a1bc89074e81c6f1e442a7822ef52bfe2d45f96..a955cdf6152813f60461970a994b0cade9a7d12f 100755 (executable)
@@ -42,7 +42,7 @@ local $PublicInbox::Import::DROP_UNIQUE_UNSUB;
 PublicInbox::Import::load_config($pi_cfg);
 my $err;
 my $mime = PublicInbox::Eml->new(do{
-       defined(my $data = do { local $/; <STDIN> }) or die "read STDIN: $!\n";
+       my $data = PublicInbox::IO::read_all \*STDIN;
        PublicInbox::Eml::strip_from($data);
 
        if ($train ne 'rm') {
index b2e0908d52403bab6058746f36f4f8e930aadd21..b463b07b4f7f22bc3eebfd78af6ab3256846a460 100755 (executable)
@@ -44,7 +44,7 @@ use PublicInbox::Spamcheck;
 # in case there's bugs in our code or user error.
 my $emergency = $ENV{PI_EMERGENCY} || "$ENV{HOME}/.public-inbox/emergency/";
 $ems = PublicInbox::Emergency->new($emergency);
-my $str = do { local $/; <STDIN> };
+my $str = PublicInbox::IO::read_all \*STDIN;
 PublicInbox::Eml::strip_from($str);
 $ems->prepare(\$str);
 my $eml = PublicInbox::Eml->new(\$str);
index 8f9b0b162aa8ede829e3a682857b459ad662a2b4..618cfec40e647944f3743149ffd232a0d795c6b3 100755 (executable)
@@ -33,7 +33,7 @@ PublicInbox::Admin::do_chdir(delete $opt->{C});
 my @ibxs = PublicInbox::Admin::resolve_inboxes(\@ARGV, $opt);
 PublicInbox::AdminEdit::check_editable(\@ibxs);
 
-defined(my $data = do { local $/; <STDIN> }) or die "read STDIN: $!\n";
+my $data = PublicInbox::IO::read_all \*STDIN;
 PublicInbox::Eml::strip_from($data);
 my $n_purged = 0;