From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-3.4 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, NUMERIC_HTTP_ADDR,WEIRD_PORT shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 6555E1FA13 for ; Wed, 28 Apr 2021 19:37:29 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/2] lei: avoid close(STD{IN,OUT,ERR}) in oneshot mode Date: Wed, 28 Apr 2021 19:37:29 +0000 Message-Id: <20210428193729.32288-3-e@80x24.org> In-Reply-To: <20210428193729.32288-1-e@80x24.org> References: <20210428193729.32288-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This seems to fix the occasional "make check-run" failures I've been chasing. Some parts of our code assumes we can close($lei->{1}) and similar, which causes IO::Handle::autoflush to behave badly when STDOUT is the "select"-ed FH of the Perl process. Since oneshot mode is (hopefully) the uncommon case, we'll just accept the cost of extra FDs and minimize differences between lei in oneshot vs daemon mode. --- lib/PublicInbox/LEI.pm | 18 ++++-------------- t/lei.t | 1 + 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 7ffcf163..1ea7c9ca 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -487,19 +487,14 @@ sub _lei_atfork_child { # we need to explicitly close things which are on stack if ($persist) { chdir '/' or die "chdir(/): $!"; - my @io = delete @$self{qw(0 1 2 sock)}; - unless ($self->{oneshot}) { - close($_) for @io; - } + close($_) for (grep(defined, delete @$self{qw(0 1 2 sock)})); if (my $cfg = $self->{cfg}) { delete $cfg->{-lei_store}; } } else { # worker, Net::NNTP (Net::Cmd) uses STDERR directly open STDERR, '+>&='.fileno($self->{2}) or warn "open $!"; } - for (delete @$self{qw(3 old_1 au_done)}) { - close($_) if defined($_); - } + close($_) for (grep(defined, delete @$self{qw(3 old_1 au_done)})); if (my $op_c = delete $self->{pkt_op_c}) { close(delete $op_c->{sock}); } @@ -1213,13 +1208,8 @@ sub oneshot { local $quit = $exit if $exit; local %PATH2CFG; umask(077) // die("umask(077): $!"); - my $self = bless { - oneshot => 1, - 0 => *STDIN{GLOB}, - 1 => *STDOUT{GLOB}, - 2 => *STDERR{GLOB}, - env => \%ENV - }, __PACKAGE__; + my $self = bless { oneshot => 1, env => \%ENV }, __PACKAGE__; + for (0..2) { open($self->{$_}, '+<&=', $_) or die "open fd=$_: $!" } dispatch($self, @ARGV); x_it($self, $self->{child_error}) if $self->{child_error}; } diff --git a/t/lei.t b/t/lei.t index 6d276050..8211c01d 100644 --- a/t/lei.t +++ b/t/lei.t @@ -154,6 +154,7 @@ my $test_fail = sub { } } lei_ok('sucks', \'yes, but hopefully less every day'); + like($lei_out, qr/loaded features/, 'loaded features shown'); SKIP: { skip 'no curl', 3 unless which('curl'); lei(qw(q --only http://127.0.0.1:99999/bogus/ t:m));