ygglibc/src/header/stdio/unlocked.rs

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)
}