diff --git a/src/libos/Cargo.lock b/src/libos/Cargo.lock index 5544f46d..bdba2c8a 100644 --- a/src/libos/Cargo.lock +++ b/src/libos/Cargo.lock @@ -4,6 +4,7 @@ name = "Occlum" version = "0.0.1" dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rcore-fs 0.1.0", @@ -14,6 +15,11 @@ dependencies = [ "xmas-elf 0.6.2", ] +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitvec" version = "0.9.0" @@ -143,6 +149,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" diff --git a/src/libos/Cargo.toml b/src/libos/Cargo.toml index c11360b8..2301c884 100644 --- a/src/libos/Cargo.toml +++ b/src/libos/Cargo.toml @@ -7,6 +7,7 @@ name = "occlum_rs" crate-type = ["staticlib"] [dependencies] +bitflags = "1.0" log = "0.4" lazy_static = { version = "1.1.0", features = ["spin_no_std"] } # Implies nightly rcore-fs = { path = "../../deps/sefs/rcore-fs" } diff --git a/src/libos/src/fs/inode_file.rs b/src/libos/src/fs/inode_file.rs index cd870721..5e559856 100644 --- a/src/libos/src/fs/inode_file.rs +++ b/src/libos/src/fs/inode_file.rs @@ -17,14 +17,20 @@ lazy_static! { pub struct INodeFile { inode: Arc, offset: SgxMutex, - is_readable: bool, - is_writable: bool, - is_append: bool, + options: OpenOptions, +} + +#[derive(Debug, Clone)] +pub struct OpenOptions { + pub read: bool, + pub write: bool, + /// Before each write, the file offset is positioned at the end of the file. + pub append: bool, } impl File for INodeFile { fn read(&self, buf: &mut [u8]) -> Result { - if !self.is_readable { + if !self.options.read { return Err(Error::new(Errno::EBADF, "File not readable")); } let mut offset = self.offset.lock().unwrap(); @@ -34,11 +40,11 @@ impl File for INodeFile { } fn write(&self, buf: &[u8]) -> Result { - if !self.is_writable { + if !self.options.write { return Err(Error::new(Errno::EBADF, "File not writable")); } let mut offset = self.offset.lock().unwrap(); - if self.is_append { + if self.options.append { let info = self.inode.metadata()?; *offset = info.size; } @@ -67,13 +73,11 @@ impl File for INodeFile { } impl INodeFile { - pub fn open(inode: Arc, is_readable: bool, is_writable: bool, is_append: bool) -> Result { + pub fn open(inode: Arc, options: OpenOptions) -> Result { Ok(INodeFile { inode, offset: SgxMutex::new(0), - is_readable, - is_writable, - is_append, + options, }) } } @@ -102,6 +106,7 @@ impl From for Error { impl Debug for INodeFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "INodeFile {{ pos: {}, inode: ??? }}", *self.offset.lock().unwrap()) + write!(f, "INodeFile {{ inode: ???, pos: {}, options: {:?} }}", + *self.offset.lock().unwrap(), self.options) } } diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index 67322d7e..f7da3be2 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -13,14 +13,7 @@ pub use self::file_table::{FileDesc, FileTable}; pub use self::pipe::Pipe; pub use self::inode_file::{INodeFile, ROOT_INODE}; use rcore_fs::vfs::{FsError, FileType, INode}; - -pub const O_RDONLY: u32 = 0x00000000; -pub const O_WRONLY: u32 = 0x00000001; -pub const O_RDWR: u32 = 0x00000002; -pub const O_CREAT: u32 = 0x00000040; -pub const O_TRUNC: u32 = 0x00000200; -pub const O_APPEND: u32 = 0x00000400; -pub const O_CLOEXEC: u32 = 0x00080000; +use self::inode_file::OpenOptions; // TODO: use the type defined in Rust libc. // @@ -30,22 +23,18 @@ pub const O_CLOEXEC: u32 = 0x00080000; pub type off_t = i64; pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { + let flags = OpenFlags::from_bits_truncate(flags); info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode); - let is_readable = (flags & O_WRONLY) == 0; - let is_writable = (flags & O_WRONLY != 0) || (flags & O_RDWR != 0); - let is_append = (flags & O_APPEND != 0); - let is_create = (flags & O_CREAT != 0); - let inode = - if is_create { + if flags.contains(OpenFlags::CREATE) { let (dir_path, file_name) = split_path(&path); let dir_inode = ROOT_INODE.lookup(dir_path)?; match dir_inode.find(file_name) { Ok(file_inode) => { -// if flags.contains(OpenFlags::EXCLUSIVE) { -// return Err(SysError::EEXIST); -// } + if flags.contains(OpenFlags::EXCLUSIVE) { + return Err(Error::new(EEXIST, "file exists")); + } file_inode }, Err(FsError::EntryNotFound) => { @@ -57,17 +46,14 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { ROOT_INODE.lookup(&path)? }; - let file_ref: Arc> = Arc::new(Box::new(INodeFile::open( - inode, - is_readable, - is_writable, - is_append, - )?)); + let file_ref: Arc> = Arc::new(Box::new( + INodeFile::open(inode, flags.to_options())? + )); let fd = { let current_ref = process::get_current(); let mut current = current_ref.lock().unwrap(); - let close_on_spawn = flags & O_CLOEXEC != 0; + let close_on_spawn = flags.contains(OpenFlags::CLOEXEC); current.get_files_mut().put(file_ref, close_on_spawn) }; Ok(fd) @@ -117,12 +103,13 @@ pub fn do_close(fd: FileDesc) -> Result<(), Error> { } pub fn do_pipe2(flags: u32) -> Result<[FileDesc; 2], Error> { + let flags = OpenFlags::from_bits_truncate(flags); let current_ref = process::get_current(); let mut current = current_ref.lock().unwrap(); let pipe = Pipe::new()?; let mut file_table = current.get_files_mut(); - let close_on_spawn = flags & O_CLOEXEC != 0; + let close_on_spawn = flags.contains(OpenFlags::CLOEXEC); let reader_fd = file_table.put(Arc::new(Box::new(pipe.reader)), close_on_spawn); let writer_fd = file_table.put(Arc::new(Box::new(pipe.writer)), close_on_spawn); Ok([reader_fd, writer_fd]) @@ -149,6 +136,7 @@ pub fn do_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result { } pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result { + let flags = OpenFlags::from_bits_truncate(flags); let current_ref = process::get_current(); let mut current = current_ref.lock().unwrap(); let file_table = current.get_files_mut(); @@ -156,7 +144,7 @@ pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result (&str, &str) { let dir_path = split.next().unwrap_or("."); (dir_path, file_name) } + +bitflags! { + struct OpenFlags: u32 { + /// read only + const RDONLY = 0; + /// write only + const WRONLY = 1; + /// read write + const RDWR = 2; + /// create file if it does not exist + const CREATE = 1 << 6; + /// error if CREATE and the file exists + const EXCLUSIVE = 1 << 7; + /// truncate file upon open + const TRUNCATE = 1 << 9; + /// append on each write + const APPEND = 1 << 10; + /// close on exec + const CLOEXEC = 1 << 19; + } +} + +impl OpenFlags { + fn readable(&self) -> bool { + let b = self.bits() & 0b11; + b == OpenFlags::RDONLY.bits() || b == OpenFlags::RDWR.bits() + } + fn writable(&self) -> bool { + let b = self.bits() & 0b11; + b == OpenFlags::WRONLY.bits() || b == OpenFlags::RDWR.bits() + } + fn to_options(&self) -> OpenOptions { + OpenOptions { + read: self.readable(), + write: self.writable(), + append: self.contains(OpenFlags::APPEND), + } + } +} diff --git a/src/libos/src/lib.rs b/src/libos/src/lib.rs index b315f22b..e903df21 100644 --- a/src/libos/src/lib.rs +++ b/src/libos/src/lib.rs @@ -9,6 +9,8 @@ #[macro_use] extern crate alloc; +#[macro_use] +extern crate bitflags; extern crate sgx_types; #[cfg(not(target_env = "sgx"))] #[macro_use] diff --git a/src/libos/src/process/task.rs b/src/libos/src/process/task.rs index 805939bc..fd3ab39e 100644 --- a/src/libos/src/process/task.rs +++ b/src/libos/src/process/task.rs @@ -70,13 +70,7 @@ thread_local! { } pub fn get_current() -> ProcessRef { - let current_ptr = { - let mut current_ptr = 0 as *const SgxMutex; - _CURRENT_PROCESS_PTR.with(|cell| { - current_ptr = cell.get(); - }); - current_ptr - }; + let current_ptr = _CURRENT_PROCESS_PTR.with(|cell| cell.get()); let current_ref = unsafe { Arc::from_raw(current_ptr) }; let current_ref_clone = current_ref.clone(); @@ -95,10 +89,8 @@ fn set_current(process: &ProcessRef) { } fn reset_current() { - let mut process_ptr = 0 as *const SgxMutex; - _CURRENT_PROCESS_PTR.with(|cp| { - process_ptr = cp.get(); - cp.set(0 as *const SgxMutex); + let mut process_ptr = _CURRENT_PROCESS_PTR.with(|cp| { + cp.replace(0 as *const SgxMutex) }); // Prevent memory leakage