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