Modify all usages of the removed Path APIs
This commit is contained in:
parent
ce2217cbdb
commit
4468eda1ef
|
|
@ -200,8 +200,13 @@ impl FileIo for PtyMaster {
|
|||
|
||||
// TODO: Deal with `open()` flags.
|
||||
let slave = {
|
||||
let fs_ref = thread_local.borrow_fs();
|
||||
let path_resolver = fs_ref.resolver().read();
|
||||
|
||||
let slave_name = {
|
||||
let devpts_path = super::DEV_PTS.get().unwrap().abs_path();
|
||||
let devpts_path = path_resolver
|
||||
.make_abs_path(super::DEV_PTS.get().unwrap())
|
||||
.into_string();
|
||||
format!("{}/{}", devpts_path, self.slave.index())
|
||||
};
|
||||
|
||||
|
|
@ -209,12 +214,7 @@ impl FileIo for PtyMaster {
|
|||
|
||||
let inode_handle = {
|
||||
let open_args = OpenArgs::from_modes(AccessMode::O_RDWR, mkmod!(u+rw));
|
||||
thread_local
|
||||
.borrow_fs()
|
||||
.resolver()
|
||||
.read()
|
||||
.lookup(&fs_path)?
|
||||
.open(open_args)?
|
||||
path_resolver.lookup(&fs_path)?.open(open_args)?
|
||||
};
|
||||
Arc::new(inode_handle)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ pub fn add_node(
|
|||
(relative_path, "")
|
||||
};
|
||||
|
||||
match dev_path.lookup(next_name) {
|
||||
match path_resolver.lookup_at_path(&dev_path, next_name) {
|
||||
Ok(next_path) => {
|
||||
if path_remain.is_empty() {
|
||||
return_errno_with_message!(Errno::EEXIST, "the device node already exists");
|
||||
|
|
|
|||
|
|
@ -1489,6 +1489,9 @@ mod tests {
|
|||
let link = d1.create("link", InodeType::SymLink, mode).unwrap();
|
||||
let link_str = "link_to_somewhere";
|
||||
link.write_link(link_str).unwrap();
|
||||
assert_eq!(link.read_link().unwrap().to_string(), link_str.to_string());
|
||||
assert!(matches!(
|
||||
link.read_link().unwrap(),
|
||||
SymbolicLink::Plain(s) if s == link_str
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,10 @@ impl Path {
|
|||
return_errno_with_message!(Errno::ENOTDIR, "the path is not a directory");
|
||||
}
|
||||
|
||||
if self.effective_parent().is_none() {
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let path_resolver = fs_ref.resolver().read();
|
||||
|
||||
if path_resolver.root() == self {
|
||||
return_errno_with_message!(Errno::EINVAL, "the root cannot be mounted on");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,8 @@ impl FileOps for CommFileOps {
|
|||
return Ok(0);
|
||||
};
|
||||
|
||||
let exe_path = vmar.process_vm().executable_file().abs_path();
|
||||
let last_component = exe_path.rsplit('/').next().unwrap_or(&exe_path);
|
||||
let mut comm = last_component.as_bytes().to_vec();
|
||||
let executable_file_name = vmar.process_vm().executable_file().name();
|
||||
let mut comm = executable_file_name.as_bytes().to_vec();
|
||||
comm.truncate(TASK_COMM_LEN - 1);
|
||||
comm.push(b'\n');
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ impl FileOps for MountInfoFileOps {
|
|||
|
||||
let fs = posix_thread.read_fs();
|
||||
let path_resolver = fs.resolver().read();
|
||||
let root_mount = path_resolver.root().mount_node();
|
||||
|
||||
root_mount.read_mount_info(offset, writer)
|
||||
path_resolver.read_mount_info(offset, writer)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -427,6 +427,8 @@ fn test_sysfs_write_attr() {
|
|||
|
||||
#[ktest]
|
||||
fn test_sysfs_read_link() {
|
||||
use crate::fs::utils::SymbolicLink;
|
||||
|
||||
let sysfs = init_sysfs_with_mock_tree();
|
||||
let root_inode = sysfs.root_inode();
|
||||
// Action: Lookup the sysfs symlink corresponding to a systree symlink node
|
||||
|
|
@ -436,7 +438,10 @@ fn test_sysfs_read_link() {
|
|||
// the path provided by the underlying mock systree symlink node's target_path method.
|
||||
|
||||
let target = link1_inode.read_link().expect("read_link failed");
|
||||
assert_eq!(target.to_string(), "../branch1/leaf1");
|
||||
assert!(matches!(
|
||||
target,
|
||||
SymbolicLink::Plain(s) if s == "../branch1/leaf1"
|
||||
));
|
||||
|
||||
// read_link on non-symlink should fail (expect EINVAL as per inode.rs)
|
||||
let branch1_inode = root_inode.lookup("branch1").unwrap();
|
||||
|
|
|
|||
|
|
@ -605,13 +605,3 @@ pub enum SymbolicLink {
|
|||
/// such as `/proc/[pid]/fd/[fd]` and `/proc/[pid]/exe`.
|
||||
Path(Path),
|
||||
}
|
||||
|
||||
#[expect(clippy::to_string_trait_impl)]
|
||||
impl ToString for SymbolicLink {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
SymbolicLink::Plain(s) => s.clone(),
|
||||
SymbolicLink::Path(path) => path.abs_path(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -498,9 +498,16 @@ fn clone_child_process(
|
|||
|
||||
let child = {
|
||||
let mut child_thread_builder = {
|
||||
let child_thread_name = ThreadName::new_from_executable_path(
|
||||
&child_vmar.process_vm().executable_file().abs_path(),
|
||||
);
|
||||
let thread_name = {
|
||||
let executable_path = child_vmar.process_vm().executable_file();
|
||||
thread_local
|
||||
.borrow_fs()
|
||||
.resolver()
|
||||
.read()
|
||||
.make_abs_path(executable_path)
|
||||
.into_string()
|
||||
};
|
||||
let child_thread_name = ThreadName::new_from_executable_path(&thread_name);
|
||||
|
||||
let credentials = {
|
||||
let credentials = ctx.posix_thread.credentials();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ use ostd::{
|
|||
|
||||
use super::process_vm::activate_vmar;
|
||||
use crate::{
|
||||
fs::{path::Path, utils::Inode},
|
||||
fs::{
|
||||
path::{Path, PathResolver},
|
||||
utils::Inode,
|
||||
},
|
||||
prelude::*,
|
||||
process::{
|
||||
ContextUnshareAdminApi, Credentials, Process,
|
||||
|
|
@ -40,16 +43,17 @@ pub fn do_execve(
|
|||
// of all strings to enforce a sensible overall limit.
|
||||
let argv = read_cstring_vec(argv_ptr_ptr, MAX_NR_STRING_ARGS, MAX_LEN_STRING_ARG, ctx)?;
|
||||
let envp = read_cstring_vec(envp_ptr_ptr, MAX_NR_STRING_ARGS, MAX_LEN_STRING_ARG, ctx)?;
|
||||
debug!(
|
||||
"filename: {:?}, argv = {:?}, envp = {:?}",
|
||||
elf_file.abs_path(),
|
||||
argv,
|
||||
envp
|
||||
);
|
||||
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let path_resolver = fs_ref.resolver().read();
|
||||
|
||||
debug!(
|
||||
"file path: {:?}, argv = {:?}, envp = {:?}",
|
||||
path_resolver.make_abs_path(&elf_file).into_string(),
|
||||
argv,
|
||||
envp
|
||||
);
|
||||
|
||||
let elf_inode = elf_file.inode();
|
||||
let program_to_load =
|
||||
ProgramToLoad::build_from_inode(elf_inode.clone(), &path_resolver, argv, envp)?;
|
||||
|
|
@ -75,7 +79,14 @@ pub fn do_execve(
|
|||
// After this point, failures in subsequent operations are fatal: the process
|
||||
// state may be left inconsistent and it can never return to user mode.
|
||||
|
||||
let res = do_execve_no_return(ctx, user_context, elf_file, new_vmar, &elf_load_info);
|
||||
let res = do_execve_no_return(
|
||||
ctx,
|
||||
user_context,
|
||||
&path_resolver,
|
||||
elf_file,
|
||||
new_vmar,
|
||||
&elf_load_info,
|
||||
);
|
||||
|
||||
if res.is_err() {
|
||||
ctx.posix_thread
|
||||
|
|
@ -128,6 +139,7 @@ fn read_cstring_vec(
|
|||
fn do_execve_no_return(
|
||||
ctx: &Context,
|
||||
user_context: &mut UserContext,
|
||||
path_resolver: &PathResolver,
|
||||
elf_file: Path,
|
||||
new_vmar: Arc<Vmar>,
|
||||
elf_load_info: &ElfLoadInfo,
|
||||
|
|
@ -165,7 +177,7 @@ fn do_execve_no_return(
|
|||
unshare_and_close_files(ctx);
|
||||
|
||||
// Update the process's executable path and set the thread name
|
||||
let executable_path = elf_file.abs_path();
|
||||
let executable_path = path_resolver.make_abs_path(&elf_file).into_string();
|
||||
*posix_thread.thread_name().lock() = ThreadName::new_from_executable_path(&executable_path);
|
||||
|
||||
// Unshare and reset signal dispositions to their default actions.
|
||||
|
|
|
|||
|
|
@ -106,18 +106,23 @@ fn create_init_task(
|
|||
) -> Result<Arc<Task>> {
|
||||
let credentials = Credentials::new_root();
|
||||
|
||||
let elf_load_info = {
|
||||
let (elf_load_info, elf_abs_path) = {
|
||||
let path_resolver = fs.resolver().read();
|
||||
|
||||
let program_to_load =
|
||||
ProgramToLoad::build_from_inode(elf_path.inode().clone(), &path_resolver, argv, envp)?;
|
||||
let vmar = process.lock_vmar();
|
||||
program_to_load.load_to_vmar(vmar.unwrap(), &path_resolver)?
|
||||
let elf_load_info = program_to_load.load_to_vmar(vmar.unwrap(), &path_resolver)?;
|
||||
let elf_abs_path = path_resolver.make_abs_path(&elf_path).into_string();
|
||||
|
||||
(elf_load_info, elf_abs_path)
|
||||
};
|
||||
|
||||
let mut user_ctx = UserContext::default();
|
||||
user_ctx.set_instruction_pointer(elf_load_info.entry_point as _);
|
||||
user_ctx.set_stack_pointer(elf_load_info.user_stack_top as _);
|
||||
|
||||
let thread_name = ThreadName::new_from_executable_path(&elf_path.abs_path());
|
||||
let thread_name = ThreadName::new_from_executable_path(&elf_abs_path);
|
||||
|
||||
let thread_builder = PosixThreadBuilder::new(tid, thread_name, Box::new(user_ctx), credentials)
|
||||
.process(Arc::downgrade(process))
|
||||
|
|
|
|||
|
|
@ -3,14 +3,29 @@
|
|||
use ostd::mm::VmIo;
|
||||
|
||||
use super::SyscallReturn;
|
||||
use crate::prelude::*;
|
||||
use crate::{fs::path::AbsPathResult, prelude::*};
|
||||
|
||||
pub fn sys_getcwd(buf: Vaddr, len: usize, ctx: &Context) -> Result<SyscallReturn> {
|
||||
let dirent = ctx.thread_local.borrow_fs().resolver().read().cwd().clone();
|
||||
let name = dirent.abs_path();
|
||||
debug!("getcwd: {:?}", name);
|
||||
let abs_path = {
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let path_resolver = fs_ref.resolver().read();
|
||||
path_resolver.make_abs_path(path_resolver.cwd())
|
||||
};
|
||||
|
||||
let cwd = CString::new(name)?;
|
||||
debug!("getcwd: {:?}", abs_path);
|
||||
|
||||
// Linux will add a "(unreachable)" prefix to the path if the CWD is not reachable.
|
||||
// However, according to POSIX, `getcwd()` should fail with ENOENT in this case.
|
||||
// `glibc` treats the Linux's behavior as a bug and handles the Linux-specific prefix
|
||||
// to conform to POSIX. Here follows Linux's behavior to keep compatibility.
|
||||
//
|
||||
// Reference: <https://man7.org/linux/man-pages/man3/getcwd.3.html>
|
||||
let abs_path = match abs_path {
|
||||
AbsPathResult::Reachable(s) => s,
|
||||
AbsPathResult::Unreachable(s) => alloc::format!("(unreachable){}", s),
|
||||
};
|
||||
|
||||
let cwd = CString::new(abs_path)?;
|
||||
let bytes = cwd.as_bytes_with_nul();
|
||||
let write_len = len.min(bytes.len());
|
||||
ctx.user_space().write_bytes(buf, &bytes[..write_len])?;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use crate::{
|
|||
fs::{
|
||||
file_table::FileDesc,
|
||||
path::{AT_FDCWD, FsPath},
|
||||
utils::SymbolicLink,
|
||||
},
|
||||
prelude::*,
|
||||
syscall::constants::MAX_FILENAME_LEN,
|
||||
|
|
@ -26,18 +27,21 @@ pub fn sys_readlinkat(
|
|||
dirfd, path_name, usr_buf_addr, usr_buf_len
|
||||
);
|
||||
|
||||
let path = {
|
||||
let link_path = {
|
||||
let fs_ref = ctx.thread_local.borrow_fs();
|
||||
let path_resolver = fs_ref.resolver().read();
|
||||
|
||||
let path_name = path_name.to_string_lossy();
|
||||
let fs_path = FsPath::from_fd_and_path(dirfd, &path_name)?;
|
||||
ctx.thread_local
|
||||
.borrow_fs()
|
||||
.resolver()
|
||||
.read()
|
||||
.lookup_no_follow(&fs_path)?
|
||||
let path = path_resolver.lookup_no_follow(&fs_path)?;
|
||||
|
||||
match path.inode().read_link()? {
|
||||
SymbolicLink::Plain(s) => s,
|
||||
SymbolicLink::Path(path) => path_resolver.make_abs_path(&path).into_string(),
|
||||
}
|
||||
};
|
||||
|
||||
let linkpath = path.inode().read_link()?.to_string();
|
||||
let bytes = linkpath.as_bytes();
|
||||
let bytes = link_path.as_bytes();
|
||||
let write_len = bytes.len().min(usr_buf_len);
|
||||
user_space.write_bytes(usr_buf_addr, &bytes[..write_len])?;
|
||||
Ok(SyscallReturn::Return(write_len as _))
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub fn sys_renameat2(
|
|||
let old_fs_path = FsPath::from_fd_and_path(old_dirfd, old_parent_path_name)?;
|
||||
(path_resolver.lookup(&old_fs_path)?, old_name)
|
||||
};
|
||||
let old_path = old_dir_path.lookup(old_name)?;
|
||||
let old_path = path_resolver.lookup_at_path(&old_dir_path, old_name)?;
|
||||
if old_path.type_() != InodeType::Dir && old_path_name.ends_with('/') {
|
||||
return_errno_with_message!(Errno::ENOTDIR, "the old path is not a directory");
|
||||
}
|
||||
|
|
@ -60,8 +60,10 @@ pub fn sys_renameat2(
|
|||
};
|
||||
|
||||
// Check the absolute path
|
||||
let old_abs_path = old_path.abs_path();
|
||||
let new_abs_path = new_dir_path.abs_path() + "/" + new_name;
|
||||
// FIXME: Using string prefix matching to check for path containment is incorrect.
|
||||
// It doesn't handle path components like '..' or '.' properly.
|
||||
let old_abs_path = path_resolver.make_abs_path(&old_path).into_string();
|
||||
let new_abs_path = path_resolver.make_abs_path(&new_dir_path).into_string() + "/" + new_name;
|
||||
if new_abs_path.starts_with(&old_abs_path) {
|
||||
if new_abs_path.len() == old_abs_path.len() {
|
||||
return Ok(SyscallReturn::Return(0));
|
||||
|
|
|
|||
Loading…
Reference in New Issue