X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=script%2Flei;h=aac8fa94980e4500eba6a5eaf0cee4e87b1a5a1b;hb=7b79c918a5ea79f6adc380ca917b0353475ab29c;hp=bea06b2c0f6edbe4ce5bc810c62bb26c76e0451c;hpb=f478afc01d2137baa215b112f7cbd33c29f28ab7;p=public-inbox.git diff --git a/script/lei b/script/lei index bea06b2c..aac8fa94 100755 --- a/script/lei +++ b/script/lei @@ -6,16 +6,33 @@ use v5.10.1; use Socket qw(AF_UNIX SOCK_STREAM pack_sockaddr_un); use PublicInbox::CmdIPC4; my $narg = 4; +my $recv_cmd = PublicInbox::CmdIPC4->can('recv_cmd4'); my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do { require PublicInbox::CmdIPC1; # 2nd choice $narg = 1; + $recv_cmd = PublicInbox::CmdIPC1->can('recv_cmd1'); PublicInbox::CmdIPC1->can('send_cmd1'); } // do { require PublicInbox::Spawn; # takes ~50ms even if built *sigh* $narg = 4; + $recv_cmd = PublicInbox::Spawn->can('recv_cmd4'); PublicInbox::Spawn->can('send_cmd4'); }; +sub exec_cmd { + my ($fds, $argc, @argv) = @_; + my %env = map { split(/=/, $_, 2) } splice(@argv, $argc); + my @m = (*STDIN{IO}, '<&=', *STDOUT{IO}, '>&=', + *STDERR{IO}, '>&='); + for my $fd (@$fds) { + my ($old_io, $mode) = splice(@m, 0, 2); + open($old_io, $mode, $fd) or die "open $mode$fd: $!"; + } + %ENV = (%ENV, %env); + exec(@argv); + die "exec: @argv: $!"; +} + my ($sock, $pwd); if ($send_cmd && eval { my $path = do { @@ -68,9 +85,14 @@ Falling back to (slow) one-shot mode select $sock; $| = 1; # unbuffer selected $sock $send_cmd->($sock, [ 0, 1, 2 ], $buf, 0); - while ($buf = <$sock>) { - $buf =~ /\Aexit=([0-9]+)\n\z/ and exit($1 + 0); - die $buf; + while (my (@fds) = $recv_cmd->($sock, $buf, 4096 * 33)) { + if ($buf =~ /\Aexit=([0-9]+)\n\z/) { + exit($1); + } elsif ($buf =~ /\Aexec (.+)\n\z/) { + exec_cmd(\@fds, split(/\0/, $1)); + } else { + die $buf; + } } } else { # for systems lacking Socket::MsgHdr, IO::FDPass or Inline::C warn $@ if $@;