From: Eric Wong Date: Wed, 31 Mar 2021 23:29:36 +0000 (+0000) Subject: script/lei: background ourselves on MUA/pager exec X-Git-Tag: v1.7.0~848 X-Git-Url: http://www.git.stargrave.org/?p=public-inbox.git;a=commitdiff_plain;h=c790a75439f3a1dbbaa2162feca2593de5997bd3 script/lei: background ourselves on MUA/pager exec This ought to give the MUA or pager exclusive access to the controlling terminal. The downside is we can only exec the pager or MUA once per invocation, but I can't imagine a valid case for running those things multiple times, either. Note: I'm no expert when it comes to terminal control matters, but this allows Ctrl-Z-ed mutt instance to come back and is a nice code reduction, as well. --- diff --git a/script/lei b/script/lei index cb605e2e..bea8dcde 100755 --- a/script/lei +++ b/script/lei @@ -14,36 +14,31 @@ my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do { 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 @orig_pid; my $exec_cmd = sub { my ($fds, $argc, @argv) = @_; + die "BUG: already exec-ed\n" if @orig_pid; + @orig_pid = ($$); + require POSIX; # WNOHANG 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; } - require POSIX; # WNOHANG - $SIG{CHLD} = $sigchld; my $pid = fork // die "fork: $!"; if ($pid == 0) { - 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 = (%ENV, %env); - exec(@argv); - warn "exec: @argv: $!\n"; - POSIX::_exit(1); + POSIX::setsid() > 0 or die "setsid: $!"; + 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 +<&=: $!"; } - $pids{$pid} = 1; + @ENV{keys %env} = values %env; + exec(@argv); + warn "exec: @argv: $!\n"; + POSIX::_exit(1); }; if ($send_cmd && eval { @@ -100,18 +95,16 @@ Falling back to (slow) one-shot mode if ($buf =~ /\Aexec (.+)\z/) { $exec_cmd->(\@fds, split(/\0/, $1)); } elsif ($buf eq '-WINCH') { - kill($buf, $$); # for MUA + kill($buf, @orig_pid); # 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;