select($rvec, undef, undef, 1) or
return send($sock, 'timed out waiting to recv FDs', MSG_EOR);
my @fds = $recv_cmd->($sock, my $buf, 4096 * 33); # >MAX_ARG_STRLEN
- if (scalar(@fds) == 3) {
+ if (scalar(@fds) == 4) {
my $i = 0;
- for my $rdr (qw(<&= >&= >&=)) {
+ for my $rdr (qw(<&= >&= >&= <&=)) {
my $fd = shift(@fds);
open($self->{$i++}, $rdr, $fd) and next;
send($sock, "open($rdr$fd) (FD=$i): $!", MSG_EOR);
my ($argc, @argv) = split(/\0/, $buf, -1);
undef $buf;
my %env = map { split(/=/, $_, 2) } splice(@argv, $argc);
- if (chdir($env{PWD})) {
+ if (chdir(delete($self->{3}))) {
local %ENV = %env;
$self->{env} = \%env;
eval { dispatch($self, @argv) };
send($sock, $@, MSG_EOR) if $@;
} else {
- send($sock, "chdir($env{PWD}): $!", MSG_EOR); # implicit close
+ send($sock, "fchdir: $!", MSG_EOR); # implicit close
}
}
# lei(1) calls this when it can't connect
sub lazy_start {
- my ($path, $errno, $nfd) = @_;
+ my ($path, $errno, $narg) = @_;
if ($errno == ECONNREFUSED) {
unlink($path) or die "unlink($path): $!";
} elsif ($errno != ENOENT) {
my $dev_ino_expect = pack('dd', $st[0], $st[1]); # dev+ino
pipe(my ($eof_r, $eof_w)) or die "pipe: $!";
local $oldset = PublicInbox::DS::block_signals();
- if ($nfd == 4) {
+ if ($narg == 5) {
$send_cmd = PublicInbox::Spawn->can('send_cmd4');
$recv_cmd = PublicInbox::Spawn->can('recv_cmd4') // do {
require PublicInbox::CmdIPC4;
};
}
$recv_cmd or die <<"";
-(Socket::MsgHdr || Inline::C) missing/unconfigured (nfd=$nfd);
+(Socket::MsgHdr || Inline::C) missing/unconfigured (narg=$narg);
require PublicInbox::Listener;
require PublicInbox::EOFpipe;
use Socket qw(AF_UNIX SOCK_SEQPACKET MSG_EOR pack_sockaddr_un);
use Errno qw(EINTR ECONNRESET);
use PublicInbox::CmdIPC4;
-my $narg = 4;
+my $narg = 5;
my ($sock, $pwd);
my $recv_cmd = PublicInbox::CmdIPC4->can('recv_cmd4');
my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do {
Falling back to (slow) one-shot mode
}
- require Cwd;
- $pwd = $ENV{PWD} // '';
- my $cwd = Cwd::fastcwd() // die "fastcwd(PWD=$pwd): $!";
- if ($pwd ne $cwd) { # prefer ENV{PWD} if it's a symlink to real cwd
- my @st_cwd = stat($cwd) or die "stat(cwd=$cwd): $!";
- my @st_pwd = stat($pwd); # PWD invalid, use cwd
- # make sure st_dev/st_ino match for {PWD} to be valid
- $pwd = $cwd if (!@st_pwd || $st_pwd[1] != $st_cwd[1] ||
- $st_pwd[0] != $st_cwd[0]);
- } else {
- $pwd = $cwd;
- }
1;
}) { # (Socket::MsgHdr|Inline::C), $sock, $pwd are all available:
- $ENV{PWD} = $pwd;
+ open my $dh, '<', '.' or die "open(.) $!";
my $buf = join("\0", scalar(@ARGV), @ARGV);
while (my ($k, $v) = each %ENV) { $buf .= "\0$k=$v" }
$buf .= "\0\0";
- $send_cmd->($sock, [ 0, 1, 2 ], $buf, MSG_EOR);
+ $send_cmd->($sock, [ 0, 1, 2, fileno($dh) ], $buf, MSG_EOR);
$SIG{TERM} = $SIG{INT} = $SIG{QUIT} = sub {
my ($sig) = @_; # 'TERM', not an integer :<
$SIG{$sig} = 'DEFAULT';
SKIP: { # real socket
require_mods(qw(Cwd), my $nr = 105);
- my $nfd = eval { require Socket::MsgHdr; 4 } // do {
+ my $nfd = eval { require Socket::MsgHdr; 5 } // do {
require PublicInbox::Spawn;
- PublicInbox::Spawn->can('send_cmd4') ? 4 : undef;
+ PublicInbox::Spawn->can('send_cmd4') ? 5 : undef;
} //
skip 'Socket::MsgHdr or Inline::C missing or unconfigured', $nr;
like($out, qr/^usage: /, 'help output works');
chmod 0700, $sock or BAIL_OUT "chmod 0700: $!";
}
- if ('oneshot on cwd gone') {
- my $cwd = Cwd::fastcwd() or BAIL_OUT "fastcwd: $!";
- my $d = "$home/to-be-removed";
- my $lei_path = 'lei';
- # we chdir, so we need an abs_path fur run_script
- if (($ENV{TEST_RUN_MODE}//2) != 2) {
- $lei_path = PublicInbox::TestCommon::key2script('lei');
- $lei_path = Cwd::abs_path($lei_path);
- }
- mkdir $d or BAIL_OUT "mkdir($d) $!";
- chdir $d or BAIL_OUT "chdir($d) $!";
- if (rmdir($d)) {
- $out = $err = '';
- ok(run_script([$lei_path, 'help'], undef, $opt),
- 'cwd fail, one-shot fallback works');
- } else {
- $err = "rmdir=$!";
- }
- chdir $cwd or BAIL_OUT "chdir($cwd) $!";
- like($err, qr/cwd\(/, 'cwd error noted');
- like($out, qr/^usage: /, 'help output still works');
- }
-
unlink $sock or BAIL_OUT "unlink($sock) $!";
for (0..100) {
kill('CHLD', $new_pid) or last;