implement add_open in posix_spawn
This commit is contained in:
parent
58a7f7c126
commit
d19676032d
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user