feature: AT_EMPTY_PATH

This commit is contained in:
2021-11-05 13:01:02 +02:00
parent f63a663b40
commit 0d2ea0f11f
6 changed files with 57 additions and 24 deletions
+7
View File
@@ -84,6 +84,13 @@ impl File {
inner: FileInner::Normal(NormalFile { vnode, pos }),
}))
}
pub fn node(&self) -> Option<VnodeRef> {
match &self.inner {
FileInner::Normal(inner) => Some(inner.vnode.clone()),
_ => None
}
}
}
impl Drop for File {
+11 -3
View File
@@ -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
}
+35 -18
View File
@@ -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<Pid, Errno> {
Process::current().fork(regs)
}
fn find_at_node<T: DerefMut<Target = ProcessIo>>(
io: &mut T,
at_fd: usize,
filename: &str,
empty_path: bool,
) -> Result<VnodeRef, Errno> {
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<usize, Errno> {
match num {
@@ -40,15 +63,15 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
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<usize, Errno> {
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::<Stat>(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 => {
+2 -2
View File
@@ -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"]
+1 -1
View File
@@ -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),
+1
View File
@@ -1,4 +1,5 @@
pub const AT_FDCWD: i32 = -2;
pub const AT_EMPTY_PATH: u32 = 1 << 16;
bitflags! {
pub struct OpenFlags: u32 {