io-console
io-console copied to clipboard
how to manually specify backend version
Is there any way to manually (and cleanly) choose the backend version that io-console uses for consoles?
For background, I'm working in JRuby within a ScriptingContainer with piped input and output streams. I'm running IRB within this, which works for the most part, but on Linux systems I get this output when I run statements in IRB:
irb(main):001> puts "world wide web wide"
puts "world wide web wide"
world wide web wide
An error occurred when inspecting the object: #<Errno::EBADF: Bad file descriptor - ioctl(TIOCGWINSZ)>
Result of Kernel#inspect: nil
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/io/console/native_console.rb:99:in 'winsize': Bad file descriptor - ioctl(TIOCGWINSZ) (Errno::EBADF)
from uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/reline/io/ansi.rb:190:in 'get_screen_size'
from uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/reline.rb:208:in 'get_screen_size'
from uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/forwardable.rb:240:in 'get_screen_size'
from org/jruby/RubyKernel.java:1658:in 'loop'
from org/jruby/RubyKernel.java:1397:in 'catch'
from <script>:1:in '<main>'
I tracked this back using the stack trace to the native console being chosen because this is Linux box. I hadn't encountered it previously as I was working on a Windows machine, and I managed to work around this by tricking the chosen console into always being the stub:
# before we require irb, we need to make sure that io-console uses the stub
# console, since the STDIN stream we are using isn't a normal terminal
host_os = RbConfig::CONFIG['host_os']
RbConfig::CONFIG['host_os'] = 'windows'
require 'irb'
# now that irb has loaded, we can switch the host os back
RbConfig::CONFIG['host_os'] = host_os
This seems a little hacky though. I see this text in lib/ffi/io/console.rb:
This will produce surprising results if anyone is actually using io/console against non-stdio ttys...but that case seems like it would be pretty rare.
I suspect I am in one of these rare cases. I fully accept that I'm already in the "doing weird things" territory so if that workaround is the best I can do, then I'll work with that. But I just want to make sure I'm not missing a better solution.
This is a very interesting use case, and one I'd like to work with you to support better!
I think part of the correct fix would be to do a better job of detecting if stdout is actually a TTY, falling back on the limited console support in that case. That's essentially what you've done here by forcing the platform to "windows", since there's currently only the most basic support for io/console there.