From 7ce2fca20957578314e47ceddd7fb9ebcc4434a8 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 19 Apr 2019 09:17:27 +0800 Subject: [PATCH] Fix ls -al for symlinks --- kernel/src/syscall/fs.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 88c99ee..0025034 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -259,7 +259,7 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> let inode = if flags.contains(OpenFlags::CREATE) { let (dir_path, file_name) = split_path(&path); // relative to cwd - let dir_inode = proc.lookup_inode_at(dir_fd, dir_path)?; + let dir_inode = proc.lookup_inode_at(dir_fd, dir_path, true)?; match dir_inode.find(file_name) { Ok(file_inode) => { if flags.contains(OpenFlags::EXCLUSIVE) { @@ -273,7 +273,7 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> Err(e) => return Err(SysError::from(e)), } } else { - proc.lookup_inode_at(dir_fd, &path)? + proc.lookup_inode_at(dir_fd, &path, true)? }; let fd = proc.get_free_fd(); @@ -306,7 +306,7 @@ pub fn sys_faccessat(dirfd: usize, path: *const u8, mode: usize, flags: usize) - dirfd as isize, path, mode, flags ); } - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?; Ok(0) } @@ -325,8 +325,7 @@ pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { } pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { - warn!("lstat is partial implemented as stat"); - sys_stat(path, stat_ptr) + sys_fstatat(AT_FDCWD, path, stat_ptr, AtFlags::SYMLINK_NOFOLLOW.bits()) } pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { @@ -351,7 +350,7 @@ pub fn sys_fstatat(dirfd: usize, path: *const u8, stat_ptr: *mut Stat, flags: us dirfd as isize, path, stat_ptr, flags ); - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?; let stat = Stat::from(inode.metadata()?); unsafe { stat_ptr.write(stat); @@ -373,7 +372,7 @@ pub fn sys_readlinkat(dirfd: usize, path: *const u8, base: *mut u8, len: usize) proc.vm.check_write_array(base, len)?; info!("readlink: path: {:?}, base: {:?}, len: {}", path, base, len); - let inode = proc.lookup_inode_at(dirfd, &path)?; + let inode = proc.lookup_inode_at(dirfd, &path, false)?; if inode.metadata()?.type_ == FileType::SymLink { // TODO: recursive link resolution and loop detection let mut slice = unsafe { slice::from_raw_parts_mut(base, len) }; @@ -536,8 +535,8 @@ pub fn sys_renameat( let (old_dir_path, old_file_name) = split_path(&oldpath); let (new_dir_path, new_file_name) = split_path(&newpath); - let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path)?; - let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?; + let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path, false)?; + let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, false)?; old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?; Ok(0) } @@ -556,7 +555,7 @@ pub fn sys_mkdirat(dirfd: usize, path: *const u8, mode: usize) -> SysResult { ); let (dir_path, file_name) = split_path(&path); - let inode = proc.lookup_inode_at(dirfd, dir_path)?; + let inode = proc.lookup_inode_at(dirfd, dir_path, true)?; if inode.find(file_name).is_ok() { return Err(SysError::EEXIST); } @@ -600,8 +599,8 @@ pub fn sys_linkat( ); let (new_dir_path, new_file_name) = split_path(&newpath); - let inode = proc.lookup_inode_at(olddirfd, &oldpath)?; - let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?; + let inode = proc.lookup_inode_at(olddirfd, &oldpath, true)?; + let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, true)?; new_dir_inode.link(new_file_name, &inode)?; Ok(0) } @@ -620,7 +619,7 @@ pub fn sys_unlinkat(dirfd: usize, path: *const u8, flags: usize) -> SysResult { ); let (dir_path, file_name) = split_path(&path); - let dir_inode = proc.lookup_inode_at(dirfd, dir_path)?; + let dir_inode = proc.lookup_inode_at(dirfd, dir_path, true)?; let file_inode = dir_inode.find(file_name)?; if file_inode.metadata()?.type_ == FileType::Dir { return Err(SysError::EISDIR); @@ -767,9 +766,8 @@ impl Process { &self, dirfd: usize, path: &str, - // follow: bool, + follow: bool, ) -> Result, SysError> { - let follow = true; debug!( "lookup_inode_at: dirfd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}", dirfd as isize, self.cwd, path, follow @@ -789,7 +787,7 @@ impl Process { } pub fn lookup_inode(&self, path: &str) -> Result, SysError> { - self.lookup_inode_at(AT_FDCWD, path) + self.lookup_inode_at(AT_FDCWD, path, true) } } @@ -1215,7 +1213,6 @@ impl IoVecs { /// For writev: `set_len` is false, Vec.cap = total_len. pub fn new_buf(&self, set_len: bool) -> Vec { let total_len = self.0.iter().map(|slice| slice.len()).sum::(); - info!("{}", total_len); let mut buf = Vec::with_capacity(total_len); if set_len { unsafe {