11//! A module implementing an io type backed by the C runtime's file descriptors, i.e. what's
22//! returned from libc::open, even on windows.
33
4- use crate :: suppress_iph;
5- use std:: { cmp, ffi, fs, io, mem} ;
4+ use std:: { cmp, ffi, io} ;
65
76#[ cfg( windows) ]
87use libc:: commit as fsync;
@@ -21,10 +20,31 @@ pub type Offset = libc::off_t;
2120#[ cfg( windows) ]
2221pub type Offset = libc:: c_longlong ;
2322
23+ // copied from stdlib::os
24+ #[ cfg( windows) ]
25+ fn errno ( ) -> io:: Error {
26+ let err = io:: Error :: last_os_error ( ) ;
27+ // FIXME: probably not ideal, we need a bigger dichotomy between GetLastError and errno
28+ if err. raw_os_error ( ) == Some ( 0 ) {
29+ extern "C" {
30+ fn _get_errno ( pValue : * mut i32 ) -> i32 ;
31+ }
32+ let mut e = 0 ;
33+ unsafe { suppress_iph ! ( _get_errno( & mut e) ) } ;
34+ io:: Error :: from_raw_os_error ( e)
35+ } else {
36+ err
37+ }
38+ }
39+ #[ cfg( not( windows) ) ]
40+ fn errno ( ) -> io:: Error {
41+ io:: Error :: last_os_error ( )
42+ }
43+
2444#[ inline]
2545fn cvt < T , I : num_traits:: PrimInt > ( ret : I , f : impl FnOnce ( I ) -> T ) -> io:: Result < T > {
2646 if ret < I :: zero ( ) {
27- Err ( crate :: stdlib :: os :: errno ( ) )
47+ Err ( errno ( ) )
2848 } else {
2949 Ok ( f ( ret) )
3050 }
@@ -73,50 +93,16 @@ impl Fd {
7393 cvt ( unsafe { suppress_iph ! ( ftruncate( self . 0 , len) ) } , drop)
7494 }
7595
76- /// NOTE: it's not recommended to use ManuallyDrop::into_inner() to drop the file - it won't
77- /// work on all platforms, and will swallow any errors you might want to handle.
78- #[ allow( unused) ] // only used on windows atm
79- pub ( crate ) fn as_rust_file ( & self ) -> io:: Result < mem:: ManuallyDrop < fs:: File > > {
80- #[ cfg( windows) ]
81- let file = {
82- use std:: os:: windows:: io:: FromRawHandle ;
83- let handle = self . to_raw_handle ( ) ?;
84- unsafe { fs:: File :: from_raw_handle ( handle) }
85- } ;
86- #[ cfg( unix) ]
87- let file = {
88- let fd = self . 0 ;
89- use std:: os:: unix:: io:: FromRawFd ;
90- if fd < 0 {
91- return Err ( io:: Error :: from_raw_os_error ( libc:: EBADF ) ) ;
92- }
93- unsafe { fs:: File :: from_raw_fd ( fd) }
94- } ;
95- #[ cfg( target_os = "wasi" ) ]
96- let file = {
97- let fd = self . 0 ;
98- if fd < 0 {
99- return Err ( io:: Error :: from_raw_os_error ( libc:: EBADF ) ) ;
100- }
101- // SAFETY: as of now, File is a wrapper around WasiFd, which is a wrapper around
102- // wasi::Fd (u32). This isn't likely to change, and if it does change to a different
103- // sized integer, mem::transmute will fail.
104- unsafe { mem:: transmute :: < u32 , fs:: File > ( fd as u32 ) }
105- } ;
106- Ok ( mem:: ManuallyDrop :: new ( file) )
107- }
108-
10996 #[ cfg( windows) ]
110- pub ( crate ) fn to_raw_handle ( & self ) -> io:: Result < std:: os:: windows:: io:: RawHandle > {
111- use winapi:: um:: { handleapi:: INVALID_HANDLE_VALUE , winnt:: HANDLE } ;
97+ pub fn to_raw_handle ( & self ) -> io:: Result < std:: os:: windows:: io:: RawHandle > {
11298 extern "C" {
11399 fn _get_osfhandle ( fd : i32 ) -> libc:: intptr_t ;
114100 }
115- let handle = unsafe { suppress_iph ! ( _get_osfhandle( self . 0 ) ) } as HANDLE ;
116- if handle == INVALID_HANDLE_VALUE {
101+ let handle = unsafe { suppress_iph ! ( _get_osfhandle( self . 0 ) ) } ;
102+ if handle == - 1 {
117103 Err ( io:: Error :: last_os_error ( ) )
118104 } else {
119- Ok ( handle)
105+ Ok ( handle as _ )
120106 }
121107 }
122108}
0 commit comments