implement add_open in posix_spawn

This commit is contained in:
WangRunji 2019-04-13 12:05:50 +08:00
parent 58a7f7c126
commit d19676032d
3 changed files with 53 additions and 30 deletions

@ -35,24 +35,8 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let inode = if flags.contains(OpenFlags::CREATE) {
let (dir_path, file_name) = split_path(&path);
let dir_inode = proc.lookup_inode(dir_path)?;
match dir_inode.find(file_name) {
Ok(file_inode) => {
if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(Error::new(EEXIST, "file exists"));
}
file_inode
}
Err(FsError::EntryNotFound) => dir_inode.create(file_name, FileType::File, mode)?,
Err(e) => return Err(Error::from(e)),
}
} else {
proc.lookup_inode(&path)?
};
let file_ref: Arc<Box<File>> = Arc::new(Box::new(INodeFile::open(inode, flags.to_options())?));
let file = proc.open_file(path, flags, mode)?;
let file_ref: Arc<Box<File>> = Arc::new(Box::new(file));
let fd = {
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
@ -363,6 +347,28 @@ extern "C" {
}
impl Process {
/// Open a file on the process. But DO NOT add it to file table.
pub fn open_file(&self, path: &str, flags: OpenFlags, mode: u32) -> Result<INodeFile, Error> {
let inode = if flags.contains(OpenFlags::CREATE) {
let (dir_path, file_name) = split_path(&path);
let dir_inode = self.lookup_inode(dir_path)?;
match dir_inode.find(file_name) {
Ok(file_inode) => {
if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(Error::new(EEXIST, "file exists"));
}
file_inode
}
Err(FsError::EntryNotFound) => dir_inode.create(file_name, FileType::File, mode)?,
Err(e) => return Err(Error::from(e)),
}
} else {
self.lookup_inode(&path)?
};
INodeFile::open(inode, flags.to_options())
}
/// Lookup INode from the cwd of the process
pub fn lookup_inode(&self, path: &str) -> Result<Arc<INode>, Error> {
debug!("lookup_inode: cwd: {:?}, path: {:?}", self.get_cwd(), path);
if path.len() > 0 && path.as_bytes()[0] == b'/' {

@ -1,7 +1,7 @@
use xmas_elf::{ElfFile, header, program, sections};
use xmas_elf::symbol_table::Entry;
use fs::{File, FileDesc, FileTable, INodeExt, ROOT_INODE, StdinFile, StdoutFile};
use fs::{File, FileDesc, FileTable, INodeExt, ROOT_INODE, StdinFile, StdoutFile, OpenFlags};
use std::ffi::{CStr, CString};
use std::path::Path;
use std::sgxfs::SgxFile;
@ -20,8 +20,14 @@ mod segment;
#[derive(Debug)]
pub enum FileAction {
// TODO: Add open action
// Open(...)
/// open(path, oflag, mode) had been called, and the returned file
/// descriptor, if not `fd`, had been changed to `fd`.
Open {
path: String,
mode: u32,
oflag: u32,
fd: FileDesc,
},
Dup2(FileDesc, FileDesc),
Close(FileDesc),
}
@ -92,14 +98,22 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result<Fi
// Perform file actions to modify the cloned file table
for file_action in file_actions {
match file_action {
FileAction::Dup2(old_fd, new_fd) => {
let file = cloned_file_table.get(*old_fd)?;
&FileAction::Open { ref path, mode, oflag, fd} => {
let flags = OpenFlags::from_bits_truncate(oflag);
let file = parent.open_file(path.as_str(), flags, mode)?;
let file_ref: Arc<Box<File>> = Arc::new(Box::new(file));
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
cloned_file_table.put_at(fd, file_ref, close_on_spawn);
}
&FileAction::Dup2(old_fd, new_fd) => {
let file = cloned_file_table.get(old_fd)?;
if old_fd != new_fd {
cloned_file_table.put_at(*new_fd, file, false);
cloned_file_table.put_at(new_fd, file, false);
}
}
FileAction::Close(fd) => {
cloned_file_table.del(*fd)?;
&FileAction::Close(fd) => {
cloned_file_table.del(fd)?;
}
}
}

@ -283,7 +283,7 @@ pub struct FdOp {
srcfd: u32,
oflag: u32,
mode: u32,
path: *const u8,
path: *const i8,
}
fn clone_file_actions_safely(fdop_ptr: *const FdOp) -> Result<Vec<FileAction>, Error> {
@ -297,9 +297,12 @@ fn clone_file_actions_safely(fdop_ptr: *const FdOp) -> Result<Vec<FileAction>, E
let file_action = match fdop.cmd {
FDOP_CLOSE => FileAction::Close(fdop.fd),
FDOP_DUP2 => FileAction::Dup2(fdop.srcfd, fdop.fd),
FDOP_OPEN => {
return errno!(EINVAL, "Not implemented");
}
FDOP_OPEN => FileAction::Open {
path: clone_cstring_safely(fdop.path)?.to_string_lossy().into_owned(),
mode: fdop.mode,
oflag: fdop.oflag,
fd: fdop.fd,
},
_ => {
return errno!(EINVAL, "Unknown file action command");
}