122 lines
3.4 KiB
Rust
122 lines
3.4 KiB
Rust
#![allow(missing_docs)]
|
|
|
|
pub mod poll {
|
|
pub use abi::io::PollControl;
|
|
}
|
|
|
|
pub use abi::io::{
|
|
options, AccessMode, DirectoryEntry, FileAttr, FileMetadataUpdate, FileMetadataUpdateMode,
|
|
FileMode, FileSync, FileTimesUpdate, FileType, OpenOptions, RawFd, RemoveFlags, Rename,
|
|
SeekFrom, TimerOptions,
|
|
};
|
|
pub use abi::option::OptionSizeHint;
|
|
|
|
pub mod device;
|
|
pub mod filesystem;
|
|
pub mod input;
|
|
pub mod paths;
|
|
pub mod terminal;
|
|
pub use paths::*;
|
|
|
|
use core::mem::MaybeUninit;
|
|
|
|
use abi::{error::Error, option::OptionValue, process::ProcessId};
|
|
|
|
pub fn read_pid_fd(fd: RawFd) -> Result<(ProcessId, i32), Error> {
|
|
let mut buffer = [0; size_of::<u32>() + size_of::<i32>()];
|
|
let len = unsafe { crate::sys::read(fd, &mut buffer) }?;
|
|
assert_eq!(len, buffer.len());
|
|
let mut word = [0; size_of::<u32>()];
|
|
word.copy_from_slice(&buffer[0..4]);
|
|
let pid = unsafe { ProcessId::from_raw(u32::from_ne_bytes(word)) };
|
|
word.copy_from_slice(&buffer[4..8]);
|
|
let status = i32::from_ne_bytes(word);
|
|
Ok((pid, status))
|
|
}
|
|
|
|
pub fn remove_file(at: Option<RawFd>, path: &str) -> Result<(), Error> {
|
|
unsafe { crate::sys::remove(at, path, RemoveFlags::empty()) }
|
|
}
|
|
|
|
pub fn remove_directory(at: Option<RawFd>, path: &str) -> Result<(), Error> {
|
|
unsafe { crate::sys::remove(at, path, RemoveFlags::DIRECTORY_ONLY) }
|
|
}
|
|
|
|
pub fn remove_directory_recursive(_at: Option<RawFd>, _path: &str) -> Result<(), Error> {
|
|
todo!()
|
|
}
|
|
|
|
fn configure_pipe(
|
|
read: RawFd,
|
|
write: RawFd,
|
|
read_nonblocking: bool,
|
|
write_nonblocking: bool,
|
|
) -> Result<(), Error> {
|
|
if read_nonblocking {
|
|
set_file_option::<options::NonBlocking>(read, &true)?;
|
|
}
|
|
if write_nonblocking {
|
|
set_file_option::<options::NonBlocking>(write, &true)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn create_pipe_pair(
|
|
read_nonblocking: bool,
|
|
write_nonblocking: bool,
|
|
) -> Result<(RawFd, RawFd), Error> {
|
|
let mut fds = [MaybeUninit::uninit(); 2];
|
|
unsafe { crate::sys::create_pipe(&mut fds) }?;
|
|
let fds = unsafe { MaybeUninit::array_assume_init(fds) };
|
|
let read = fds[0];
|
|
let write = fds[1];
|
|
|
|
match configure_pipe(read, write, read_nonblocking, write_nonblocking) {
|
|
Ok(()) => Ok((read, write)),
|
|
Err(error) => {
|
|
unsafe {
|
|
crate::sys::close(read).ok();
|
|
crate::sys::close(write).ok();
|
|
}
|
|
Err(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub macro get_file_option($fd:expr, $variant_ty:ty) {{
|
|
let mut buffer = [0; <$variant_ty as $crate::io::OptionSizeHint>::SIZE_HINT];
|
|
$crate::io::get_file_option::<$variant_ty>($fd, &mut buffer)
|
|
}}
|
|
|
|
pub fn get_file_option<'de, T: OptionValue<'de>>(
|
|
fd: RawFd,
|
|
buffer: &'de mut [u8],
|
|
) -> Result<T::Value, Error> {
|
|
let len = unsafe { crate::sys::get_file_option(fd, T::VARIANT.into(), buffer) }?;
|
|
T::load(&buffer[..len])
|
|
}
|
|
|
|
pub fn set_file_option<'de, T: OptionValue<'de> + OptionSizeHint>(
|
|
fd: RawFd,
|
|
value: &T::Value,
|
|
) -> Result<(), Error>
|
|
where
|
|
[u8; T::SIZE_HINT]: Sized,
|
|
{
|
|
let mut buffer = [0; T::SIZE_HINT];
|
|
set_file_option_with::<T>(fd, &mut buffer, value)
|
|
}
|
|
|
|
pub fn set_file_option_with<'de, T: OptionValue<'de>>(
|
|
fd: RawFd,
|
|
buffer: &mut [u8],
|
|
value: &T::Value,
|
|
) -> Result<(), Error> {
|
|
let len = T::store(value, buffer)?;
|
|
unsafe { crate::sys::set_file_option(fd, T::VARIANT.into(), &buffer[..len]) }
|
|
}
|
|
|
|
pub fn set_nonblocking(fd: RawFd, nonblocking: bool) -> Result<(), Error> {
|
|
set_file_option::<options::NonBlocking>(fd, &nonblocking)
|
|
}
|