yggdrasil/lib/abi/src/io/file.rs

106 lines
2.9 KiB
Rust

use core::fmt;
use abi_lib::SyscallRegister;
use crate::time::SystemTime;
use super::FileMode;
/// Describes an action done on a file descriptor
#[derive(Debug)]
pub enum FileControl {}
/// Describes an operation to perform when updating certain file metadata elements
#[derive(Debug, Clone)]
pub enum FileMetadataUpdateMode {
/// value = new
Set,
/// value = old | new
Or,
/// value = old & new
And,
/// value = old & !new
AndNot,
}
/// Describes how file times are updated
#[derive(Debug, Clone)]
pub struct FileTimesUpdate {
/// Last accessed time
pub atime: Option<SystemTime>,
/// Last modified time
pub mtime: Option<SystemTime>,
/// Created time
pub ctime: Option<SystemTime>,
}
/// Describes a modification to a file's metadata
#[derive(Debug, Clone)]
pub enum FileMetadataUpdate {
/// Changes file permissions
Permissions(FileMode, FileMetadataUpdateMode),
/// Changes file mtime/atime/ctime
Times(FileTimesUpdate),
}
/// Describes a seek operation for a regular file
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SeekFrom {
/// Argument is an offset from the start of the file
Start(u64),
/// Argument is an offset from the end of the file
End(i64),
/// Argument is an offset from the current position
Current(i64),
}
impl SyscallRegister for SeekFrom {
fn into_syscall_register(self) -> usize {
match self {
SeekFrom::Start(value) => (value as usize) << 2,
SeekFrom::End(value) => (value << 2) as usize | 1,
SeekFrom::Current(value) => (value << 2) as usize | 2,
}
}
fn from_syscall_register(value: usize) -> Self {
let dir = value & 0x3;
match dir {
0 => Self::Start((value as u64) >> 2),
1 => Self::End((value as i64) >> 2),
2 => Self::Current((value as i64) >> 2),
_ => unreachable!(),
}
}
}
impl fmt::Display for FileMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
macro_rules! print_bit {
($res:expr, $val:expr, $self:expr, $bit:expr) => {
if $self.contains($bit) {
$res = $val;
}
};
}
let mut buf = ['-'; 9];
print_bit!(buf[0], 'r', self, Self::USER_READ);
print_bit!(buf[1], 'w', self, Self::USER_WRITE);
print_bit!(buf[2], 'x', self, Self::USER_EXEC);
print_bit!(buf[3], 'r', self, Self::GROUP_READ);
print_bit!(buf[4], 'w', self, Self::GROUP_WRITE);
print_bit!(buf[5], 'x', self, Self::GROUP_EXEC);
print_bit!(buf[6], 'r', self, Self::OTHER_READ);
print_bit!(buf[7], 'w', self, Self::OTHER_WRITE);
print_bit!(buf[8], 'x', self, Self::OTHER_EXEC);
for ch in buf.iter() {
fmt::Display::fmt(ch, f)?;
}
Ok(())
}
}