From d7e266d0e3a2f3fc242bbd963a8569ebb8375bfa Mon Sep 17 00:00:00 2001 From: "Tate, Hongliang Tian" Date: Tue, 9 Apr 2019 23:01:10 +0800 Subject: [PATCH] Add access and faccessat --- src/libos/src/fs/access.rs | 52 ++++++++++++++++++++++++++++++++++++ src/libos/src/fs/mod.rs | 2 ++ src/libos/src/syscall/mod.rs | 25 +++++++++++++++-- test/truncate/main.c | 5 ++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/libos/src/fs/access.rs diff --git a/src/libos/src/fs/access.rs b/src/libos/src/fs/access.rs new file mode 100644 index 00000000..e2910a73 --- /dev/null +++ b/src/libos/src/fs/access.rs @@ -0,0 +1,52 @@ +use super::*; + +//int faccessat(int dirfd, const char *pathname, int mode, int flags); +//int access(const char *pathname, int mode); + +bitflags! { + pub struct AccessModes : u32 { + const X_OK = 1; + const W_OK = 2; + const R_OK = 4; + } +} + +impl AccessModes { + pub fn from_u32(bits: u32) -> Result { + AccessModes::from_bits(bits).ok_or_else(|| Error::new(Errno::EINVAL, "invalid mode")) + } +} + + +bitflags! { + pub struct AccessFlags : u32 { + const AT_SYMLINK_NOFOLLOW = 0x100; + const AT_EACCESS = 0x200; + } +} + +impl AccessFlags { + pub fn from_u32(bits: u32) -> Result { + AccessFlags::from_bits(bits).ok_or_else(|| Error::new(Errno::EINVAL, "invalid flags")) + } +} + + +pub const AT_FDCWD : i32 = -100; + +pub fn do_faccessat(dirfd: Option, path: &str, mode: AccessModes, flags: AccessFlags) -> Result<(), Error> { + match dirfd { + // TODO: handle dirfd + Some(dirfd) => errno!(ENOSYS, "cannot accept dirfd"), + None => do_access(path, mode), + } +} + +pub fn do_access(path: &str, mode: AccessModes) -> Result<(), Error> { + let current_ref = process::get_current(); + let mut current = current_ref.lock().unwrap(); + let inode = current.lookup_inode(path)?; + //let metadata = inode.get_metadata(); + // TODO: check metadata.mode with mode + Ok(()) +} diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index 162f7062..8142f23a 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -11,12 +11,14 @@ pub use self::file_table::{FileDesc, FileTable}; pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE}; use self::inode_file::OpenOptions; pub use self::pipe::Pipe; +pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat}; mod file; mod file_table; mod inode_file; mod pipe; mod sgx_impl; +mod access; // TODO: use the type defined in Rust libc. // diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index 1e642086..af0319a3 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -1,6 +1,5 @@ use {fs, process, std, vm}; -use fs::{FileDesc, off_t}; -use fs::File; +use fs::{File, FileDesc, off_t, AccessModes, AccessFlags, AT_FDCWD}; use prelude::*; use process::{ChildProcessFilter, FileAction, pid_t, CloneFlags, FutexFlags, FutexOp}; use std::ffi::{CStr, CString}; @@ -57,6 +56,8 @@ pub extern "C" fn dispatch_syscall( SYS_STAT => do_stat(arg0 as *const i8, arg1 as *mut fs::Stat), SYS_FSTAT => do_fstat(arg0 as FileDesc, arg1 as *mut fs::Stat), SYS_LSTAT => do_lstat(arg0 as *const i8, arg1 as *mut fs::Stat), + SYS_ACCESS => do_access(arg0 as *const i8, arg1 as u32), + SYS_FACCESSAT => do_faccessat(arg0 as i32, arg1 as *const i8, arg2 as u32, arg3 as u32), SYS_LSEEK => do_lseek(arg0 as FileDesc, arg1 as off_t, arg2 as i32), SYS_FSYNC => do_fsync(arg0 as FileDesc), SYS_FDATASYNC => do_fdatasync(arg0 as FileDesc), @@ -730,3 +731,23 @@ fn do_prlimit(pid: pid_t, resource: u32, new_limit: *const rlimit_t, old_limit: }; misc::do_prlimit(pid, resource, new_limit, old_limit).map(|_| 0) } + +fn do_access(path: *const i8, mode: u32) -> Result { + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + let mode = AccessModes::from_u32(mode)?; + fs::do_access(&path, mode).map(|_| 0) +} + +fn do_faccessat(dirfd: i32, path: *const i8, mode: u32, flags: u32) -> Result { + let dirfd = if dirfd >= 0 { + Some(dirfd as FileDesc) + } else if dirfd == AT_FDCWD { + None + } else { + return errno!(EINVAL, "invalid dirfd"); + }; + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + let mode = AccessModes::from_u32(mode)?; + let flags = AccessFlags::from_u32(flags)?; + fs::do_faccessat(dirfd, &path, mode, flags).map(|_| 0) +} diff --git a/test/truncate/main.c b/test/truncate/main.c index 021fe3a8..36a3d45a 100644 --- a/test/truncate/main.c +++ b/test/truncate/main.c @@ -21,6 +21,11 @@ int main(int argc, const char* argv[]) { return fd; } + if (access(FILE_NAME, F_OK) < 0) { + printf("cannot access the new file\n"); + return -1; + } + ret = ftruncate(fd, TRUNC_LEN); if (ret < 0) { printf("failed to ftruncate the file\n");