1*9b0abe6dSLoGin use alloc::{string::String, sync::Arc}; 2*9b0abe6dSLoGin 3*9b0abe6dSLoGin use crate::{process::ProcessControlBlock, syscall::SystemError}; 4*9b0abe6dSLoGin 5*9b0abe6dSLoGin use super::{fcntl::AtFlags, FileType, IndexNode, ROOT_INODE}; 6*9b0abe6dSLoGin 7004e86ffSlogin /// @brief 切分路径字符串,返回最左侧那一级的目录名和剩余的部分。 8004e86ffSlogin /// 9004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为123, 第二个值为456/789 10004e86ffSlogin pub fn split_path(path: &str) -> (&str, Option<&str>) { 11004e86ffSlogin let mut path_split: core::str::SplitN<&str> = path.trim_matches('/').splitn(2, "/"); 12004e86ffSlogin let comp = path_split.next().unwrap_or(""); 13004e86ffSlogin let rest_opt = path_split.next(); 14004e86ffSlogin 15004e86ffSlogin return (comp, rest_opt); 16004e86ffSlogin } 17004e86ffSlogin 18004e86ffSlogin /// @brief 切分路径字符串,返回最右侧那一级的目录名和剩余的部分。 19004e86ffSlogin /// 20004e86ffSlogin /// 举例:对于 /123/456/789/ 本函数返回的第一个值为789, 第二个值为123/456 21004e86ffSlogin pub fn rsplit_path(path: &str) -> (&str, Option<&str>) { 22004e86ffSlogin let mut path_split: core::str::RSplitN<&str> = path.trim_matches('/').rsplitn(2, "/"); 23004e86ffSlogin let comp = path_split.next().unwrap_or(""); 24004e86ffSlogin let rest_opt = path_split.next(); 25004e86ffSlogin 26004e86ffSlogin return (comp, rest_opt); 27004e86ffSlogin } 28*9b0abe6dSLoGin 29*9b0abe6dSLoGin /// 根据dirfd和path,计算接下来开始lookup的inode和剩余的path 30*9b0abe6dSLoGin /// 31*9b0abe6dSLoGin /// ## 返回值 32*9b0abe6dSLoGin /// 33*9b0abe6dSLoGin /// 返回值为(需要lookup的inode, 剩余的path) 34*9b0abe6dSLoGin pub fn user_path_at( 35*9b0abe6dSLoGin pcb: &Arc<ProcessControlBlock>, 36*9b0abe6dSLoGin dirfd: i32, 37*9b0abe6dSLoGin mut path: String, 38*9b0abe6dSLoGin ) -> Result<(Arc<dyn IndexNode>, String), SystemError> { 39*9b0abe6dSLoGin let mut inode = ROOT_INODE(); 40*9b0abe6dSLoGin // 如果path不是绝对路径,则需要拼接 41*9b0abe6dSLoGin if path.as_bytes()[0] != b'/' { 42*9b0abe6dSLoGin // 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录 43*9b0abe6dSLoGin if dirfd != AtFlags::AT_FDCWD.bits() { 44*9b0abe6dSLoGin let binding = pcb.fd_table(); 45*9b0abe6dSLoGin let fd_table_guard = binding.read(); 46*9b0abe6dSLoGin let file = fd_table_guard 47*9b0abe6dSLoGin .get_file_by_fd(dirfd) 48*9b0abe6dSLoGin .ok_or(SystemError::EBADF)?; 49*9b0abe6dSLoGin 50*9b0abe6dSLoGin // drop guard 以避免无法调度的问题 51*9b0abe6dSLoGin drop(fd_table_guard); 52*9b0abe6dSLoGin 53*9b0abe6dSLoGin let file_guard = file.lock(); 54*9b0abe6dSLoGin // 如果dirfd不是目录,则返回错误码ENOTDIR 55*9b0abe6dSLoGin if file_guard.file_type() != FileType::Dir { 56*9b0abe6dSLoGin return Err(SystemError::ENOTDIR); 57*9b0abe6dSLoGin } 58*9b0abe6dSLoGin 59*9b0abe6dSLoGin inode = file_guard.inode(); 60*9b0abe6dSLoGin } else { 61*9b0abe6dSLoGin let mut cwd = pcb.basic().cwd(); 62*9b0abe6dSLoGin cwd.push('/'); 63*9b0abe6dSLoGin cwd.push_str(path.as_str()); 64*9b0abe6dSLoGin path = cwd; 65*9b0abe6dSLoGin } 66*9b0abe6dSLoGin } 67*9b0abe6dSLoGin 68*9b0abe6dSLoGin return Ok((inode, path)); 69*9b0abe6dSLoGin } 70