Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/rubyPublic

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
tenderlove wants to merge2 commits intoruby:master
base:master
Choose a base branch
Loading
fromtenderlove:eof-wip

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'tcall the eof
function on IO because it will block.

Here is a short script to demonstrate the issue:

x=STDIN.getsputsxputsx.eof?

If you run the script, then type some characters (butNOT a newline),
then hit Ctrl-D twice, it will print the input string. Unfortunately,
callingeof? 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:

loopdostr=STDIN.getsprocess(str)ifstr.nil?p:DONEendend

Which required 3 Ctrl-D to exit. If we naively changed it to something
like this:

loopdostr=STDIN.getsprocess(str)ifstr.eof?p:DONEendend

It would still require 3 Ctrl-D becauseeof? 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 determinewhether the input stream has reached EOF or not.  `fgets` could have runin to an error and returned NULL.  Additionally, we can't just check thebuffer contents for `\n` because `fgets` could have read the maximumbuffer 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 whenstdin has run in to an EOF case.  Unfortunately we can't _call_ the eoffunction on IO because it will block.Here is a short script to demonstrate the issue:```rubyx = STDIN.getsputs xputs 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 a3rd Ctrl-D to exit the program.Before introducing the EOF callback to Prism, the input loop lookedkind of like this:```rubyloop do  str = STDIN.gets  process(str)  if str.nil?    p :DONE  endend```Which required 3 Ctrl-D to exit.  If we naively changed it to somethinglike this:```rubyloop do  str = STDIN.gets  process(str)  if str.eof?    p :DONE  endend```It would still require 3 Ctrl-D because `eof?` would block.  In thispatch, we're wrapping the IO object, checking the buffer for a newlineand length, and then using that to simulate a non-blocking eof? method.[Bug #21188]
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

1 participant
@tenderlove

[8]ページ先頭

©2009-2025 Movatter.jp