19b0abe6dSLoGin use alloc::{string::String, sync::Arc}; 291e9d4abSLoGin use system_error::SystemError; 39b0abe6dSLoGin 491e9d4abSLoGin use crate::process::ProcessControlBlock; 59b0abe6dSLoGin 69b0abe6dSLoGin use super::{fcntl::AtFlags, FileType, IndexNode, ROOT_INODE}; 79b0abe6dSLoGin 8004e86ffSlogin /// @brief 切分路径字符串,返回最左侧那一级的目录名和剩余的部分。 9004e86ffSlogin /// 10004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为123, 第二个值为456/789 11bf4a4899SLoGin #[allow(dead_code)] 12004e86ffSlogin pub fn split_path(path: &str) -> (&str, Option<&str>) { 13004e86ffSlogin let mut path_split: core::str::SplitN<&str> = path.trim_matches('/').splitn(2, "/"); 14004e86ffSlogin let comp = path_split.next().unwrap_or(""); 15004e86ffSlogin let rest_opt = path_split.next(); 16004e86ffSlogin 17004e86ffSlogin return (comp, rest_opt); 18004e86ffSlogin } 19004e86ffSlogin 20004e86ffSlogin /// @brief 切分路径字符串,返回最右侧那一级的目录名和剩余的部分。 21004e86ffSlogin /// 22004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为789, 第二个值为123/456 23004e86ffSlogin pub fn rsplit_path(path: &str) -> (&str, Option<&str>) { 24004e86ffSlogin let mut path_split: core::str::RSplitN<&str> = path.trim_matches('/').rsplitn(2, "/"); 25004e86ffSlogin let comp = path_split.next().unwrap_or(""); 26004e86ffSlogin let rest_opt = path_split.next(); 27004e86ffSlogin 28004e86ffSlogin return (comp, rest_opt); 29004e86ffSlogin } 309b0abe6dSLoGin 319b0abe6dSLoGin /// 根据dirfd和path,计算接下来开始lookup的inode和剩余的path 329b0abe6dSLoGin /// 339b0abe6dSLoGin /// ## 返回值 349b0abe6dSLoGin /// 35bf4a4899SLoGin /// 返回值为(需要执行lookup的inode, 剩余的path) 369b0abe6dSLoGin pub fn user_path_at( 379b0abe6dSLoGin pcb: &Arc<ProcessControlBlock>, 389b0abe6dSLoGin dirfd: i32, 390fb515b0SLoGin path: &str, 409b0abe6dSLoGin ) -> Result<(Arc<dyn IndexNode>, String), SystemError> { 419b0abe6dSLoGin let mut inode = ROOT_INODE(); 420fb515b0SLoGin let ret_path; 439b0abe6dSLoGin // 如果path不是绝对路径,则需要拼接 449b0abe6dSLoGin if path.as_bytes()[0] != b'/' { 459b0abe6dSLoGin // 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录 469b0abe6dSLoGin if dirfd != AtFlags::AT_FDCWD.bits() { 479b0abe6dSLoGin let binding = pcb.fd_table(); 489b0abe6dSLoGin let fd_table_guard = binding.read(); 499b0abe6dSLoGin let file = fd_table_guard 509b0abe6dSLoGin .get_file_by_fd(dirfd) 519b0abe6dSLoGin .ok_or(SystemError::EBADF)?; 529b0abe6dSLoGin 539b0abe6dSLoGin // drop guard 以避免无法调度的问题 549b0abe6dSLoGin drop(fd_table_guard); 559b0abe6dSLoGin 569b0abe6dSLoGin // 如果dirfd不是目录,则返回错误码ENOTDIR 57*dfe53cf0SGnoCiYeH if file.file_type() != FileType::Dir { 589b0abe6dSLoGin return Err(SystemError::ENOTDIR); 599b0abe6dSLoGin } 609b0abe6dSLoGin 61*dfe53cf0SGnoCiYeH inode = file.inode(); 620fb515b0SLoGin ret_path = String::from(path); 639b0abe6dSLoGin } else { 649b0abe6dSLoGin let mut cwd = pcb.basic().cwd(); 659b0abe6dSLoGin cwd.push('/'); 660fb515b0SLoGin cwd.push_str(path); 670fb515b0SLoGin ret_path = cwd; 689b0abe6dSLoGin } 690fb515b0SLoGin } else { 700fb515b0SLoGin ret_path = String::from(path); 719b0abe6dSLoGin } 729b0abe6dSLoGin 730fb515b0SLoGin return Ok((inode, ret_path)); 749b0abe6dSLoGin } 75