Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 7bec67fe authored by Stéphane Martin's avatar Stéphane Martin Committed by stephane martin
Browse files

[Runner] Backport Bugfix: Close useless descriptor after fork.

Before this patch when kadeploy crash, the administrator needs to kill
all children to rebind the socket.

Change-Id: I85d9b2f6692270f15251e67b8db85b051f63a6e2
parent 104a1036
Branches 3.2
No related tags found
No related merge requests found
...@@ -36,53 +36,43 @@ class Execute ...@@ -36,53 +36,43 @@ class Execute
if opts[:stdin] if opts[:stdin]
in_r, in_w = IO::pipe in_r, in_w = IO::pipe
in_w.sync = true in_w.sync = true
out_r, out_w = IO::pipe
err_r, err_w = IO::pipe
[ [in_r,out_w,err_w], [in_w,out_r,err_r] ]
else else
out_r, out_w = IO::pipe in_r, in_w = [nil,nil]
err_r, err_w = IO::pipe
[ [nil,out_w,err_w], [nil,out_r,err_r] ]
end end
out_r, out_w = IO::pipe
err_r, err_w = IO::pipe
[ [in_r,out_w,err_w], [in_w,out_r,err_r] ]
end end
def run(opts={:stdin => false}) def run(opts={:stdin => false})
@@forkmutex.synchronize do @@forkmutex.synchronize do
@child_io, @parent_io = Execute.init_ios(opts) @child_io, @parent_io = Execute.init_ios(opts)
@parent_io.each { |io| io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if io }
@exec_pid = fork { @exec_pid = fork {
begin begin
@parent_io.each do |io|
begin
io.close if io and !io.closed?
rescue IOError
end
end
std = nil #stdin
if opts[:stdin] STDIN.reopen(@child_io[0]) if opts[:stdin]
std = [STDIN, STDOUT, STDERR]
else
std = [nil, STDOUT, STDERR]
end
std.each_index do |i| #stdout
next unless std[i] STDOUT.reopen(@child_io[1])
begin
std[i].reopen(@child_io[i])
@child_io[i].close
rescue IOError
end
end
#close unused opened file descriptor #stderr
ObjectSpace.each_object(IO) do |f| STDERR.reopen(@child_io[2])
f.close() if !f.closed? && !(0..2).include?(f.fileno)
end
# Close useless file descriptors.
# Since ruby 2.0, FD_CLOEXEC is set when ruby opens a descriptor.
# After performing exec(), all file descriptors are closed excepted 0,1,2
# https://bugs.ruby-lang.org/issues/5041
if RUBY_VERSION < "2.0"
ObjectSpace.each_object(IO) do |f|
#Some IO objects are not initialized while testing.
#So the function 'closed?' raises an exception. We ignore that.
f.close if !f.closed? && ![0,1,2].include?(f.fileno) rescue IOError
end
end
exec(*@command) exec(*@command)
rescue SystemCallError, Exception => e rescue SystemCallError, Exception => e
STDERR.puts "Fork Error: #{e.message} (#{e.class.name})" STDERR.puts "Fork Error: #{e.message} (#{e.class.name})"
...@@ -92,10 +82,7 @@ class Execute ...@@ -92,10 +82,7 @@ class Execute
} }
@child_io.each do |io| @child_io.each do |io|
begin io.close if io and !io.closed?
io.close if io and !io.closed?
rescue IOError
end
end end
end end
result = [@exec_pid, *@parent_io] result = [@exec_pid, *@parent_io]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment