Bug #11009
closedclosed STDOUT status does not get inherited to children processes created with exec
Description
When closing STDOUT
, then STDOUT.closed?
returns true
. In a child process started with exec, STDOUT
is closed but it does closed?
returns false
.
Also, in the child process, writing to STDOUT
fails silently, so the user has no idea that his stdout
is closed.
Ruby should return the proper response to closed?
and not fail silently when writing to the closed STDOUT
stream.
#!/usr/bin/ruby
child_mode = true if ARGV[0] == 'child_mode'
process_name = child_mode ? "CHILD" : "PARENT"
if !child_mode
STDERR.puts "Closing stdout and forking"
STDOUT.close
STDERR.puts "#{process_name} STDOUT closed? #{STDOUT.closed?}"
exec 'ruby', $0, "child_mode"
else
STDERR.puts "#{process_name} STDOUT closed? #{STDOUT.closed?}"
end
STDERR.puts "Trying to write to STDOUT a test line"
STDOUT.puts "#{process_name} test puts to STDOUT"
STDERR.puts "Done writing STDOUT. Did you see anything?"
Updated by costi (Constantin Gavrilescu) about 9 years ago
The output of the script is:
Closing stdout and forking
PARENT STDOUT closed? true
CHILD STDOUT closed? false
Trying to write to STDOUT a test line
Done writing STDOUT. Did you see anything?
Updated by costi (Constantin Gavrilescu) about 9 years ago
Actually, the fails this way only in 1.8.7.
Ruby 2.1 child process reports the STDOUT
as open and uses successfully STDOUT
, even if the parent closed it, which is also strange, but not as bad.
Updated by nobu (Nobuyoshi Nakada) about 9 years ago
- Description updated (diff)
- Status changed from Open to Rejected
Ruby does not close the standard file descriptors 0..2 actually, but just disconnects them from the corresponding IO objects, since r23705.
And they are filled with broken pipes unless opened, since r33567.
This is because closing these descriptors often results in unexpected and bad side-effects.
You can close stdout of a child process by exec(... out: :close)
if you really need it.