Skip to content
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

Reline.readline does not work if STDOUT is a tty and STDIN is not a tty #537

Closed
tompng opened this issue May 4, 2023 · 7 comments · Fixed by #659
Closed

Reline.readline does not work if STDOUT is a tty and STDIN is not a tty #537

tompng opened this issue May 4, 2023 · 7 comments · Fixed by #659
Labels
bug Something isn't working

Comments

@tompng
Copy link
Member

tompng commented May 4, 2023

Description

In Mac, Reline crashes if stdout is a tty and stdin is not a tty. This behavior depends on environment. It works in CI. test_with_newline in test_rendering.rb passes.

% (printf 'hello') | ruby -rreline -e "p Reline.readline '> '"

# In macOS, Terminal.app, zsh
▽/Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline/ansi.rb:273:in `pread': not opened for reading (IOError)
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline/ansi.rb:273:in `rescue in cursor_pos'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline/ansi.rb:252:in `cursor_pos'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:498:in `may_req_ambiguous_char_width'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:311:in `inner_readline'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:287:in `readline'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/3.2.0/forwardable.rb:240:in `readline'
	from -e:1:in `<main>'
/Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline/ansi.rb:255:in `raw': Inappropriate ioctl for device (Errno::ENOTTY)
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline/ansi.rb:255:in `cursor_pos'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:498:in `may_req_ambiguous_char_width'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:311:in `inner_readline'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/reline-0.3.3/lib/reline.rb:287:in `readline'
	from /Users/tomoya/.rbenv/versions/3.2.0/lib/ruby/3.2.0/forwardable.rb:240:in `readline'
	from -e:1:in `<main>'

# Inside docker (docker run --rm -ti rubylang/rubyfarm sh)
> hello
"hello"

In the above example, it seems working in docker, but actually it's not.

# (printf 'he';sleep 1;printf 'llo') | ruby -rreadline -e "p Readline.readline '> '"
> hello
"hello"
# (printf 'he';sleep 1;printf 'llo') | ruby -rreline -e "p Reline.readline '> '"
> he
"he"
# ruby -v
ruby 3.3.0dev (2023-05-01T12:20:20Z master 13dfbcf7bf) [x86_64-linux]
# ruby -rreline -e "puts Reline::VERSION"
0.3.3

Terminal Emulator

macOS Terminal.app

@revolter
Copy link

revolter commented Apr 1, 2024

Could this be the same error as:

bundler: failed to load command: fastlane (/Users/revolt/.gems/bin/fastlane)
/Users/revolt/.rbenv/versions/3.3.0/lib/ruby/3.3.0/reline/ansi.rb:238:in `winsize': [!] Operation not supported by device - <STDIN> (Errno::ENODEV)
	from /Users/revolt/.rbenv/versions/3.3.0/lib/ruby/3.3.0/reline/ansi.rb:238:in `get_screen_size'
	from /Users/revolt/.rbenv/versions/3.3.0/lib/ruby/3.3.0/reline.rb:218:in `get_screen_size'
	from /Users/revolt/.rbenv/versions/3.3.0/lib/ruby/3.3.0/forwardable.rb:240:in `get_screen_size'
	from /Users/revolt/.gems/gems/tty-screen-0.8.2/lib/tty/screen.rb:359:in `size_from_readline'
	from /Users/revolt/.gems/gems/tty-screen-0.8.2/lib/tty/screen.rb:111:in `size'
	from /Users/revolt/.gems/gems/tty-screen-0.8.2/lib/tty/screen.rb:129:in `width'
	from /Users/revolt/.gems/gems/fastlane-2.219.0/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb:90:in `header'

?

It's only triggered when we:

  • execute git commit
  • which executes a pre-commit hook
  • which executes a Python script
  • which executes a fastlane lane
  • which tries to execute TTY::Screen.width

cc @bpoplauschi

@forthrin
Copy link

forthrin commented Apr 7, 2024

  1. Is the below the same problem as this issue?
  2. When will the problem be patched via RubyGems?
  3. Where can I find a patch to apply in the meantime?
$ echo Foo | xargs ruby -r readline -e "puts 'Bar'"
/opt/homebrew/lib/ruby/gems/3.3.0/gems/reline-0.5.0/lib/reline/ansi.rb:240:in `winsize': Operation not supported by device - <STDIN> (Errno::ENODEV)
	from /opt/homebrew/lib/ruby/gems/3.3.0/gems/reline-0.5.0/lib/reline/ansi.rb:240:in `get_screen_size'
	from /opt/homebrew/lib/ruby/gems/3.3.0/gems/reline-0.5.0/lib/reline/line_editor.rb:59:in `initialize'
	from /opt/homebrew/lib/ruby/gems/3.3.0/gems/reline-0.5.0/lib/reline.rb:553:in `new'

@vtamara
Copy link
Contributor

vtamara commented Apr 26, 2024

On OpenBSD/adJ 7.4 I don't see the problem that @forthrin reports by running:

% echo Foo | xargs ruby -r readline -e "puts 'Bar'"
Bar

But I see the same error reline-0.5.3/lib/reline/ansi.rb:246:in 'winsize': Operation not supported by device - <STDIN> (Errno::ENODEV) described by him and by @revolter in a different scenario that I described in the issue #690.

@tompng
Copy link
Member Author

tompng commented Apr 26, 2024

#659 also adds rescue Errno::ENODEV

@kaoru
Copy link

kaoru commented Apr 30, 2024

I think we might be seeing the originally described bug "Reline.readline does not work if STDOUT is a tty and STDIN is not a tty" when working on a Rails app with hookup. Hookup automatically runs rake db:migrate and bundle install when switching branches, but it runs db:migrate with a closed STDIN and that causes this LoadError: cannot load such file -- readline.bundle (LoadError) to appear.

$ bin/rails db:migrate < /dev/null
bin/rails aborted!
Errno::ENODEV: Operation not supported by device - <STDIN> (Errno::ENODEV)
/Users/alex/Documents/Git/App/config/application.rb:8:in `<main>'
/Users/alex/Documents/Git/App/Rakefile:4:in `<main>'
bin/rails:4:in `<main>'

Caused by:
LoadError: cannot load such file -- readline.bundle (LoadError)
Did you mean?  readline
/Users/alex/Documents/Git/App/config/application.rb:8:in `<main>'
/Users/alex/Documents/Git/App/Rakefile:4:in `<main>'
bin/rails:4:in `<main>'
(See full trace by running task with --trace)

I have been able to reproduce this with a new rails app like so:

$ rails new rn7
$ cd rn7
$ bin/rails db:migrate < /dev/null

And removing the following line from the Gemfile fixes it:

gem "debug", platforms: %i[ mri windows ]

Which I think points to reline, as it is a dependency of the debug gem.

Adding the following line to the Gemfile:

gem "reline", git: 'https://github.com/tompng/reline', branch: 'ansi_is_general_io'

Seems to fix it, which points to #659 as being a good fix.

However, I've only tested that with empty/no-op db:migrate calls so I can't say for sure that it's working fully.

@kaoru
Copy link

kaoru commented May 29, 2024

This seems to be fixed in https://github.com/ruby/reline/releases/tag/v0.5.7 - bin/rails db:migrate < /dev/null is no longer throwing Errno::ENODEV: Operation not supported by device since we upgraded.

@tompng
Copy link
Member Author

tompng commented May 29, 2024

Original issue pread: not opened for reading is fixed in #671
The bin/rails db:migrate < /dev/null problem mentioned here is fixed in #703

@tompng tompng closed this as completed May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging a pull request may close this issue.

6 participants