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-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 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 633661FA12 for ; Sun, 3 Jan 2021 11:24:56 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/2] lei: fix output race in client/daemon mode Date: Sun, 3 Jan 2021 11:24:51 +0000 Message-Id: <20210103112451.75313-3-e@80x24.org> In-Reply-To: <20210103112451.75313-1-e@80x24.org> References: <20210103112451.75313-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: The daemon needs to flush stdout before disconnecting or killing clients, otherwise they may reread empty data on redirected outputs. We also don't want to unbuffer stdout too early in case we have lots of small chunks of data to output. The received ($self->{2}) will always have autoflush, matching normal STDERR behavior. --- lib/PublicInbox/LEI.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 3ad5e01a..6f21da35 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -236,6 +236,7 @@ my %CONFIG_KEYS = ( sub x_it ($$) { # pronounced "exit" my ($self, $code) = @_; + $self->{1}->autoflush(1); # make sure client sees stdout before exit if (my $sig = ($code & 127)) { kill($sig, $self->{pid} // $$); } else { @@ -635,6 +636,7 @@ sub accept_dispatch { # Listener {post_accept} callback say $sock "timed out waiting to recv FDs"; return; } + $self->{2}->autoflush(1); # keep stdout buffered until x_it|DESTROY # $ARGV_STR = join("]\0[", @ARGV); # $ENV_STR = join('', map { "$_=$ENV{$_}\0" } keys %ENV); # $line = "$$\0\0>$ARGV_STR\0\0>$ENV_STR\0\0"; @@ -773,4 +775,8 @@ sub oneshot { }, __PACKAGE__), @ARGV); } +# ensures stdout hits the FS before sock disconnects so a client +# can immediately reread it +sub DESTROY { $_[0]->{1}->autoflush(1) } + 1;