148 lines
3.5 KiB
Rust
148 lines
3.5 KiB
Rust
use core::ffi::{c_char, c_int, c_void, CStr};
|
|
|
|
use crate::{
|
|
error::{CEofResult, CFdResult, CIntZeroResult, CUsizeResult, OptionExt},
|
|
header::errno::EBADF,
|
|
};
|
|
|
|
use super::{stdin, stdout, FileFlags, FILE};
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn flockfile(stream: *mut FILE) {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.lock();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn ftrylockfile(stream: *mut FILE) -> CIntZeroResult {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.try_lock()?;
|
|
CIntZeroResult::OK
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn funlockfile(stream: *mut FILE) {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.unlock();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn feof_unlocked(stream: *mut FILE) -> c_int {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.has_flag_unlocked(FileFlags::EOF) as _
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn ferror_unlocked(stream: *mut FILE) -> c_int {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.has_flag_unlocked(FileFlags::ERROR) as _
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn clearerr_unlocked(stream: *mut FILE) {
|
|
let stream = stream.as_mut().unwrap();
|
|
stream.clear_error_unlocked();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn fileno_unlocked(stream: *mut FILE) -> CFdResult {
|
|
let stream = stream.as_mut().unwrap();
|
|
let fd = stream.as_raw_fd_opt_unlocked().e_ok_or(EBADF)?;
|
|
CFdResult::success(fd)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn fwrite_unlocked(
|
|
ptr: *mut c_void,
|
|
size: usize,
|
|
nmemb: usize,
|
|
stream: *mut FILE,
|
|
) -> CUsizeResult {
|
|
if ptr.is_null() {
|
|
panic!();
|
|
}
|
|
let stream = stream.as_mut().unwrap();
|
|
let data = core::slice::from_raw_parts(ptr as *const u8, size * nmemb);
|
|
|
|
let count = stream.write_unlocked(data)?;
|
|
|
|
CUsizeResult(count / size)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn fread_unlocked(
|
|
ptr: *mut c_void,
|
|
size: usize,
|
|
nmemb: usize,
|
|
stream: *mut FILE,
|
|
) -> CUsizeResult {
|
|
if ptr.is_null() {
|
|
panic!();
|
|
}
|
|
let stream = stream.as_mut().unwrap();
|
|
let data = core::slice::from_raw_parts_mut(ptr as *mut u8, size * nmemb);
|
|
|
|
let count = stream.read_unlocked(data)?;
|
|
|
|
CUsizeResult(count / size)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn fflush_unlocked(stream: *mut FILE) -> CEofResult {
|
|
if let Some(stream) = stream.as_mut() {
|
|
stream.flush_unlocked()?;
|
|
} else {
|
|
super::fflush_all_unlocked()?;
|
|
}
|
|
|
|
CEofResult(0)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn fgetc_unlocked(stream: *mut FILE) -> CEofResult {
|
|
let stream = stream.as_mut().unwrap();
|
|
let mut buf = [0];
|
|
match stream.read_unlocked(&mut buf)? {
|
|
1 => CEofResult(buf[0] as _),
|
|
_ => CEofResult::ERR,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn getc_unlocked(stream: *mut FILE) -> CEofResult {
|
|
fgetc_unlocked(stream)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn getchar_unlocked() -> CEofResult {
|
|
fgetc_unlocked(stdin)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn putchar_unlocked(c: c_int) -> CEofResult {
|
|
fputc_unlocked(c, stdout)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe fn fputc_unlocked(c: c_int, stream: *mut FILE) -> CEofResult {
|
|
let stream = stream.as_mut().unwrap();
|
|
|
|
stream.write_unlocked(&[c as u8])?;
|
|
|
|
CEofResult(0)
|
|
}
|
|
|
|
pub unsafe fn fputs_unlocked(s: *const c_char, stream: *mut FILE) -> CEofResult {
|
|
if s.is_null() {
|
|
panic!();
|
|
}
|
|
|
|
let s = CStr::from_ptr(s);
|
|
let stream = stream.as_mut().unwrap();
|
|
|
|
// TODO write_all_unlocked
|
|
stream.write_unlocked(s.to_bytes())?;
|
|
|
|
CEofResult(0)
|
|
}
|