@@ -165,95 +165,70 @@ pub fn fwrite_refcount(a0: AnyPtr, a1: u64, a2: u64, a3: Ptr<::std::fs::File>) -
165165 ( written_bytes / a1 as usize ) as u64
166166}
167167
168+ unsafe extern "C" {
169+ #[ cfg( target_os = "linux" ) ]
170+ #[ link_name = "stdin" ]
171+ static mut LIBC_STDIN : * mut libc:: FILE ;
172+ #[ cfg( target_os = "linux" ) ]
173+ #[ link_name = "stdout" ]
174+ static mut LIBC_STDOUT : * mut libc:: FILE ;
175+ #[ cfg( target_os = "linux" ) ]
176+ #[ link_name = "stderr" ]
177+ static mut LIBC_STDERR : * mut libc:: FILE ;
178+
179+ #[ cfg( target_os = "macos" ) ]
180+ #[ link_name = "__stdinp" ]
181+ static mut LIBC_STDIN : * mut libc:: FILE ;
182+ #[ cfg( target_os = "macos" ) ]
183+ #[ link_name = "__stdoutp" ]
184+ static mut LIBC_STDOUT : * mut libc:: FILE ;
185+ #[ cfg( target_os = "macos" ) ]
186+ #[ link_name = "__stderrp" ]
187+ static mut LIBC_STDERR : * mut libc:: FILE ;
188+ }
189+
190+ /// # Safety
191+ ///
192+ /// Returns the libc `stdin` handle. The pointer is valid for the process
193+ /// lifetime.
194+ pub unsafe fn stdin_unsafe ( ) -> * mut libc:: FILE {
195+ unsafe { LIBC_STDIN }
196+ }
197+
198+ /// # Safety
199+ ///
200+ /// Returns the libc `stdout` handle.
201+ pub unsafe fn stdout_unsafe ( ) -> * mut libc:: FILE {
202+ unsafe { LIBC_STDOUT }
203+ }
204+
168205/// # Safety
169206///
170- /// `a0` must point to a readable buffer of at least `a1 * a2` bytes, and `a3`
171- /// must point to a valid, open `std::fs::File`.
207+ /// Returns the libc `stderr` handle.
208+ pub unsafe fn stderr_unsafe ( ) -> * mut libc:: FILE {
209+ unsafe { LIBC_STDERR }
210+ }
211+
212+ /// # Safety
213+ ///
214+ /// Same contract as C's `fwrite`.
172215pub unsafe fn fwrite_unsafe (
173216 a0 : * const :: std:: ffi:: c_void ,
174217 a1 : u64 ,
175218 a2 : u64 ,
176- a3 : * mut :: std :: fs :: File ,
219+ a3 : * mut libc :: FILE ,
177220) -> u64 {
178- let total = a1. saturating_mul ( a2) as usize ;
179- let mut src = a0 as * const u8 ;
180-
181- let f = unsafe { ( * a3) . try_clone ( ) . expect ( "try_clone failed" ) } ;
182- let mut writer = std:: io:: BufWriter :: with_capacity ( 64 * 1024 , f) ;
183-
184- let mut written_bytes: usize = 0 ;
185- let mut buffer: [ u8 ; 8192 ] = [ 0 ; 8192 ] ;
186-
187- while written_bytes < total {
188- let remaining = total - written_bytes;
189- let to_fill = std:: cmp:: min ( buffer. len ( ) , remaining) ;
190-
191- for b in buffer. iter_mut ( ) . take ( to_fill) {
192- unsafe {
193- * b = * src;
194- src = src. offset ( 1 ) ;
195- }
196- }
197-
198- let mut off = 0 ;
199- while off < to_fill {
200- match std:: io:: Write :: write ( & mut writer, & buffer[ off..to_fill] ) {
201- Ok ( 0 ) => break ,
202- Ok ( n) => off += n,
203- Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
204- Err ( e) => panic ! ( "Unhandled error in fwrite: {e}" ) ,
205- }
206- }
207-
208- if off == 0 {
209- break ;
210- }
211-
212- written_bytes += off;
213- }
214-
215- ( written_bytes / a1 as usize ) as u64
221+ unsafe { libc:: fwrite ( a0, a1 as libc:: size_t , a2 as libc:: size_t , a3) as u64 }
216222}
217223
218224/// # Safety
219225///
220- /// `a0` must point to a writable buffer of at least `a1 * a2` bytes, and `a3`
221- /// must point to a valid, open `std::fs::File`.
226+ /// Same contract as C's `fread`.
222227pub unsafe fn fread_unsafe (
223228 a0 : * mut :: std:: ffi:: c_void ,
224229 a1 : u64 ,
225230 a2 : u64 ,
226- a3 : * mut :: std :: fs :: File ,
231+ a3 : * mut libc :: FILE ,
227232) -> u64 {
228- let total = a1. saturating_mul ( a2) as usize ;
229- let mut dst = a0 as * mut u8 ;
230-
231- let f = unsafe { ( * a3) . try_clone ( ) . expect ( "try_clone failed" ) } ;
232- let mut reader = std:: io:: BufReader :: with_capacity ( 64 * 1024 , f) ;
233-
234- let mut read_bytes: usize = 0 ;
235- let mut buffer: [ u8 ; 8192 ] = [ 0 ; 8192 ] ;
236-
237- while read_bytes < total {
238- let remaining = total - read_bytes;
239- let to_read = std:: cmp:: min ( buffer. len ( ) , remaining) ;
240-
241- let n = match std:: io:: Read :: read ( & mut reader, & mut buffer[ ..to_read] ) {
242- Ok ( 0 ) => break ,
243- Ok ( n) => n,
244- Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: Interrupted => continue ,
245- Err ( e) => panic ! ( "Unhandled error in fread: {e}" ) ,
246- } ;
247-
248- for & byte in & buffer[ ..n] {
249- unsafe {
250- * dst = byte;
251- dst = dst. offset ( 1 ) ;
252- }
253- }
254-
255- read_bytes += n;
256- }
257-
258- ( read_bytes / a1 as usize ) as u64
233+ unsafe { libc:: fread ( a0, a1 as libc:: size_t , a2 as libc:: size_t , a3) as u64 }
259234}
0 commit comments