Bug #9688
closedRuby's child process inherits parent's sockets (mswin)
Description
When Ruby application creates child process, sockets are inherited from the parent process.
This causes severe troubles.
In my situation, I have some web services using WEBrick and Sinatra. They invoke child process as a batch file using kernel.system method. And in the batch file I launch some long running applications by 'start'.
If these type of long running applications stay in running state, I never restart the services because the children grab server sockets while running. What is worse that Windows never report EADDRINUSE so I have no clue to judge its condition. Indeed 'netstat /b' reports the port is occupied by System not the child app.
Below is the reproduction script.
require 'socket'
require 'timeout'
exit unless RUBY_PLATFORM =~ /mswin/
BAT = "#{ENV['TMP']}#{File::SEPARATOR}test_inheritsock.bat"
File.open(BAT, 'w') do |fout|
fout.puts 'start ruby -e "sleep(10)"'
end
port = nil
TCPServer.open(0) do |gs|
port = gs.addr[1]
system(BAT)
end
File.delete BAT
gs = TCPServer.open(port)
running = true
client = false
begin
timeout(20) do
while running
Thread.start do
s = gs.accept
s.gets
s.close
running = false
end
unless client
client = true
Thread.start do
TCPSocket.open('localhost', port) do |sock|
sock.puts('')
end
end
else
sleep(1)
end
end
end
puts 'no problem'
rescue Timeout::Error
puts 'failed'
end
gs.close
The second opend TCPServer can not receive a connection request.
Unak already made no inheritance patch (https://gist.github.com/unak/9825743) and I tested it with Windowds7(x86) and Windows8.1(x64) and in both environments the above script runs completely.
So I wonder if the patch is applied to the trunk.
Thanks in advance.
Updated by usa (Usaku NAKAMURA) over 10 years ago
Thank you for testing my patch!
Updated by usa (Usaku NAKAMURA) over 10 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r45471.
- win32/win32.c (rb_w32_accept, open_ifs_socket, socketpair_internal):
reset inherit flag of socket to avoid unintentional inheritance of
socket. note that the return value of SetHandleInformation() is not
verified intentionally because old Windows may return an error.
[Bug #9688] [ruby-core:61754]
Updated by usa (Usaku NAKAMURA) over 10 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN to 2.0.0: REQUIRED, 2.1: REQUIRED
Updated by usa (Usaku NAKAMURA) over 10 years ago
- Backport changed from 2.0.0: REQUIRED, 2.1: REQUIRED to 2.0.0: DONE, 2.1: REQUIRED
backported into ruby_2_0_0 at r45753.
Updated by nagachika (Tomoyuki Chikanaga) over 10 years ago
- Backport changed from 2.0.0: DONE, 2.1: REQUIRED to 2.0.0: DONE, 2.1: DONE
Backported into ruby_2_1
branch at r46305.