Applied in changeset git|89d89fa49d387a09e0d3ea7092a598b88d6d86eb.
When reading from stdin, put a wrapper around the IO object
The purpose of this commit is to fix Bug #21188. We need to detect when
stdin has run in to an EOF case. Unfortunately we can't call the eof
function on IO because it will block.
Here is a short script to demonstrate the issue:
x = STDIN.gets
puts x
puts x.eof?
If you run the script, then type some characters (but NOT a newline),
then hit Ctrl-D twice, it will print the input string. Unfortunately,
calling eof?
will try to read from STDIN again causing us to need a
3rd Ctrl-D to exit the program.
Before introducing the EOF callback to Prism, the input loop looked
kind of like this:
loop do
str = STDIN.gets
process(str)
if str.nil?
p :DONE
end
end
Which required 3 Ctrl-D to exit. If we naively changed it to something
like this:
loop do
str = STDIN.gets
process(str)
if STDIN.eof?
p :DONE
end
end
It would still require 3 Ctrl-D because eof?
would block. In this
patch, we're wrapping the IO object, checking the buffer for a newline
and length, and then using that to simulate a non-blocking eof? method.
This commit wraps STDIN and emulates a non-blocking eof
function.
[Bug #21188]