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.
Activity
ChrisDenton commentedon Sep 28, 2024
Ideally we could use
NtQueryVolumeInformationFile
withFileFsDeviceInformation
to get the device type. This doesn't have the problem ofGetFileType
and we also don't need any complex inference. However, I hesitate to suggest this as we do try to use win32 functions unless there's no alternative.estebank commentedon Oct 2, 2024
We could also try and lint against calling
is_terminal
on a read-only handle. But I'd prefer using the alternative proposed platform APIs instead.