fdpass_recv: Set O_CLOEXEC on received fds
Turns out this is necessary even if the fd is going to be passed through exec() soon, because the supervisor might receive multiple fds before spawning another process, in which case all of them are going to be passed to the new process instead of just one.
This commit is contained in:
parent
9e1be5bc71
commit
2f50736782
3 changed files with 9 additions and 13 deletions
13
FU.pm
13
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue