Project

General

Profile

Actions

Bug #21188

closed

PRISM does not end reading from tty with ^D twice

Added by nobu (Nobuyoshi Nakada) 5 months ago. Updated about 9 hours ago.

Status:
Closed
Assignee:
Target version:
-
[ruby-core:121390]

Description

When reading from tty, ^D ends the text without the newline.

$ cat
a

Typing ^D here, only "a" is sent without a newline, and cat echos back it.
Then by typing ^D again, an empty read that means EOF causes cat to exit.

ruby --parser=parse.y behaves in this manner:

$ ruby --parser=parse.y
p __FILE__"-"

Typing ^D twice just after __FILE__, and p prints "-".
However prism requires ^D thrice.

Actions #1

Updated by hsbt (Hiroshi SHIBATA) 4 months ago

  • Status changed from Open to Assigned
Actions #2

Updated by tenderlovemaking (Aaron Patterson) about 9 hours ago

  • Status changed from Assigned to Closed

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]

Actions

Also available in: Atom PDF

Like0
Like0Like0