106 lines
2.9 KiB
Rust
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(())
|
|
}
|
|
}
|