use crate bitflags

This commit is contained in:
WangRunji 2019-03-05 23:44:00 +08:00 committed by Tate Tian
parent 8f078e9499
commit a3c49c2a3e
6 changed files with 82 additions and 48 deletions

7
src/libos/Cargo.lock generated

@ -4,6 +4,7 @@
name = "Occlum" name = "Occlum"
version = "0.0.1" version = "0.0.1"
dependencies = [ 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)", "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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rcore-fs 0.1.0", "rcore-fs 0.1.0",
@ -14,6 +15,11 @@ dependencies = [
"xmas-elf 0.6.2", "xmas-elf 0.6.2",
] ]
[[package]]
name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "0.9.0" version = "0.9.0"
@ -143,6 +149,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [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 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 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" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"

@ -7,6 +7,7 @@ name = "occlum_rs"
crate-type = ["staticlib"] crate-type = ["staticlib"]
[dependencies] [dependencies]
bitflags = "1.0"
log = "0.4" log = "0.4"
lazy_static = { version = "1.1.0", features = ["spin_no_std"] } # Implies nightly lazy_static = { version = "1.1.0", features = ["spin_no_std"] } # Implies nightly
rcore-fs = { path = "../../deps/sefs/rcore-fs" } rcore-fs = { path = "../../deps/sefs/rcore-fs" }

@ -17,14 +17,20 @@ lazy_static! {
pub struct INodeFile { pub struct INodeFile {
inode: Arc<INode>, inode: Arc<INode>,
offset: SgxMutex<usize>, offset: SgxMutex<usize>,
is_readable: bool, options: OpenOptions,
is_writable: bool, }
is_append: bool,
#[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 { impl File for INodeFile {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> { fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
if !self.is_readable { if !self.options.read {
return Err(Error::new(Errno::EBADF, "File not readable")); return Err(Error::new(Errno::EBADF, "File not readable"));
} }
let mut offset = self.offset.lock().unwrap(); let mut offset = self.offset.lock().unwrap();
@ -34,11 +40,11 @@ impl File for INodeFile {
} }
fn write(&self, buf: &[u8]) -> Result<usize, Error> { fn write(&self, buf: &[u8]) -> Result<usize, Error> {
if !self.is_writable { if !self.options.write {
return Err(Error::new(Errno::EBADF, "File not writable")); return Err(Error::new(Errno::EBADF, "File not writable"));
} }
let mut offset = self.offset.lock().unwrap(); let mut offset = self.offset.lock().unwrap();
if self.is_append { if self.options.append {
let info = self.inode.metadata()?; let info = self.inode.metadata()?;
*offset = info.size; *offset = info.size;
} }
@ -67,13 +73,11 @@ impl File for INodeFile {
} }
impl INodeFile { impl INodeFile {
pub fn open(inode: Arc<INode>, is_readable: bool, is_writable: bool, is_append: bool) -> Result<Self, Error> { pub fn open(inode: Arc<INode>, options: OpenOptions) -> Result<Self, Error> {
Ok(INodeFile { Ok(INodeFile {
inode, inode,
offset: SgxMutex::new(0), offset: SgxMutex::new(0),
is_readable, options,
is_writable,
is_append,
}) })
} }
} }
@ -102,6 +106,7 @@ impl From<FsError> for Error {
impl Debug for INodeFile { impl Debug for INodeFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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)
} }
} }

