diff --git a/fs/vfs/src/file.rs b/fs/vfs/src/file.rs index 1061aa2..a81f374 100644 --- a/fs/vfs/src/file.rs +++ b/fs/vfs/src/file.rs @@ -84,6 +84,13 @@ impl File { inner: FileInner::Normal(NormalFile { vnode, pos }), })) } + + pub fn node(&self) -> Option { + match &self.inner { + FileInner::Normal(inner) => Some(inner.vnode.clone()), + _ => None + } + } } impl Drop for File { diff --git a/init/src/main.rs b/init/src/main.rs index 0cc5405..591cbaa 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -5,11 +5,19 @@ #[macro_use] extern crate libusr; +use libusr::sys::{Stat, AT_FDCWD, OpenFlags, FileMode, AT_EMPTY_PATH}; + #[no_mangle] fn main() -> i32 { - println!("Pre-fork"); - let pid = unsafe { libusr::sys::sys_fork() }; - println!("Post-fork: {}", pid); + let mut stat = Stat::default(); + let fd = unsafe { + libusr::sys::sys_openat(AT_FDCWD, "/test.txt", FileMode::empty(), OpenFlags::O_RDONLY) + }; + println!("fd = {}", fd); + let ret = unsafe { + libusr::sys::sys_fstatat(fd, "", &mut stat, AT_EMPTY_PATH) + }; + println!("{}, {:?}", ret, stat); -1 } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 0b3f407..8dc1973 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -2,13 +2,17 @@ use crate::arch::platform::exception::ExceptionFrame; use crate::debug::Level; -use crate::proc::{elf, wait, Pid, Process}; +use crate::proc::{elf, process::ProcessIo, wait, Pid, Process}; use core::mem::size_of; +use core::ops::DerefMut; use core::time::Duration; use error::Errno; use libcommon::{Read, Write}; -use syscall::{abi, stat::AT_FDCWD}; -use vfs::{FileMode, OpenFlags, Stat}; +use syscall::{ + abi, + stat::{AT_EMPTY_PATH, AT_FDCWD}, +}; +use vfs::{FileMode, OpenFlags, Stat, VnodeRef}; mod arg; use arg::*; @@ -24,6 +28,25 @@ pub unsafe fn sys_fork(regs: &mut ExceptionFrame) -> Result { Process::current().fork(regs) } +fn find_at_node>( + io: &mut T, + at_fd: usize, + filename: &str, + empty_path: bool, +) -> Result { + let at = if at_fd as i32 != AT_FDCWD { + io.file(at_fd)?.borrow().node() + } else { + None + }; + + if empty_path && filename.is_empty() { + at.ok_or(Errno::InvalidArgument) + } else { + io.ioctx().find(at, filename, true) + } +} + /// Main system call dispatcher function pub fn syscall(num: usize, args: &[usize]) -> Result { match num { @@ -40,15 +63,15 @@ pub fn syscall(num: usize, args: &[usize]) -> Result { let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?; + let proc = Process::current(); + let mut io = proc.io.lock(); + let at = if at_fd as i32 == AT_FDCWD { None } else { - todo!(); + io.file(at_fd)?.borrow().node() }; - let proc = Process::current(); - let mut io = proc.io.lock(); - let file = io.ioctx().open(at, path, mode, opts)?; io.place_file(file) } @@ -67,20 +90,14 @@ pub fn syscall(num: usize, args: &[usize]) -> Result { io.file(args[0])?.borrow_mut().write(buf) } abi::SYS_FSTATAT => { - let proc = Process::current(); - let mut io = proc.io.lock(); - let fd = args[0]; + let at_fd = args[0]; let filename = validate_user_str(args[1], args[2])?; let buf = validate_user_ptr_struct::(args[3])?; + let flags = args[4] as u32; - // 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)?; + let proc = Process::current(); + let mut io = proc.io.lock(); + find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat(buf)?; Ok(0) } abi::SYS_CLOSE => { diff --git a/libusr/src/lib.rs b/libusr/src/lib.rs index 0b3f6d7..348c57a 100644 --- a/libusr/src/lib.rs +++ b/libusr/src/lib.rs @@ -3,13 +3,13 @@ use core::panic::PanicInfo; +pub mod io; pub mod mem; pub mod os; -pub mod io; pub mod sys { pub use syscall::calls::*; - pub use syscall::stat::{AT_FDCWD, Stat, OpenFlags, FileMode}; + pub use syscall::stat::{FileMode, OpenFlags, Stat, AT_EMPTY_PATH, AT_FDCWD}; } #[link_section = ".text._start"] diff --git a/syscall/src/calls.rs b/syscall/src/calls.rs index c63a6f5..bd30e0f 100644 --- a/syscall/src/calls.rs +++ b/syscall/src/calls.rs @@ -121,7 +121,7 @@ pub unsafe fn sys_write(fd: i32, data: &[u8]) -> isize { } #[inline(always)] -pub unsafe fn sys_fstatat(at: i32, pathname: &str, statbuf: &mut Stat, flags: i32) -> i32 { +pub unsafe fn sys_fstatat(at: i32, pathname: &str, statbuf: &mut Stat, flags: u32) -> i32 { syscall!( abi::SYS_FSTATAT, argn!(at), diff --git a/syscall/src/stat.rs b/syscall/src/stat.rs index ff5f5cc..0cb05ae 100644 --- a/syscall/src/stat.rs +++ b/syscall/src/stat.rs @@ -1,4 +1,5 @@ pub const AT_FDCWD: i32 = -2; +pub const AT_EMPTY_PATH: u32 = 1 << 16; bitflags! { pub struct OpenFlags: u32 {