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=-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 47C6F1F4B4 for ; Fri, 2 Apr 2021 09:42:55 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] lei: fix git-credential handling Date: Fri, 2 Apr 2021 05:42:54 -0400 Message-Id: <20210402094254.89006-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: I completely forgot about git-credential prompting when making lei background the client process for MUA. Now it backgrounds itself only for the MUA when no FDs are passed, since the MUA is the final command run. Otherwise, it relies on FD passing as before. Fixes: c790a75439f3a1db ("script/lei: background ourselves on MUA/pager exec") --- lib/PublicInbox/LEI.pm | 8 +++++++- script/lei | 46 ++++++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 69d48bd1..f9361c68 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -839,7 +839,13 @@ sub start_mua { if (my $sock = $self->{sock}) { # lei(1) client process runs it send($sock, exec_buf(\@cmd, {}), MSG_EOR); } elsif ($self->{oneshot}) { - $self->{"pid.$self.$$"}->{spawn(\@cmd)} = \@cmd; + my $pid = fork // die "fork: $!"; + if ($pid > 0) { # original process + exec(@cmd); + warn "exec @cmd: $!\n"; + POSIX::_exit(1); + } + POSIX::setsid() > 0 or die "setsid: $!"; } if ($self->{lxs} && $self->{au_done}) { # kick wait_startq syswrite($self->{au_done}, 'q' x ($self->{lxs}->{jobs} // 0)); diff --git a/script/lei b/script/lei index bea8dcde..78a7dab9 100755 --- a/script/lei +++ b/script/lei @@ -14,31 +14,45 @@ my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do { PublicInbox::Spawn->can('send_cmd4'); }; -my @orig_pid; +my %pids; +my $sigchld = sub { + my $flags = scalar(@_) ? POSIX::WNOHANG() : 0; + for my $pid (keys %pids) { + delete($pids{$pid}) if waitpid($pid, $flags) == $pid; + } +}; +my @parent; my $exec_cmd = sub { my ($fds, $argc, @argv) = @_; - die "BUG: already exec-ed\n" if @orig_pid; - @orig_pid = ($$); - require POSIX; # WNOHANG + my $parent = $$; + require POSIX; my @old = (*STDIN{IO}, *STDOUT{IO}, *STDERR{IO}); my @rdr; for my $fd (@$fds) { - open(my $tmpfh, '+<&=', $fd) or die "open +<&=$fd: $!"; - push @rdr, shift(@old), $tmpfh; + open(my $newfh, '+<&=', $fd) or die "open +<&=$fd: $!"; + push @rdr, shift(@old), $newfh; } + my $do_exec = sub { + my %env = map { split(/=/, $_, 2) } splice(@argv, $argc); + @ENV{keys %env} = values %env; + exec(@argv); + warn "exec: @argv: $!\n"; + POSIX::_exit(1); + }; + $SIG{CHLD} = $sigchld; my $pid = fork // die "fork: $!"; if ($pid == 0) { + while (my ($io, $newfh) = splice(@rdr, 0, 2)) { + open $io, '+<&', $newfh or die "open +<&=: $!"; + } + $do_exec->() if scalar(@$fds); # git-credential, pager + + # parent backgrounds on MUA POSIX::setsid() > 0 or die "setsid: $!"; + @parent = ($parent); return; # continue $recv_cmd in background } - my %env = map { split(/=/, $_, 2) } splice(@argv, $argc); - while (my ($old_io, $tmpfh) = splice(@rdr, 0, 2)) { - open $old_io, '+<&', $tmpfh or die "open +<&=: $!"; - } - @ENV{keys %env} = values %env; - exec(@argv); - warn "exec: @argv: $!\n"; - POSIX::_exit(1); + $do_exec->() if !scalar(@$fds); # MUA reuses all FDs }; if ($send_cmd && eval { @@ -95,16 +109,18 @@ Falling back to (slow) one-shot mode if ($buf =~ /\Aexec (.+)\z/) { $exec_cmd->(\@fds, split(/\0/, $1)); } elsif ($buf eq '-WINCH') { - kill($buf, @orig_pid); # for MUA + kill($buf, @parent); # for MUA } elsif ($buf =~ /\Ax_it ([0-9]+)\z/) { $x_it_code = $1 + 0; last; } elsif ($buf =~ /\Achild_error ([0-9]+)\z/) { $x_it_code = $1 + 0; } else { + $sigchld->(); die $buf; } } + $sigchld->(); if (my $sig = ($x_it_code & 127)) { kill $sig, $$; sleep(1) while 1;