55use std:: collections:: HashSet ;
66
77use std:: io:: prelude:: * ;
8+ #[ cfg( unix) ]
89use std:: os:: unix:: io:: { FromRawFd , IntoRawFd } ;
910
1011use std:: fs:: File ;
@@ -147,6 +148,31 @@ fn file_io_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
147148 Ok ( vm. ctx . new_bytes ( bytes) )
148149}
149150
151+ pub ( crate ) fn file_from_handle ( fd : i32 ) -> File {
152+ //unsafe block - creates file handle from the UNIX file descriptor
153+ //raw_fd is supported on UNIX only. This will need to be extended
154+ //to support windows - i.e. raw file_handles
155+ unsafe {
156+ #[ cfg( unix) ]
157+ return File :: from_raw_fd ( fd) ;
158+ #[ cfg( not( unix) ) ]
159+ {
160+ std:: mem:: drop ( fd) ; // suppress compiler warnings
161+ return std:: mem:: uninitialized :: < File > ( ) ;
162+ }
163+ }
164+ }
165+
166+ pub ( crate ) fn handle_from_file ( f : File ) -> Option < num_bigint:: BigInt > {
167+ #[ cfg( unix) ]
168+ return f. into_raw_fd ( ) . to_bigint ( ) ;
169+ #[ cfg( not( unix) ) ]
170+ {
171+ std:: mem:: drop ( f) ; // suppress compiler warnings
172+ return None ;
173+ }
174+ }
175+
150176fn file_io_readinto ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
151177 arg_check ! ( vm, args, required = [ ( file_io, None ) , ( obj, None ) ] ) ;
152178
@@ -163,12 +189,7 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
163189
164190 let file_no = file_io. get_attr ( "file_no" ) . unwrap ( ) ;
165191 let raw_fd = objint:: get_value ( & file_no) . to_i32 ( ) . unwrap ( ) ;
166-
167- //unsafe block - creates file handle from the UNIX file descriptor
168- //raw_fd is supported on UNIX only. This will need to be extended
169- //to support windows - i.e. raw file_handles
170- let handle = unsafe { File :: from_raw_fd ( raw_fd) } ;
171-
192+ let handle = file_from_handle ( raw_fd) ;
172193 let mut f = handle. take ( length) ;
173194 match obj. borrow_mut ( ) . payload {
174195 //TODO: Implement for MemoryView
@@ -182,7 +203,7 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
182203 _ => { }
183204 } ;
184205
185- let new_handle = f. into_inner ( ) . into_raw_fd ( ) . to_bigint ( ) ;
206+ let new_handle = handle_from_file ( f. into_inner ( ) ) ;
186207 vm. ctx
187208 . set_attr ( & file_io, "file_no" , vm. ctx . new_int ( new_handle. unwrap ( ) ) ) ;
188209 Ok ( vm. get_none ( ) )
@@ -197,18 +218,13 @@ fn file_io_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
197218
198219 let file_no = file_io. get_attr ( "file_no" ) . unwrap ( ) ;
199220 let raw_fd = objint:: get_value ( & file_no) . to_i32 ( ) . unwrap ( ) ;
200-
201- //unsafe block - creates file handle from the UNIX file descriptor
202- //raw_fd is supported on UNIX only. This will need to be extended
203- //to support windows - i.e. raw file_handles
204- let mut handle = unsafe { File :: from_raw_fd ( raw_fd) } ;
205-
221+ let mut handle = file_from_handle ( raw_fd) ;
206222 match obj. borrow_mut ( ) . payload {
207223 PyObjectPayload :: Bytes { ref mut value } => {
208224 match handle. write ( & value[ ..] ) {
209225 Ok ( len) => {
210226 //reset raw fd on the FileIO object
211- let new_handle = handle . into_raw_fd ( ) . to_bigint ( ) ;
227+ let new_handle = handle_from_file ( handle ) ;
212228 vm. ctx
213229 . set_attr ( & file_io, "file_no" , vm. ctx . new_int ( new_handle. unwrap ( ) ) ) ;
214230
0 commit comments