diff --git a/FU.pm b/FU.pm index 81bcf94..1451c74 100644 --- a/FU.pm +++ b/FU.pm @@ -475,26 +475,23 @@ sub _supervisor($c) { } # Don't bother spawning more than 1 at a time while in error state - my $spawn = !$err ? $c->{proc} - keys %childs : (grep $_ == 1, values %childs) ? 0 : 1; + my $spawn = !$err ? $c->{proc} - keys %childs : !@client_fd && (grep $_ == 1, values %childs) ? 0 : 1; for (1..$spawn) { - my $client = shift @client_fd; + my $client = @client_fd ? IO::Socket->new_from_fd(shift(@client_fd), 'r') : undef; my $pid = fork; die $! if !defined $pid; if (!$pid) { # child $SIG{CHLD} = $SIG{HUP} = $SIG{INT} = $SIG{TERM} = undef; + # In error state, wait with loading the script until we've received a request. + # Otherwise we'll end up in an infinite spawning loop if the script doesn't start properly. + $client = $c->{listen_sock}->accept() or die $! if !$client && $err; if ($client) { - $ENV{FU_CLIENT_FD} = $client; - } elsif ($err) { - # In error state, wait with loading the script until we've received a request. - # Otherwise we'll end up in an infinite spawning loop if the script doesn't start properly. - $client = $c->{listen_sock}->accept() or die $!; fcntl $client, Fcntl::F_SETFD, 0; $ENV{FU_CLIENT_FD} = fileno $client; } exec $^X, (map "-I$_", @INC), $0; exit 1; } - $client && IO::Socket->new_from_fd($client, 'r'); # close() the fd if we have one $childs{$pid} = 1; } diff --git a/FU/Util.pm b/FU/Util.pm index 7b8c6ad..e823d79 100644 --- a/FU/Util.pm +++ b/FU/Util.pm @@ -458,10 +458,9 @@ Like regular socket I/O, a single C message may be split across multiple C calls; in that case the C<$fd> is only received on the first call. -Don't use this function if the sender may include multiple file descriptors in -a single message, weird things can happen. File descriptors received this way -do not have the C flag and will thus survive a call to C. -Refer to L flag is set on received file descriptors. Don't use this +function if the sender may include multiple file descriptors in a single +message, weird things can happen. Refer to L for more weirdness and edge cases. diff --git a/c/fdpass.c b/c/fdpass.c index ae4b141..b54df7d 100644 --- a/c/fdpass.c +++ b/c/fdpass.c @@ -53,7 +53,7 @@ static int fufdpass_recv(pTHX_ I32 ax, int socket, size_t len) { msg.msg_controllen = sizeof(cmsgbuf.buf); msg.msg_flags = 0; - ssize_t r = recvmsg(socket, &msg, 0); + ssize_t r = recvmsg(socket, &msg, MSG_CMSG_CLOEXEC); if (r < 0) { ST(0) = &PL_sv_undef; ST(1) = &PL_sv_undef;