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")
if (my $sock = $self->{sock}) { # lei(1) client process runs it
send($sock, exec_buf(\@cmd, {}), MSG_EOR);
} elsif ($self->{oneshot}) {
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));
}
if ($self->{lxs} && $self->{au_done}) { # kick wait_startq
syswrite($self->{au_done}, 'q' x ($self->{lxs}->{jobs} // 0));
PublicInbox::Spawn->can('send_cmd4');
};
PublicInbox::Spawn->can('send_cmd4');
};
+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) = @_;
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) {
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) {
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: $!";
POSIX::setsid() > 0 or die "setsid: $!";
return; # continue $recv_cmd in background
}
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 {
};
if ($send_cmd && eval {
if ($buf =~ /\Aexec (.+)\z/) {
$exec_cmd->(\@fds, split(/\0/, $1));
} elsif ($buf eq '-WINCH') {
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 {
} 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 {
if (my $sig = ($x_it_code & 127)) {
kill $sig, $$;
sleep(1) while 1;
if (my $sig = ($x_it_code & 127)) {
kill $sig, $$;
sleep(1) while 1;