(
fd: OptionalArg<i32>,
vm: &VirtualMachine,
)
| 992 | |
| 993 | #[pyfunction] |
| 994 | fn get_terminal_size( |
| 995 | fd: OptionalArg<i32>, |
| 996 | vm: &VirtualMachine, |
| 997 | ) -> PyResult<_os::TerminalSizeData> { |
| 998 | let fd = fd.unwrap_or(1); // default to stdout |
| 999 | |
| 1000 | // Use _get_osfhandle for all fds |
| 1001 | let borrowed = unsafe { crt_fd::Borrowed::borrow_raw(fd) }; |
| 1002 | let handle = crt_fd::as_handle(borrowed).map_err(|e| e.to_pyexception(vm))?; |
| 1003 | let h = handle.as_raw_handle() as Foundation::HANDLE; |
| 1004 | |
| 1005 | let mut csbi = MaybeUninit::uninit(); |
| 1006 | let ret = unsafe { Console::GetConsoleScreenBufferInfo(h, csbi.as_mut_ptr()) }; |
| 1007 | if ret == 0 { |
| 1008 | // Check if error is due to lack of read access on a console handle |
| 1009 | // ERROR_ACCESS_DENIED (5) means it's a console but without read permission |
| 1010 | // In that case, try opening CONOUT$ directly with read access |
| 1011 | let err = unsafe { Foundation::GetLastError() }; |
| 1012 | if err != Foundation::ERROR_ACCESS_DENIED { |
| 1013 | return Err(vm.new_last_os_error()); |
| 1014 | } |
| 1015 | let conout: Vec<u16> = "CONOUT$\0".encode_utf16().collect(); |
| 1016 | let console_handle = unsafe { |
| 1017 | FileSystem::CreateFileW( |
| 1018 | conout.as_ptr(), |
| 1019 | Foundation::GENERIC_READ | Foundation::GENERIC_WRITE, |
| 1020 | FileSystem::FILE_SHARE_READ | FileSystem::FILE_SHARE_WRITE, |
| 1021 | core::ptr::null(), |
| 1022 | FileSystem::OPEN_EXISTING, |
| 1023 | 0, |
| 1024 | core::ptr::null_mut(), |
| 1025 | ) |
| 1026 | }; |
| 1027 | if console_handle == INVALID_HANDLE_VALUE { |
| 1028 | return Err(vm.new_last_os_error()); |
| 1029 | } |
| 1030 | let ret = |
| 1031 | unsafe { Console::GetConsoleScreenBufferInfo(console_handle, csbi.as_mut_ptr()) }; |
| 1032 | unsafe { Foundation::CloseHandle(console_handle) }; |
| 1033 | if ret == 0 { |
| 1034 | return Err(vm.new_last_os_error()); |
| 1035 | } |
| 1036 | } |
| 1037 | let csbi = unsafe { csbi.assume_init() }; |
| 1038 | let w = csbi.srWindow; |
| 1039 | let columns = (w.Right - w.Left + 1) as usize; |
| 1040 | let lines = (w.Bottom - w.Top + 1) as usize; |
| 1041 | Ok(_os::TerminalSizeData { columns, lines }) |
| 1042 | } |
| 1043 | |
| 1044 | #[cfg(target_env = "msvc")] |
| 1045 | unsafe extern "C" { |
nothing calls this directly
no test coverage detected