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