@ -13,14 +13,7 @@ pub use self::file_table::{FileDesc, FileTable};
pub use self::pipe::Pipe; pub use self::pipe::Pipe;
pub use self::inode_file::{INodeFile, ROOT_INODE}; pub use self::inode_file::{INodeFile, ROOT_INODE};
use rcore_fs::vfs::{FsError, FileType, INode}; use rcore_fs::vfs::{FsError, FileType, INode};
use self::inode_file::OpenOptions;
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;
// TODO: use the type defined in Rust libc. // TODO: use the type defined in Rust libc.
// //
@ -30,22 +23,18 @@ pub const O_CLOEXEC: u32 = 0x00080000;
pub type off_t = i64; pub type off_t = i64;
pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> { pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
let flags = OpenFlags::from_bits_truncate(flags);
info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode); 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 = let inode =
if is_create { if flags.contains(OpenFlags::CREATE) {
let (dir_path, file_name) = split_path(&path); let (dir_path, file_name) = split_path(&path);
let dir_inode = ROOT_INODE.lookup(dir_path)?; let dir_inode = ROOT_INODE.lookup(dir_path)?;
match dir_inode.find(file_name) { match dir_inode.find(file_name) {
Ok(file_inode) => { Ok(file_inode) => {
// if flags.contains(OpenFlags::EXCLUSIVE) { if flags.contains(OpenFlags::EXCLUSIVE) {
// return Err(SysError::EEXIST); return Err(Error::new(EEXIST, "file exists"));
// } }
file_inode file_inode
}, },
Err(FsError::EntryNotFound) => { Err(FsError::EntryNotFound) => {
@ -57,17 +46,14 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
ROOT_INODE.lookup(&path)? ROOT_INODE.lookup(&path)?
}; };
let file_ref: Arc<Box<File>> = Arc::new(Box::new(INodeFile::open( let file_ref: Arc<Box<File>> = Arc::new(Box::new(
inode, INodeFile::open(inode, flags.to_options())?
is_readable, ));
is_writable,
is_append,
)?));
let fd = { let fd = {
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut current = current_ref.lock().unwrap(); 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) current.get_files_mut().put(file_ref, close_on_spawn)
}; };
Ok(fd) Ok(fd)
@ -117,12 +103,13 @@ pub fn do_close(fd: FileDesc) -> Result<(), Error> {
} }
pub fn do_pipe2(flags: u32) -> Result<[FileDesc; 2], 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 current_ref = process::get_current();
let mut current = current_ref.lock().unwrap(); let mut current = current_ref.lock().unwrap();
let pipe = Pipe::new()?; let pipe = Pipe::new()?;
let mut file_table = current.get_files_mut(); 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 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); let writer_fd = file_table.put(Arc::new(Box::new(pipe.writer)), close_on_spawn);
Ok([reader_fd, writer_fd]) Ok([reader_fd, writer_fd])
@ -149,6 +136,7 @@ pub fn do_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<FileDesc, Error> {
} }
pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<FileDesc, Error> { pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<FileDesc, Error> {
let flags = OpenFlags::from_bits_truncate(flags);
let current_ref = process::get_current(); let current_ref = process::get_current();
let mut current = current_ref.lock().unwrap(); let mut current = current_ref.lock().unwrap();
let file_table = current.get_files_mut(); let file_table = current.get_files_mut();
@ -156,7 +144,7 @@ pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<FileDes
if old_fd == new_fd { if old_fd == new_fd {
return errno!(EINVAL, "old_fd must not be equal to new_fd"); return errno!(EINVAL, "old_fd must not be equal to new_fd");
} }
let close_on_spawn = flags & O_CLOEXEC != 0; let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
file_table.put_at(new_fd, file, close_on_spawn); file_table.put_at(new_fd, file, close_on_spawn);
Ok(new_fd) Ok(new_fd)
} }
@ -179,3 +167,42 @@ fn split_path(path: &str) -> (&str, &str) {
let dir_path = split.next().unwrap_or("."); let dir_path = split.next().unwrap_or(".");
(dir_path, file_name) (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),
}
}
}

@ -9,6 +9,8 @@
#[macro_use] #[macro_use]
extern crate alloc; extern crate alloc;
#[macro_use]
extern crate bitflags;
extern crate sgx_types; extern crate sgx_types;
#[cfg(not(target_env = "sgx"))] #[cfg(not(target_env = "sgx"))]
#[macro_use] #[macro_use]

@ -70,13 +70,7 @@ thread_local! {
} }
pub fn get_current() -> ProcessRef { pub fn get_current() -> ProcessRef {
let current_ptr = { let current_ptr = _CURRENT_PROCESS_PTR.with(|cell| cell.get());
let mut current_ptr = 0 as *const SgxMutex<Process>;
_CURRENT_PROCESS_PTR.with(|cell| {
current_ptr = cell.get();
});
current_ptr
};
let current_ref = unsafe { Arc::from_raw(current_ptr) }; let current_ref = unsafe { Arc::from_raw(current_ptr) };
let current_ref_clone = current_ref.clone(); let current_ref_clone = current_ref.clone();
@ -95,10 +89,8 @@ fn set_current(process: &ProcessRef) {
} }
fn reset_current() { fn reset_current() {
let mut process_ptr = 0 as *const SgxMutex<Process>; let mut process_ptr = _CURRENT_PROCESS_PTR.with(|cp| {
_CURRENT_PROCESS_PTR.with(|cp| { cp.replace(0 as *const SgxMutex<Process>)
process_ptr = cp.get();
cp.set(0 as *const SgxMutex<Process>);
}); });
// Prevent memory leakage // Prevent memory leakage