Skip to content

fix(cursor): write CSI 6n query to TTY when stdout is redirected - #1062

Open
raphaelvigee wants to merge 1 commit into
crossterm-rs:masterfrom
hephbuild:fix-cursor-position-stderr
Open

fix(cursor): write CSI 6n query to TTY when stdout is redirected#1062
raphaelvigee wants to merge 1 commit into
crossterm-rs:masterfrom
hephbuild:fix-cursor-position-stderr

Conversation

@raphaelvigee

Copy link
Copy Markdown

Summary

Fixes #652.

cursor::position() on Unix wrote the ESC [ 6 n Device Status Report query to stdout. When stdout is piped to another program (e.g. prog | rev), the escape sequence went into the pipe instead of the terminal, so the terminal never responded and the call hung until the 2s timeout. The terminal's reply also corrupted the piped output.

Change

write_cursor_query picks the first available TTY for the query, in order:

  1. stdout (preserved as default behavior when not redirected)
  2. stderr
  3. /dev/tty

The response is already read via tty_fd(), which falls back to /dev/tty when stdin is not a TTY, so the read side already worked — only the write side needed fixing.

rustix::termios::isatty is used for the TTY check (or libc::isatty under the libc feature). No new dependencies. MSRV 1.63 preserved (avoided std::io::IsTerminal, stable in 1.70).

Test plan

  • cargo build (default features)
  • cargo build --features libc
  • cargo build --no-default-features --features events
  • Manual: run a small binary that calls crossterm::cursor::position() with stdout piped to rev — confirm the call returns the cursor position instead of corrupting the pipe / timing out.
  • Manual: same binary run normally in a terminal — confirm behavior unchanged.

cursor::position() previously wrote the DSR query to stdout. When stdout
is piped to another program (e.g. `prog | rev`), the escape sequence was
sent to the pipe instead of the terminal, so the terminal never
responded and the call hung until timeout.

Pick the first available TTY: stdout, then stderr, then /dev/tty. Uses
rustix::termios::isatty (or libc::isatty under the libc feature) to stay
within MSRV 1.63.

Fixes crossterm-rs#652
@raphaelvigee
raphaelvigee requested a review from TimonPost as a code owner May 28, 2026 19:43
@raphaelvigee

Copy link
Copy Markdown
Author

I'm currently using the version 0.29 of the project, if this PR is accepted in principle i will update it to master

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.

Feature Request: A method for Unix systems to get the position of the cursor in stderr

1 participant