Skip to content

Reline misbehaves on Windows under stdin redirection #907

Description

@rschmitt

When stdin is redirected (such that $stdin.isatty is false), Readline.readline hangs on Windows. This one-line reproducer can be run in PowerShell to illustrate the problem (this is with Ruby 4.0.5):

$null | ruby -e "require 'readline'; STDERR.puts %Q{gate=#{Reline::IOGate.class}}; STDERR.puts %Q{`$stdin.isatty=#{`$stdin.isatty}}; p Readline.readline('> ')"

This prints the following and then goes into an infinite loop until killed with Ctrl-C:

gate=Reline::Windows
$stdin.isatty=false
>

Worse still, piping a non-null string ('input' | ruby -e ...) or even multiple lines (@('line1', 'line2') | ruby -e ...) results in the same behavior, apparently because Reline::Windows is reading directly from the console handle rather than the stdin stream.

Setting $env:TERM='dumb' (as per #616) shows the expected behavior: the program immediately reads EOF and returns:

$env:TERM='dumb'; $null | ruby -e "require 'readline'; STDERR.puts %Q{gate=#{Reline::IOGate.class}}; STDERR.puts %Q{`$stdin.isatty=#{`$stdin.isatty}}; p Readline.readline('> ')"; ri Env:\TERM
gate=Reline::Dumb
$stdin.isatty=false
> > nil

Non null inputs render strangely, but they still read correctly:

$env:TERM='dumb'; 'input' | ruby -e "require 'readline'; STDERR.puts %Q{gate=#{Reline::IOGate.class}}; STDERR.puts %Q{`$stdin.isatty=#{`$stdin.isatty}}; p Readline.readline('> ')"; ri Env:\TERM
gate=Reline::Dumb
$stdin.isatty=false
> iininpinpuinput> input
"input"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions