feature: add Stat struct and fstatat()

This commit is contained in:
2021-11-03 16:15:22 +02:00
parent ad17789d94
commit 53a432bc05
15 changed files with 130 additions and 67 deletions
Generated
+1 -56
View File
@@ -2,17 +2,6 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@@ -81,26 +70,6 @@ dependencies = [
"unsafe_unwrap",
]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]]
name = "init"
version = "0.1.0"
@@ -124,12 +93,6 @@ dependencies = [
"vfs",
]
[[package]]
name = "libc"
version = "0.2.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce"
[[package]]
name = "libcommon"
version = "0.1.0"
@@ -182,12 +145,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "osdev5"
version = "0.1.0"
@@ -273,23 +230,11 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "vfs"
version = "0.1.0"
dependencies = [
"error",
"hashbrown",
"libcommon",
"syscall",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+5 -1
View File
@@ -1,4 +1,4 @@
use vfs::{VnodeImpl, VnodeKind, VnodeRef, Vnode};
use vfs::{VnodeImpl, VnodeKind, VnodeRef, Vnode, Stat};
use alloc::boxed::Box;
use error::Errno;
@@ -50,5 +50,9 @@ impl VnodeImpl for DirInode {
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
todo!()
}
fn stat(&mut self, _node: VnodeRef, _stat: &mut Stat) -> Result<(), Errno> {
todo!();
}
}
+8 -1
View File
@@ -1,4 +1,4 @@
use vfs::{VnodeImpl, VnodeKind, VnodeRef};
use vfs::{VnodeImpl, VnodeKind, VnodeRef, Stat};
use error::Errno;
use crate::{BlockAllocator, Bvec};
@@ -53,4 +53,11 @@ impl<'a, A: BlockAllocator + Copy + 'static> VnodeImpl for FileInode<'a, A> {
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
Ok(self.data.size())
}
fn stat(&mut self, node: VnodeRef, stat: &mut Stat) -> Result<(), Errno> {
stat.size = self.data.size() as u64;
stat.blksize = 4096;
stat.mode = 0o755;
Ok(())
}
}
+1 -1
View File
@@ -8,4 +8,4 @@ edition = "2021"
[dependencies]
error = { path = "../../error" }
libcommon = { path = "../../libcommon" }
hashbrown = "0.11.*"
syscall = { path = "../../syscall" }
+5 -1
View File
@@ -1,4 +1,4 @@
use crate::{VnodeImpl, VnodeKind, VnodeRef};
use crate::{VnodeImpl, VnodeKind, VnodeRef, Stat};
use error::Errno;
/// Generic character device trait
@@ -59,6 +59,10 @@ impl VnodeImpl for CharDeviceWrapper {
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
panic!();
}
fn stat(&mut self, _node: VnodeRef, _stat: &mut Stat) -> Result<(), Errno> {
todo!();
}
}
impl CharDeviceWrapper {
+2
View File
@@ -9,6 +9,8 @@ extern crate std;
extern crate alloc;
pub use syscall::stat::Stat;
mod block;
pub use block::BlockDevice;
mod fs;
+13 -1
View File
@@ -1,4 +1,4 @@
use crate::{File, FileMode, Filesystem};
use crate::{File, FileMode, Filesystem, Stat};
use alloc::{borrow::ToOwned, boxed::Box, rc::Rc, string::String, vec::Vec};
use core::cell::{RefCell, RefMut};
use core::fmt;
@@ -70,6 +70,9 @@ pub trait VnodeImpl {
/// Resizes the file storage if necessary.
fn write(&mut self, node: VnodeRef, pos: usize, data: &[u8]) -> Result<usize, Errno>;
/// Retrieves file status
fn stat(&mut self, node: VnodeRef, stat: &mut Stat) -> Result<(), Errno>;
/// Reports the size of this filesystem object in bytes
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno>;
}
@@ -339,6 +342,15 @@ impl Vnode {
Err(Errno::NotImplemented)
}
}
/// Reports file status
pub fn stat(self: &VnodeRef, stat: &mut Stat) -> Result<(), Errno> {
if let Some(ref mut data) = *self.data() {
data.stat(self.clone(), stat)
} else {
Err(Errno::NotImplemented)
}
}
}
impl fmt::Debug for Vnode {
+5
View File
@@ -5,13 +5,18 @@
#[macro_use]
extern crate libusr;
use libusr::io;
#[no_mangle]
fn main() -> i32 {
let mut buf = [0; 128];
let stat = io::stat("/test.txt").unwrap();
print!("\x1B[2J\x1B[1;1H");
println!("Hello!");
println!("test.txt: {:?}", stat);
loop {
print!("> ");
+28 -1
View File
@@ -5,7 +5,10 @@ use core::mem::size_of;
use core::time::Duration;
use error::Errno;
use libcommon::{Read, Write};
use syscall::abi;
use syscall::{
abi,
stat::{Stat, AT_FDCWD},
};
fn translate(virt: usize) -> Option<usize> {
let mut res: usize;
@@ -19,6 +22,13 @@ fn translate(virt: usize) -> Option<usize> {
}
}
fn validate_user_ptr_struct<'a, T>(base: usize) -> Result<&'a mut T, Errno> {
let bytes = validate_user_ptr(base, size_of::<T>())?;
Ok(unsafe {
&mut *(bytes.as_mut_ptr() as *mut T)
})
}
fn validate_user_ptr<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Errno> {
if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET {
warnln!(
@@ -133,6 +143,23 @@ pub unsafe fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
io.file(args[0])?.write(buf)
}
abi::SYS_FSTATAT => {
let proc = Process::current();
let mut io = proc.io.lock();
let fd = args[0];
let filename = validate_user_str(args[1], 256)?;
let buf = validate_user_ptr_struct::<Stat>(args[2])?;
// TODO "self" flag
let at = if fd as i32 != AT_FDCWD {
todo!();
} else {
None
};
let node = io.ioctx().find(at, filename, true)?;
node.stat(buf)?;
Ok(0)
}
// Extra system calls
abi::SYS_EX_DEBUG_TRACE => {
+22 -1
View File
@@ -1,8 +1,29 @@
use crate::sys;
use crate::sys::{self, Stat};
use syscall::stat::AT_FDCWD;
use core::mem::MaybeUninit;
use core::fmt;
const STDOUT_FILENO: i32 = 0;
pub fn stat(pathname: &str) -> Result<Stat, ()> {
let mut buf = MaybeUninit::<Stat>::uninit();
let mut path = [0u8; 256];
let bytes = pathname.as_bytes();
path[..pathname.len()].copy_from_slice(&bytes);
path[pathname.len()] = 0;
unsafe {
let res = sys::sys_fstatat(AT_FDCWD, path.as_ptr(), buf.as_mut_ptr(), 0);
if res != 0 {
todo!();
}
Ok(buf.assume_init())
}
}
// print!/println! group
#[macro_export]
macro_rules! print {
($($args:tt)+) => ($crate::io::_print(format_args!($($args)+)))
+2 -1
View File
@@ -8,7 +8,8 @@ pub mod os;
pub mod io;
pub mod sys {
pub use syscall::*;
pub use syscall::calls::*;
pub use syscall::stat::Stat;
}
#[link_section = ".text._start"]
+1
View File
@@ -7,3 +7,4 @@ pub const SYS_EXIT: usize = 1;
pub const SYS_READ: usize = 2;
pub const SYS_WRITE: usize = 3;
pub const SYS_OPEN: usize = 4;
pub const SYS_FSTATAT: usize = 5;
+25 -1
View File
@@ -1,4 +1,5 @@
use crate::abi;
use crate::stat::Stat;
macro_rules! syscall {
($num:expr, $a0:expr) => {{
@@ -22,6 +23,13 @@ macro_rules! syscall {
in("x8") $num, options(nostack));
res
}};
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => {{
let mut res: usize = $a0;
asm!("svc #0",
inout("x0") res, in("x1") $a1, in("x2") $a2,
in("x3") $a3, in("x8") $num, options(nostack));
res
}};
}
#[inline(always)]
@@ -42,7 +50,12 @@ pub unsafe fn sys_ex_debug_trace(msg: *const u8, len: usize) -> usize {
#[inline(always)]
pub unsafe fn sys_open(pathname: *const u8, mode: u32, flags: u32) -> i32 {
syscall!(abi::SYS_OPEN, pathname as usize, mode as usize, flags as usize) as i32
syscall!(
abi::SYS_OPEN,
pathname as usize,
mode as usize,
flags as usize
) as i32
}
#[inline(always)]
@@ -54,3 +67,14 @@ pub unsafe fn sys_read(fd: i32, data: *mut u8, len: usize) -> isize {
pub unsafe fn sys_write(fd: i32, data: *const u8, len: usize) -> isize {
syscall!(abi::SYS_WRITE, fd as usize, data as usize, len) as isize
}
#[inline(always)]
pub unsafe fn sys_fstatat(at: i32, pathname: *const u8, statbuf: *mut Stat, flags: i32) -> i32 {
syscall!(
abi::SYS_FSTATAT,
at as usize,
pathname as usize,
statbuf as usize,
flags as usize
) as i32
}
+3 -2
View File
@@ -5,9 +5,10 @@
compile_error!("Not yet implemented");
pub mod abi;
pub use abi::*;
pub mod stat;
#[cfg(feature = "user")]
mod calls;
pub mod calls;
#[cfg(feature = "user")]
pub use calls::*;
+9
View File
@@ -0,0 +1,9 @@
pub const AT_FDCWD: i32 = -2;
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Stat {
pub mode: u32,
pub size: u64,
pub blksize: u32,
}