std\sys\io\is_terminal/
windows.rs1use crate::ffi::c_void;
2use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
3use crate::sys::c;
4
5pub fn is_terminal(h: &impl AsHandle) -> bool {
6 handle_is_console(h.as_handle())
7}
8
9fn handle_is_console(handle: BorrowedHandle<'_>) -> bool {
10 if handle.as_raw_handle().is_null() {
12 return false;
13 }
14
15 let mut out = 0;
16 if unsafe { c::GetConsoleMode(handle.as_raw_handle(), &mut out) != 0 } {
17 return true;
19 }
20
21 msys_tty_on(handle)
23}
24
25fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool {
26 if unsafe { c::GetFileType(handle.as_raw_handle()) != c::FILE_TYPE_PIPE } {
28 return false;
29 }
30
31 #[repr(C)]
36 #[allow(non_snake_case)]
37 struct FILE_NAME_INFO {
38 FileNameLength: u32,
39 FileName: [u16; c::MAX_PATH as usize],
40 }
41 let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] };
42 let res = unsafe {
44 c::GetFileInformationByHandleEx(
45 handle.as_raw_handle(),
46 c::FileNameInfo,
47 (&raw mut name_info) as *mut c_void,
48 size_of::<FILE_NAME_INFO>() as u32,
49 )
50 };
51 if res == 0 {
52 return false;
53 }
54
55 let s = match name_info.FileName.get(..name_info.FileNameLength as usize / 2) {
57 None => return false,
58 Some(s) => s,
59 };
60 let name = String::from_utf16_lossy(s);
61 let name = name.rsplit('\\').next().unwrap_or(&name);
63 let is_msys = name.starts_with("msys-") || name.starts_with("cygwin-");
68 let is_pty = name.contains("-pty");
69 is_msys && is_pty
70}