On Windows `is_terminal` always returns `false` if the handle is not opened with read access
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Minimal example:
use std::io::IsTerminal;
fn main() {
let conout = r"\\.\CONOUT$";
let stdout = std::fs::File::options().write(true).open(conout).unwrap();
assert!(stdout.is_terminal());
}
This is because we use GetConsoleMode to determine if a handle is a console handle or not and the docs for GetConsoleMode state:
The handle must have the GENERIC_READ access right.
We could check the error of GetConsoleMode and, if it's ERROR_ACCESS_DENIED, then use GetFileType to see if it returns FILE_TYPE_CHAR. We can't use GetFileType alone because, for example, the NUL device claims to be a character device.
EDIT: Maybe simpler, we could check if GetConsoleMode errors with ERROR_INVALID_HANDLE though I'm not 100% sure it'll always return that for non-console handles.
Alternatively we could just close this issue and say this is not our problem. Most applications and runtimes don't do anything special here and simply treat it as a non-console handle.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal Rust example and the std::io::IsTerminal implementation for Windows. Reproduce the write-only CONOUT$ case, then investigate how GetConsoleMode errors compare with GetFileType for console and NUL handles. Done means is_terminal correctly handles handles without read access without misclassifying NUL.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100