Add access and faccessat

This commit is contained in:
Tate, Hongliang Tian 2019-04-09 23:01:10 +08:00 committed by Tate Tian
parent b003f4ce43
commit d7e266d0e3
4 changed files with 82 additions and 2 deletions

@ -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, Error> {
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, Error> {
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<FileDesc>, 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(())
}

@ -11,12 +11,14 @@ pub use self::file_table::{FileDesc, FileTable};
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE}; pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
use self::inode_file::OpenOptions; use self::inode_file::OpenOptions;
pub use self::pipe::Pipe; pub use self::pipe::Pipe;
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
mod file; mod file;
mod file_table; mod file_table;
mod inode_file; mod inode_file;
mod pipe; mod pipe;
mod sgx_impl; mod sgx_impl;
mod access;
// TODO: use the type defined in Rust libc. // TODO: use the type defined in Rust libc.
// //

@ -1,6 +1,5 @@
use {fs, process, std, vm}; use {fs, process, std, vm};
use fs::{FileDesc, off_t}; use fs::{File, FileDesc, off_t, AccessModes, AccessFlags, AT_FDCWD};
use fs::File;
use prelude::*; use prelude::*;
use process::{ChildProcessFilter, FileAction, pid_t, CloneFlags, FutexFlags, FutexOp}; use process::{ChildProcessFilter, FileAction, pid_t, CloneFlags, FutexFlags, FutexOp};
use std::ffi::{CStr, CString}; 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_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_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_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_LSEEK => do_lseek(arg0 as FileDesc, arg1 as off_t, arg2 as i32),
SYS_FSYNC => do_fsync(arg0 as FileDesc), SYS_FSYNC => do_fsync(arg0 as FileDesc),
SYS_FDATASYNC => do_fdatasync(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) misc::do_prlimit(pid, resource, new_limit, old_limit).map(|_| 0)
} }
fn do_access(path: *const i8, mode: u32) -> Result<isize, Error> {
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<isize, Error> {
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)
}

@ -21,6 +21,11 @@ int main(int argc, const char* argv[]) {
return fd; return fd;
} }
if (access(FILE_NAME, F_OK) < 0) {
printf("cannot access the new file\n");
return -1;
}
ret = ftruncate(fd, TRUNC_LEN); ret = ftruncate(fd, TRUNC_LEN);
if (ret < 0) { if (ret < 0) {
printf("failed to ftruncate the file\n"); printf("failed to ftruncate the file\n");