1 use alloc::vec::Vec; 2 use core::ptr; 3 4 use crate::unix::{ 5 header::{stdio::FILE, stdlib}, 6 io::BufRead, 7 }; 8 9 #[no_mangle] 10 pub unsafe extern "C" fn __getline( 11 lineptr: *mut *mut ::c_char, 12 n: *mut ::size_t, 13 stream: *mut FILE, 14 ) -> ::ssize_t { 15 __getdelim(lineptr, n, b'\n' as ::c_int, stream) 16 } 17 18 #[no_mangle] 19 pub unsafe extern "C" fn __getdelim( 20 lineptr: *mut *mut ::c_char, 21 n: *mut ::size_t, 22 delim: ::c_int, 23 stream: *mut FILE, 24 ) -> ::ssize_t { 25 let lineptr = &mut *lineptr; 26 let n = &mut *n; 27 let delim = delim as u8; 28 29 //TODO: More efficient algorithm using lineptr and n instead of this vec 30 let mut buf = Vec::new(); 31 let count = { 32 let mut stream = (*stream).lock(); 33 match stream.read_until(delim, &mut buf) { 34 Ok(ok) => ok, 35 Err(err) => return -1, 36 } 37 }; 38 39 //TODO: Check errors and improve safety 40 { 41 // Allocate lineptr to size of buf and set n to size of lineptr 42 *n = count + 1; 43 *lineptr = stdlib::realloc(*lineptr as *mut ::c_void, *n) as *mut ::c_char; 44 45 // Copy buf to lineptr 46 ptr::copy(buf.as_ptr(), *lineptr as *mut u8, count); 47 48 // NUL terminate lineptr 49 *lineptr.offset(count as isize) = 0; 50 51 // Return allocated size 52 *n as ::ssize_t 53 } 54 } 55