Skip to content

More accurate TTY checking for IO - #9594

Draft
headius wants to merge 3 commits into
jruby:jruby-10.0from
headius:better_console_checking
Draft

More accurate TTY checking for IO#9594
headius wants to merge 3 commits into
jruby:jruby-10.0from
headius:better_console_checking

Conversation

@headius

@headius headius commented Aug 17, 2026

Copy link
Copy Markdown
Member

This introduces some cleanup and improvements in how we determine whether an IO is a TTY (IO#tty? method):

  • If the IO has a proper native file descriptor and we can call isatty, use that result.
  • Otherwise, if the IO was set up as user-facing stdio AND the current JRuby was started via Main, use the JDK's System.console() and Console.isTerminal().
  • Otherwise, treat the IO as a non-terminal.

This should address situations where JRuby has been embedded as part of a larger application with user-facing stdio streams connected to non-terminal channels, such as in #9590 (deployed in Tomcat using jruby-rack).

Draft until appropriate tests can be added.

The System.console() method is intended to indicate whether the
JVM process is running with stdio connected to a TTY-like, but in
JDK 22 through 24, it also returns non-null for non-TTY stdio due
to the use of JLine as a pseudo-terminal. This behavior changed
back to JDK 21 behavior in JDK 25, but we must continue double-
checking Console.isTerminal() for situations where the JLine logic
is live.

Part of improvements for jruby#9590.

See https://bugs.openjdk.org/browse/JDK-8361911 for an OpenJDK
issue that details the changing behavior of System.console().
We have other reasons to know if JRuby was started as the JVM's
main entry point, so rename this to reflect the actual state.
@headius

headius commented Aug 17, 2026

Copy link
Copy Markdown
Member Author

See also #8934 for previous attempts to deal with JDK 22 always returning non-null System.console().

If JRuby is started through Main, then the stdio channels we set up
are either native or come from the JVM's System.in/out/err. In the
latter case, we can use the JVM's System.console() and
Console.isTerminal() methods to indicate if the JRuby stdio is a
TTY. This fixes previous logic that always assumed any non-native
stdio was conneected to a TTY, leading to cases where embedded use
might incorrectly assume that color console output or hard process
exits were appropriate.

Fixes jruby#9590
@headius
headius force-pushed the better_console_checking branch from 3e3598f to 4a8dab5 Compare August 17, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IO#tty? silently returns true for redirected stdio in embedded runtimes when --add-opens are missing

1 participant