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 current_ref = process::get_current();
|
||||||
let mut proc = current_ref.lock().unwrap();
|
let mut proc = current_ref.lock().unwrap();
|
||||||
|
|
||||||
let inode = if flags.contains(OpenFlags::CREATE) {
|
let file = proc.open_file(path, flags, mode)?;
|
||||||
let (dir_path, file_name) = split_path(&path);
|
let file_ref: Arc<Box<File>> = Arc::new(Box::new(file));
|
||||||
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 fd = {
|
let fd = {
|
||||||
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
|
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
|
||||||
@ -363,6 +347,28 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Process {
|
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> {
|
pub fn lookup_inode(&self, path: &str) -> Result<Arc<INode>, Error> {
|
||||||
debug!("lookup_inode: cwd: {:?}, path: {:?}", self.get_cwd(), path);
|
debug!("lookup_inode: cwd: {:?}, path: {:?}", self.get_cwd(), path);
|
||||||
if path.len() > 0 && path.as_bytes()[0] == b'/' {
|
if path.len() > 0 && path.as_bytes()[0] == b'/' {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use xmas_elf::{ElfFile, header, program, sections};
|
use xmas_elf::{ElfFile, header, program, sections};
|
||||||
use xmas_elf::symbol_table::Entry;
|
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::ffi::{CStr, CString};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sgxfs::SgxFile;
|
use std::sgxfs::SgxFile;
|
||||||
@ -20,8 +20,14 @@ mod segment;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FileAction {
|
pub enum FileAction {
|
||||||
// TODO: Add open action
|
/// open(path, oflag, mode) had been called, and the returned file
|
||||||
// Open(...)
|
/// descriptor, if not `fd`, had been changed to `fd`.
|
||||||
|
Open {
|
||||||
|
path: String,
|
||||||
|
mode: u32,
|
||||||
|
oflag: u32,
|
||||||
|
fd: FileDesc,
|
||||||
|
},
|
||||||
Dup2(FileDesc, FileDesc),
|
Dup2(FileDesc, FileDesc),
|
||||||
Close(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
|
// Perform file actions to modify the cloned file table
|
||||||
for file_action in file_actions {
|
for file_action in file_actions {
|
||||||
match file_action {
|
match file_action {
|
||||||
FileAction::Dup2(old_fd, new_fd) => {
|
&FileAction::Open { ref path, mode, oflag, fd} => {
|
||||||
let file = cloned_file_table.get(*old_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 {
|
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) => {
|
&FileAction::Close(fd) => {
|
||||||
cloned_file_table.del(*fd)?;
|
cloned_file_table.del(fd)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ pub struct FdOp {
|
|||||||
srcfd: u32,
|
srcfd: u32,
|
||||||
oflag: u32,
|
oflag: u32,
|
||||||
mode: u32,
|
mode: u32,
|
||||||
path: *const u8,
|
path: *const i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_file_actions_safely(fdop_ptr: *const FdOp) -> Result<Vec<FileAction>, Error> {
|
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 {
|
let file_action = match fdop.cmd {
|
||||||
FDOP_CLOSE => FileAction::Close(fdop.fd),
|
FDOP_CLOSE => FileAction::Close(fdop.fd),
|
||||||
FDOP_DUP2 => FileAction::Dup2(fdop.srcfd, fdop.fd),
|
FDOP_DUP2 => FileAction::Dup2(fdop.srcfd, fdop.fd),
|
||||||
FDOP_OPEN => {
|
FDOP_OPEN => FileAction::Open {
|
||||||
return errno!(EINVAL, "Not implemented");
|
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");
|
return errno!(EINVAL, "Unknown file action command");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user