Content-Length: 251528 | pFad | http://github.com/ruby/ruby/pull/13944

0E When reading from stdin, put a wrapper around the IO object by tenderlove · Pull Request #13944 · ruby/ruby · GitHub
Skip to content

When reading from stdin, put a wrapper around the IO object #13944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

tenderlove
Copy link
Member

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 str.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.

[Bug #21188]

Checking the return value of `fgets` isn't good enough to determine
whether the input stream has reached EOF or not.  `fgets` could have run
in to an error and returned NULL.  Additionally, we can't just check the
buffer contents for `\n` because `fgets` could have read the maximum
buffer size (which may not have ended with a `\n`).

I want to use this callback to implement a fix for:

  https://bugs.ruby-lang.org/issues/21188
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:

```ruby
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:

```ruby
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:

```ruby
loop do
  str = STDIN.gets
  process(str)

  if str.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.

[Bug #21188]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/ruby/ruby/pull/13944

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy