@@ -207,32 +207,56 @@ pub(crate) mod module {
207207 fd : OptionalArg < i32 > ,
208208 vm : & VirtualMachine ,
209209 ) -> PyResult < _os:: TerminalSizeData > {
210- let ( columns, lines) = {
211- let stdhandle = match fd {
212- OptionalArg :: Present ( 0 ) => Console :: STD_INPUT_HANDLE ,
213- OptionalArg :: Present ( 1 ) | OptionalArg :: Missing => Console :: STD_OUTPUT_HANDLE ,
214- OptionalArg :: Present ( 2 ) => Console :: STD_ERROR_HANDLE ,
215- _ => return Err ( vm. new_value_error ( "bad file descriptor" ) ) ,
216- } ;
217- let h = unsafe { Console :: GetStdHandle ( stdhandle) } ;
218- if h. is_null ( ) {
219- return Err ( vm. new_os_error ( "handle cannot be retrieved" . to_owned ( ) ) ) ;
210+ let fd = fd. unwrap_or ( 1 ) ; // default to stdout
211+
212+ // For standard streams, use GetStdHandle which returns proper console handles
213+ // For other fds, use _get_osfhandle to convert
214+ let h = match fd {
215+ 0 => unsafe { Console :: GetStdHandle ( Console :: STD_INPUT_HANDLE ) } ,
216+ 1 => unsafe { Console :: GetStdHandle ( Console :: STD_OUTPUT_HANDLE ) } ,
217+ 2 => unsafe { Console :: GetStdHandle ( Console :: STD_ERROR_HANDLE ) } ,
218+ _ => {
219+ let borrowed = unsafe { crt_fd:: Borrowed :: borrow_raw ( fd) } ;
220+ let handle = crt_fd:: as_handle ( borrowed) . map_err ( |e| e. to_pyexception ( vm) ) ?;
221+ handle. as_raw_handle ( ) as _
220222 }
221- if h == INVALID_HANDLE_VALUE {
223+ } ;
224+
225+ if h. is_null ( ) || h == INVALID_HANDLE_VALUE {
226+ return Err ( errno_err ( vm) ) ;
227+ }
228+
229+ let mut csbi = MaybeUninit :: uninit ( ) ;
230+ let ret = unsafe { Console :: GetConsoleScreenBufferInfo ( h, csbi. as_mut_ptr ( ) ) } ;
231+ if ret == 0 {
232+ // If the handle doesn't have read access (e.g., conout$ opened with 'w'),
233+ // try opening CONOUT$ directly with read access like CPython does
234+ let conout: Vec < u16 > = "CONOUT$\0 " . encode_utf16 ( ) . collect ( ) ;
235+ let console_handle = unsafe {
236+ FileSystem :: CreateFileW (
237+ conout. as_ptr ( ) ,
238+ Foundation :: GENERIC_READ | Foundation :: GENERIC_WRITE ,
239+ FileSystem :: FILE_SHARE_READ | FileSystem :: FILE_SHARE_WRITE ,
240+ std:: ptr:: null ( ) ,
241+ FileSystem :: OPEN_EXISTING ,
242+ 0 ,
243+ std:: ptr:: null_mut ( ) ,
244+ )
245+ } ;
246+ if console_handle == INVALID_HANDLE_VALUE {
222247 return Err ( errno_err ( vm) ) ;
223248 }
224- let mut csbi = MaybeUninit :: uninit ( ) ;
225- let ret = unsafe { Console :: GetConsoleScreenBufferInfo ( h , csbi. as_mut_ptr ( ) ) } ;
226- let csbi = unsafe { csbi . assume_init ( ) } ;
249+ let ret =
250+ unsafe { Console :: GetConsoleScreenBufferInfo ( console_handle , csbi. as_mut_ptr ( ) ) } ;
251+ unsafe { Foundation :: CloseHandle ( console_handle ) } ;
227252 if ret == 0 {
228253 return Err ( errno_err ( vm) ) ;
229254 }
230- let w = csbi. srWindow ;
231- (
232- ( w. Right - w. Left + 1 ) as usize ,
233- ( w. Bottom - w. Top + 1 ) as usize ,
234- )
235- } ;
255+ }
256+ let csbi = unsafe { csbi. assume_init ( ) } ;
257+ let w = csbi. srWindow ;
258+ let columns = ( w. Right - w. Left + 1 ) as usize ;
259+ let lines = ( w. Bottom - w. Top + 1 ) as usize ;
236260 Ok ( _os:: TerminalSizeData { columns, lines } )
237261 }
238262
0 commit comments