feature: AT_EMPTY_PATH
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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"]
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
pub const AT_FDCWD: i32 = -2;
|
||||
pub const AT_EMPTY_PATH: u32 = 1 << 16;
|
||||
|
||||
bitflags! {
|
||||
pub struct OpenFlags: u32 {
|
||||
|
||||
Reference in New Issue
Block a user