reformat code using cargo fmt
This commit is contained in:
parent
dd3de96b8e
commit
6e871f7948
@ -68,7 +68,7 @@ fn parse_arguments(
|
||||
|
||||
// TODO: make sure do_boot can only be called once
|
||||
fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> {
|
||||
// info!("boot: path: {:?}, argv: {:?}", path_str, argv);
|
||||
// info!("boot: path: {:?}, argv: {:?}", path_str, argv);
|
||||
util::mpx_util::mpx_enable()?;
|
||||
|
||||
let envp = std::vec::Vec::new();
|
||||
|
@ -24,7 +24,10 @@ impl convert::From<(Errno, &'static str)> for Error {
|
||||
|
||||
impl convert::From<std::io::Error> for Error {
|
||||
fn from(info: std::io::Error) -> Error {
|
||||
Error::new(Errno::from_errno(info.raw_os_error().unwrap()), "std::io::Error")
|
||||
Error::new(
|
||||
Errno::from_errno(info.raw_os_error().unwrap()),
|
||||
"std::io::Error",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ impl AccessModes {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bitflags! {
|
||||
pub struct AccessFlags : u32 {
|
||||
const AT_SYMLINK_NOFOLLOW = 0x100;
|
||||
@ -31,11 +30,18 @@ impl AccessFlags {
|
||||
}
|
||||
}
|
||||
|
||||
pub const AT_FDCWD: i32 = -100;
|
||||
|
||||
pub const AT_FDCWD : i32 = -100;
|
||||
|
||||
pub fn do_faccessat(dirfd: Option<FileDesc>, path: &str, mode: AccessModes, flags: AccessFlags) -> Result<(), Error> {
|
||||
info!("faccessat: dirfd: {:?}, path: {:?}, mode: {:?}, flags: {:?}", dirfd, path, mode, flags);
|
||||
pub fn do_faccessat(
|
||||
dirfd: Option<FileDesc>,
|
||||
path: &str,
|
||||
mode: AccessModes,
|
||||
flags: AccessFlags,
|
||||
) -> Result<(), Error> {
|
||||
info!(
|
||||
"faccessat: dirfd: {:?}, path: {:?}, mode: {:?}, flags: {:?}",
|
||||
dirfd, path, mode, flags
|
||||
);
|
||||
match dirfd {
|
||||
// TODO: handle dirfd
|
||||
Some(dirfd) => errno!(ENOSYS, "cannot accept dirfd"),
|
||||
|
@ -377,7 +377,7 @@ impl File for StdoutFile {
|
||||
mode: 0,
|
||||
nlinks: 0,
|
||||
uid: 0,
|
||||
gid: 0
|
||||
gid: 0,
|
||||
})
|
||||
}
|
||||
|
||||
@ -493,7 +493,7 @@ impl File for StdinFile {
|
||||
mode: 0,
|
||||
nlinks: 0,
|
||||
uid: 0,
|
||||
gid: 0
|
||||
gid: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,12 @@ impl FileTable {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dup(&mut self, fd: FileDesc, min_fd: FileDesc, close_on_spawn: bool) -> Result<FileDesc, Error> {
|
||||
pub fn dup(
|
||||
&mut self,
|
||||
fd: FileDesc,
|
||||
min_fd: FileDesc,
|
||||
close_on_spawn: bool,
|
||||
) -> Result<FileDesc, Error> {
|
||||
let file_ref = self.get(fd)?;
|
||||
|
||||
let min_fd = min_fd as usize;
|
||||
@ -34,11 +39,13 @@ impl FileTable {
|
||||
}
|
||||
}
|
||||
|
||||
table.iter()
|
||||
table
|
||||
.iter()
|
||||
.enumerate()
|
||||
.skip(min_fd as usize)
|
||||
.find(|&(idx, opt)| opt.is_none())
|
||||
.unwrap().0
|
||||
.unwrap()
|
||||
.0
|
||||
} as FileDesc;
|
||||
|
||||
self.put_at(min_free_fd, file_ref, close_on_spawn);
|
||||
@ -50,7 +57,8 @@ impl FileTable {
|
||||
let mut table = &mut self.table;
|
||||
|
||||
let min_free_fd = if self.num_fds < table.len() {
|
||||
table.iter()
|
||||
table
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|&(idx, opt)| opt.is_none())
|
||||
.unwrap()
|
||||
|
@ -2,8 +2,8 @@ use rcore_fs::vfs::{FileSystem, FsError, INode};
|
||||
use rcore_fs_sefs::SEFS;
|
||||
use std::fmt;
|
||||
|
||||
use super::*;
|
||||
use super::sgx_impl::SgxStorage;
|
||||
use super::*;
|
||||
|
||||
lazy_static! {
|
||||
/// The root of file system
|
||||
|
@ -2,8 +2,8 @@ use super::*;
|
||||
use std::any::Any;
|
||||
use std::collections::btree_map::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::vec::Vec;
|
||||
use std::sync::atomic::spin_loop_hint;
|
||||
use std::vec::Vec;
|
||||
|
||||
/// Forward to host `poll`
|
||||
/// (sgx_libc doesn't have `select`)
|
||||
@ -81,7 +81,11 @@ pub fn do_select(
|
||||
Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32,
|
||||
};
|
||||
|
||||
let ret = try_libc!(libc::ocall::poll(polls.as_mut_ptr(), polls.len() as u64, timeout));
|
||||
let ret = try_libc!(libc::ocall::poll(
|
||||
polls.as_mut_ptr(),
|
||||
polls.len() as u64,
|
||||
timeout
|
||||
));
|
||||
|
||||
// convert fd back and write fdset
|
||||
readfds.clear();
|
||||
@ -105,7 +109,11 @@ pub fn do_select(
|
||||
}
|
||||
|
||||
pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Error> {
|
||||
info!("poll: {:?}, timeout: {}", polls.iter().map(|p| p.fd).collect::<Vec<_>>(), timeout);
|
||||
info!(
|
||||
"poll: {:?}, timeout: {}",
|
||||
polls.iter().map(|p| p.fd).collect::<Vec<_>>(),
|
||||
timeout
|
||||
);
|
||||
|
||||
let current_ref = process::get_current();
|
||||
let mut proc = current_ref.lock().unwrap();
|
||||
@ -138,7 +146,11 @@ pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Erro
|
||||
return errno!(EBADF, "not a socket");
|
||||
}
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::poll(polls.as_mut_ptr(), polls.len() as u64, timeout));
|
||||
let ret = try_libc!(libc::ocall::poll(
|
||||
polls.as_mut_ptr(),
|
||||
polls.len() as u64,
|
||||
timeout
|
||||
));
|
||||
// recover fd ?
|
||||
Ok(ret as usize)
|
||||
}
|
||||
@ -258,8 +270,12 @@ impl EpollFileInner {
|
||||
host_fd: FileDesc,
|
||||
event: *const libc::epoll_event,
|
||||
) -> Result<(), Error> {
|
||||
let ret =
|
||||
try_libc!(libc::ocall::epoll_ctl(self.epoll_fd, op, host_fd as c_int, event as *mut _));
|
||||
let ret = try_libc!(libc::ocall::epoll_ctl(
|
||||
self.epoll_fd,
|
||||
op,
|
||||
host_fd as c_int,
|
||||
event as *mut _
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -270,14 +286,12 @@ impl EpollFileInner {
|
||||
events: &mut [libc::epoll_event],
|
||||
timeout: c_int,
|
||||
) -> Result<usize, Error> {
|
||||
let ret = try_libc!(
|
||||
libc::ocall::epoll_wait(
|
||||
self.epoll_fd,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
timeout,
|
||||
)
|
||||
);
|
||||
let ret = try_libc!(libc::ocall::epoll_wait(
|
||||
self.epoll_fd,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
timeout,
|
||||
));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,35 @@
|
||||
use {process, std};
|
||||
use prelude::*;
|
||||
use process::Process;
|
||||
use rcore_fs::vfs::{FileType, FsError, INode, Metadata, Timespec};
|
||||
use std::sgxfs as fs_impl;
|
||||
use {process, std};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub use self::access::{do_access, do_faccessat, AccessFlags, AccessModes, AT_FDCWD};
|
||||
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
|
||||
pub use self::file_table::{FileDesc, FileTable};
|
||||
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
|
||||
pub use self::socket_file::{SocketFile, AsSocket};
|
||||
pub use self::unix_socket::{UnixSocketFile, AsUnixSocket};
|
||||
use self::inode_file::OpenOptions;
|
||||
pub use self::pipe::Pipe;
|
||||
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
|
||||
pub use self::io_multiplexing::*;
|
||||
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
|
||||
use self::null::NullFile;
|
||||
use std::mem::uninitialized;
|
||||
pub use self::pipe::Pipe;
|
||||
pub use self::socket_file::{AsSocket, SocketFile};
|
||||
pub use self::unix_socket::{AsUnixSocket, UnixSocketFile};
|
||||
use std::any::Any;
|
||||
use std::mem::uninitialized;
|
||||
|
||||
mod access;
|
||||
mod file;
|
||||
mod file_table;
|
||||
mod inode_file;
|
||||
mod socket_file;
|
||||
mod io_multiplexing;
|
||||
mod null;
|
||||
mod pipe;
|
||||
mod sgx_impl;
|
||||
mod io_multiplexing;
|
||||
mod access;
|
||||
mod null;
|
||||
mod socket_file;
|
||||
mod unix_socket;
|
||||
|
||||
|
||||
pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
|
||||
let flags = OpenFlags::from_bits_truncate(flags);
|
||||
info!(
|
||||
@ -46,7 +45,10 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result<FileDesc, Error> {
|
||||
|
||||
let fd = {
|
||||
let close_on_spawn = flags.contains(OpenFlags::CLOEXEC);
|
||||
proc.get_files().lock().unwrap().put(file_ref, close_on_spawn)
|
||||
proc.get_files()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.put(file_ref, close_on_spawn)
|
||||
};
|
||||
Ok(fd)
|
||||
}
|
||||
@ -353,7 +355,8 @@ pub fn do_sendfile(
|
||||
in_fd: FileDesc,
|
||||
offset: Option<off_t>,
|
||||
count: usize,
|
||||
) -> Result<(usize, usize), Error> { // (len, offset)
|
||||
) -> Result<(usize, usize), Error> {
|
||||
// (len, offset)
|
||||
info!(
|
||||
"sendfile: out: {}, in: {}, offset: {:?}, count: {}",
|
||||
out_fd, in_fd, offset, count
|
||||
@ -683,7 +686,6 @@ pub unsafe fn write_cstr(ptr: *mut u8, s: &str) {
|
||||
ptr.add(s.len()).write(0);
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FcntlCmd {
|
||||
/// Duplicate the file descriptor fd using the lowest-numbered available
|
||||
@ -727,11 +729,11 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
|
||||
FcntlCmd::DupFd(min_fd) => {
|
||||
let dup_fd = files.dup(fd, *min_fd, false)?;
|
||||
dup_fd as isize
|
||||
},
|
||||
}
|
||||
FcntlCmd::DupFdCloexec(min_fd) => {
|
||||
let dup_fd = files.dup(fd, *min_fd, true)?;
|
||||
dup_fd as isize
|
||||
},
|
||||
}
|
||||
FcntlCmd::GetFd() => {
|
||||
let entry = files.get_entry(fd)?;
|
||||
let fd_flags = if entry.is_close_on_spawn() {
|
||||
@ -740,12 +742,12 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
|
||||
0
|
||||
};
|
||||
fd_flags as isize
|
||||
},
|
||||
}
|
||||
FcntlCmd::SetFd(fd_flags) => {
|
||||
let entry = files.get_entry_mut(fd)?;
|
||||
entry.set_close_on_spawn((fd_flags & libc::FD_CLOEXEC as u32) != 0);
|
||||
0
|
||||
},
|
||||
}
|
||||
FcntlCmd::GetFl() => {
|
||||
let file = files.get(fd)?;
|
||||
if let Ok(socket) = file.as_socket() {
|
||||
|
@ -2,12 +2,12 @@ use rcore_fs::dev::TimeProvider;
|
||||
use rcore_fs::vfs::Timespec;
|
||||
use rcore_fs_sefs::dev::*;
|
||||
use std::boxed::Box;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sgxfs::{remove, OpenOptions, SgxFile};
|
||||
use std::sync::{SgxMutex as Mutex, Arc};
|
||||
use std::sync::{Arc, SgxMutex as Mutex};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub struct SgxStorage {
|
||||
path: PathBuf,
|
||||
@ -19,7 +19,7 @@ impl SgxStorage {
|
||||
// assert!(path.as_ref().is_dir());
|
||||
SgxStorage {
|
||||
path: path.as_ref().to_path_buf(),
|
||||
file_cache: Mutex::new(BTreeMap::new())
|
||||
file_cache: Mutex::new(BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
/// Get file by `file_id`.
|
||||
|
@ -33,19 +33,30 @@ impl Drop for SocketFile {
|
||||
let ret = unsafe { libc::ocall::close(self.fd) };
|
||||
if ret < 0 {
|
||||
let errno = unsafe { libc::errno() };
|
||||
warn!("socket (host fd: {}) close failed: errno = {}", self.fd, errno);
|
||||
warn!(
|
||||
"socket (host fd: {}) close failed: errno = {}",
|
||||
self.fd, errno
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl File for SocketFile {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
let ret = try_libc!(libc::ocall::read(self.fd, buf.as_mut_ptr() as *mut c_void, buf.len()));
|
||||
let ret = try_libc!(libc::ocall::read(
|
||||
self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len()
|
||||
));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
|
||||
let ret = try_libc!(libc::ocall::write(self.fd, buf.as_ptr() as *const c_void, buf.len()));
|
||||
let ret = try_libc!(libc::ocall::write(
|
||||
self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len()
|
||||
));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
@ -103,7 +114,7 @@ impl File for SocketFile {
|
||||
mode: 0,
|
||||
nlinks: 0,
|
||||
uid: 0,
|
||||
gid: 0
|
||||
gid: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
use super::*;
|
||||
use std::collections::btree_map::BTreeMap;
|
||||
use util::ring_buf::{RingBufReader, RingBufWriter, RingBuf};
|
||||
use std::sync::SgxMutex as Mutex;
|
||||
use alloc::prelude::ToString;
|
||||
use std::collections::btree_map::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::sync::atomic::spin_loop_hint;
|
||||
use std::sync::SgxMutex as Mutex;
|
||||
use util::ring_buf::{RingBuf, RingBufReader, RingBufWriter};
|
||||
|
||||
pub struct UnixSocketFile {
|
||||
inner: Mutex<UnixSocket>
|
||||
inner: Mutex<UnixSocket>,
|
||||
}
|
||||
|
||||
impl File for UnixSocketFile {
|
||||
@ -77,7 +77,7 @@ impl File for UnixSocketFile {
|
||||
mode: 0,
|
||||
nlinks: 0,
|
||||
uid: 0,
|
||||
gid: 0
|
||||
gid: 0,
|
||||
})
|
||||
}
|
||||
|
||||
@ -105,7 +105,9 @@ impl File for UnixSocketFile {
|
||||
impl UnixSocketFile {
|
||||
pub fn new(socket_type: c_int, protocol: c_int) -> Result<Self, Error> {
|
||||
let inner = UnixSocket::new(socket_type, protocol)?;
|
||||
Ok(UnixSocketFile { inner: Mutex::new(inner) })
|
||||
Ok(UnixSocketFile {
|
||||
inner: Mutex::new(inner),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bind(&self, path: impl AsRef<str>) -> Result<(), Error> {
|
||||
@ -121,7 +123,9 @@ impl UnixSocketFile {
|
||||
pub fn accept(&self) -> Result<UnixSocketFile, Error> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let new_socket = inner.accept()?;
|
||||
Ok(UnixSocketFile { inner: Mutex::new(new_socket) })
|
||||
Ok(UnixSocketFile {
|
||||
inner: Mutex::new(new_socket),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn connect(&self, path: impl AsRef<str>) -> Result<(), Error> {
|
||||
@ -146,7 +150,6 @@ impl Debug for UnixSocketFile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait AsUnixSocket {
|
||||
fn as_unix_socket(&self) -> Result<&UnixSocketFile, Error>;
|
||||
}
|
||||
@ -159,7 +162,6 @@ impl AsUnixSocket for FileRef {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct UnixSocket {
|
||||
obj: Option<Arc<UnixSocketObject>>,
|
||||
status: Status,
|
||||
@ -177,7 +179,7 @@ impl UnixSocket {
|
||||
if socket_type == libc::SOCK_STREAM && protocol == 0 {
|
||||
Ok(UnixSocket {
|
||||
obj: None,
|
||||
status: Status::None
|
||||
status: Status::None,
|
||||
})
|
||||
} else {
|
||||
errno!(ENOSYS, "unimplemented unix socket type")
|
||||
@ -221,8 +223,8 @@ impl UnixSocket {
|
||||
if let Status::Listening = self.status {
|
||||
return errno!(EINVAL, "unix socket is listening?");
|
||||
}
|
||||
let obj = UnixSocketObject::get(path)
|
||||
.ok_or(Error::new(EINVAL, "unix socket path not found"))?;
|
||||
let obj =
|
||||
UnixSocketObject::get(path).ok_or(Error::new(EINVAL, "unix socket path not found"))?;
|
||||
let (channel1, channel2) = Channel::new_pair();
|
||||
self.status = Status::Connected(channel1);
|
||||
obj.push(UnixSocket {
|
||||
@ -240,7 +242,8 @@ impl UnixSocket {
|
||||
self.channel()?.writer.write(buf)
|
||||
}
|
||||
|
||||
pub fn poll(&self) -> Result<(bool, bool, bool), Error> { // (read, write, error)
|
||||
pub fn poll(&self) -> Result<(bool, bool, bool), Error> {
|
||||
// (read, write, error)
|
||||
let channel = self.channel()?;
|
||||
let r = channel.reader.can_read();
|
||||
let w = channel.writer.can_write();
|
||||
@ -251,7 +254,9 @@ impl UnixSocket {
|
||||
const FIONREAD: c_int = 0x541B; // Get the number of bytes to read
|
||||
if cmd == FIONREAD {
|
||||
let bytes_to_read = self.channel()?.reader.bytes_to_read();
|
||||
unsafe { argp.write(bytes_to_read as c_int); }
|
||||
unsafe {
|
||||
argp.write(bytes_to_read as c_int);
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
warn!("ioctl for unix socket is unimplemented");
|
||||
@ -302,7 +307,7 @@ impl UnixSocketObject {
|
||||
}
|
||||
let obj = Arc::new(UnixSocketObject {
|
||||
path: path.as_ref().to_string(),
|
||||
accepted_sockets: Mutex::new(VecDeque::new())
|
||||
accepted_sockets: Mutex::new(VecDeque::new()),
|
||||
});
|
||||
paths.insert(path.as_ref().to_string(), obj.clone());
|
||||
Ok(obj)
|
||||
@ -315,7 +320,7 @@ impl UnixSocketObject {
|
||||
|
||||
struct Channel {
|
||||
reader: RingBufReader,
|
||||
writer: RingBufWriter
|
||||
writer: RingBufWriter,
|
||||
}
|
||||
|
||||
unsafe impl Send for Channel {}
|
||||
@ -340,6 +345,6 @@ impl Channel {
|
||||
pub const DEFAULT_BUF_SIZE: usize = 1 * 1024 * 1024;
|
||||
|
||||
lazy_static! {
|
||||
static ref UNIX_SOCKET_OBJS: Mutex<BTreeMap<String, Arc<UnixSocketObject>>>
|
||||
= Mutex::new(BTreeMap::new());
|
||||
static ref UNIX_SOCKET_OBJS: Mutex<BTreeMap<String, Arc<UnixSocketObject>>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
}
|
||||
|
@ -36,12 +36,12 @@ mod prelude;
|
||||
mod entry;
|
||||
mod errno;
|
||||
mod fs;
|
||||
mod misc;
|
||||
mod process;
|
||||
mod syscall;
|
||||
mod time;
|
||||
mod util;
|
||||
mod vm;
|
||||
mod misc;
|
||||
|
||||
use prelude::*;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::*;
|
||||
|
||||
mod uname;
|
||||
mod rlimit;
|
||||
mod uname;
|
||||
|
||||
pub use self::uname::{utsname_t, do_uname};
|
||||
pub use self::rlimit::{rlimit_t, resource_t, ResourceLimits, ResourceLimitsRef, do_prlimit};
|
||||
pub use self::rlimit::{do_prlimit, resource_t, rlimit_t, ResourceLimits, ResourceLimitsRef};
|
||||
pub use self::uname::{do_uname, utsname_t};
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use process::{pid_t};
|
||||
use process::pid_t;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ResourceLimits {
|
||||
@ -21,13 +21,12 @@ impl Default for ResourceLimits {
|
||||
fn default() -> ResourceLimits {
|
||||
// TODO: set appropriate limits for resources
|
||||
let mut rlimits = ResourceLimits {
|
||||
rlimits: [ Default::default(); RLIMIT_COUNT ],
|
||||
rlimits: [Default::default(); RLIMIT_COUNT],
|
||||
};
|
||||
rlimits
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct rlimit_t {
|
||||
@ -44,41 +43,40 @@ impl Default for rlimit_t {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum resource_t {
|
||||
RLIMIT_CPU = 0,
|
||||
RLIMIT_FSIZE = 1,
|
||||
RLIMIT_DATA = 2,
|
||||
RLIMIT_STACK = 3,
|
||||
RLIMIT_CORE = 4,
|
||||
RLIMIT_RSS = 5,
|
||||
RLIMIT_NPROC = 6,
|
||||
RLIMIT_NOFILE = 7,
|
||||
RLIMIT_MEMLOCK = 8,
|
||||
RLIMIT_AS = 9,
|
||||
RLIMIT_LOCKS = 10,
|
||||
RLIMIT_SIGPENDING = 11,
|
||||
RLIMIT_MSGQUEUE = 12,
|
||||
RLIMIT_NICE = 13,
|
||||
RLIMIT_RTPRIO = 14,
|
||||
RLIMIT_CPU = 0,
|
||||
RLIMIT_FSIZE = 1,
|
||||
RLIMIT_DATA = 2,
|
||||
RLIMIT_STACK = 3,
|
||||
RLIMIT_CORE = 4,
|
||||
RLIMIT_RSS = 5,
|
||||
RLIMIT_NPROC = 6,
|
||||
RLIMIT_NOFILE = 7,
|
||||
RLIMIT_MEMLOCK = 8,
|
||||
RLIMIT_AS = 9,
|
||||
RLIMIT_LOCKS = 10,
|
||||
RLIMIT_SIGPENDING = 11,
|
||||
RLIMIT_MSGQUEUE = 12,
|
||||
RLIMIT_NICE = 13,
|
||||
RLIMIT_RTPRIO = 14,
|
||||
}
|
||||
const RLIMIT_COUNT: usize = 15;
|
||||
|
||||
impl resource_t {
|
||||
pub fn from_u32(bits: u32) -> Result<resource_t, Error> {
|
||||
match bits {
|
||||
0 => Ok(resource_t::RLIMIT_CPU),
|
||||
1 => Ok(resource_t::RLIMIT_FSIZE),
|
||||
2 => Ok(resource_t::RLIMIT_DATA),
|
||||
3 => Ok(resource_t::RLIMIT_STACK),
|
||||
4 => Ok(resource_t::RLIMIT_CORE),
|
||||
5 => Ok(resource_t::RLIMIT_RSS),
|
||||
6 => Ok(resource_t::RLIMIT_NPROC),
|
||||
7 => Ok(resource_t::RLIMIT_NOFILE),
|
||||
8 => Ok(resource_t::RLIMIT_MEMLOCK),
|
||||
9 => Ok(resource_t::RLIMIT_AS),
|
||||
0 => Ok(resource_t::RLIMIT_CPU),
|
||||
1 => Ok(resource_t::RLIMIT_FSIZE),
|
||||
2 => Ok(resource_t::RLIMIT_DATA),
|
||||
3 => Ok(resource_t::RLIMIT_STACK),
|
||||
4 => Ok(resource_t::RLIMIT_CORE),
|
||||
5 => Ok(resource_t::RLIMIT_RSS),
|
||||
6 => Ok(resource_t::RLIMIT_NPROC),
|
||||
7 => Ok(resource_t::RLIMIT_NOFILE),
|
||||
8 => Ok(resource_t::RLIMIT_MEMLOCK),
|
||||
9 => Ok(resource_t::RLIMIT_AS),
|
||||
10 => Ok(resource_t::RLIMIT_LOCKS),
|
||||
11 => Ok(resource_t::RLIMIT_SIGPENDING),
|
||||
12 => Ok(resource_t::RLIMIT_MSGQUEUE),
|
||||
@ -89,7 +87,6 @@ impl resource_t {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn do_prlimit(
|
||||
pid: pid_t,
|
||||
resource: resource_t,
|
||||
@ -98,8 +95,7 @@ pub fn do_prlimit(
|
||||
) -> Result<(), Error> {
|
||||
let process_ref = if pid == 0 {
|
||||
process::get_current()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
process::get(pid)?
|
||||
};
|
||||
let mut process = process_ref.lock().unwrap();
|
||||
|
@ -34,7 +34,7 @@ pub fn do_uname(name: &mut utsname_t) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref SYSNAME : CString = CString::new("Occlum").unwrap();
|
||||
static ref SYSNAME: CString = CString::new("Occlum").unwrap();
|
||||
static ref NODENAME: CString = CString::new("occlum-node").unwrap();
|
||||
static ref RELEASE: CString = CString::new("0.1").unwrap();
|
||||
static ref VERSION: CString = CString::new("0.1").unwrap();
|
||||
@ -43,9 +43,8 @@ lazy_static! {
|
||||
}
|
||||
|
||||
fn copy_from_cstr_to_u8_array(src: &CStr, dst: &mut [u8]) {
|
||||
let src : &[u8] = src.to_bytes_with_nul();
|
||||
let src: &[u8] = src.to_bytes_with_nul();
|
||||
let len = min(dst.len() - 1, src.len());
|
||||
dst[..len].copy_from_slice(&src[..len]);
|
||||
dst[len] = 0;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ pub use std::sync::{
|
||||
//pub use std::borrow::BorrowMut;
|
||||
pub use std::borrow::ToOwned;
|
||||
pub use std::boxed::Box;
|
||||
pub use std::cmp::{max, min};
|
||||
pub use std::cmp::{Ordering, PartialOrd};
|
||||
pub use std::collections::{HashMap, VecDeque};
|
||||
pub use std::fmt::{Debug, Display};
|
||||
@ -22,7 +23,6 @@ pub use std::iter::Iterator;
|
||||
pub use std::rc::Rc;
|
||||
pub use std::string::String;
|
||||
pub use std::vec::Vec;
|
||||
pub use std::cmp::{min, max};
|
||||
|
||||
pub use errno::Errno;
|
||||
pub use errno::Errno::*;
|
||||
|
@ -22,22 +22,28 @@ impl ArchPrctlCode {
|
||||
}
|
||||
|
||||
pub fn do_arch_prctl(code: ArchPrctlCode, addr: *mut usize) -> Result<(), Error> {
|
||||
info!("do_arch_prctl: code: {:?}, addr: {:#o}", code, addr as usize);
|
||||
info!(
|
||||
"do_arch_prctl: code: {:?}, addr: {:#o}",
|
||||
code, addr as usize
|
||||
);
|
||||
match code {
|
||||
ArchPrctlCode::ARCH_SET_FS => {
|
||||
ArchPrctlCode::ARCH_SET_FS => {
|
||||
let current_ref = get_current();
|
||||
let mut current = current_ref.lock().unwrap();
|
||||
let task = &mut current.task;
|
||||
task.user_fsbase_addr = addr as usize;
|
||||
},
|
||||
ArchPrctlCode::ARCH_GET_FS => {
|
||||
}
|
||||
ArchPrctlCode::ARCH_GET_FS => {
|
||||
let current_ref = get_current();
|
||||
let current = current_ref.lock().unwrap();
|
||||
let task = ¤t.task;
|
||||
unsafe { *addr = task.user_fsbase_addr; }
|
||||
},
|
||||
ArchPrctlCode::ARCH_SET_GS | ArchPrctlCode::ARCH_GET_GS
|
||||
=> return errno!(EINVAL, "GS cannot be accessed from the user space"),
|
||||
unsafe {
|
||||
*addr = task.user_fsbase_addr;
|
||||
}
|
||||
}
|
||||
ArchPrctlCode::ARCH_SET_GS | ArchPrctlCode::ARCH_GET_GS => {
|
||||
return errno!(EINVAL, "GS cannot be accessed from the user space");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ pub fn do_exit(exit_status: i32) {
|
||||
|
||||
// Notify another process, if any, that waits on ctid (see set_tid_address)
|
||||
if let Some(ctid) = current.clear_child_tid {
|
||||
unsafe { atomic_store(ctid, 0); }
|
||||
unsafe {
|
||||
atomic_store(ctid, 0);
|
||||
}
|
||||
futex_wake(ctid as *const i32, 1);
|
||||
}
|
||||
|
||||
|
@ -7,18 +7,18 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum FutexOp {
|
||||
FUTEX_WAIT = 0,
|
||||
FUTEX_WAKE = 1,
|
||||
FUTEX_FD = 2,
|
||||
FUTEX_REQUEUE = 3,
|
||||
FUTEX_CMP_REQUEUE = 4,
|
||||
FUTEX_WAKE_OP = 5,
|
||||
FUTEX_LOCK_PI = 6,
|
||||
FUTEX_UNLOCK_PI = 7,
|
||||
FUTEX_TRYLOCK_PI = 8,
|
||||
FUTEX_WAIT_BITSET = 9,
|
||||
FUTEX_WAIT = 0,
|
||||
FUTEX_WAKE = 1,
|
||||
FUTEX_FD = 2,
|
||||
FUTEX_REQUEUE = 3,
|
||||
FUTEX_CMP_REQUEUE = 4,
|
||||
FUTEX_WAKE_OP = 5,
|
||||
FUTEX_LOCK_PI = 6,
|
||||
FUTEX_UNLOCK_PI = 7,
|
||||
FUTEX_TRYLOCK_PI = 8,
|
||||
FUTEX_WAIT_BITSET = 9,
|
||||
}
|
||||
const FUTEX_OP_MASK : u32 = 0x0000_000F;
|
||||
const FUTEX_OP_MASK: u32 = 0x0000_000F;
|
||||
|
||||
impl FutexOp {
|
||||
pub fn from_u32(bits: u32) -> Result<FutexOp, Error> {
|
||||
@ -44,12 +44,11 @@ bitflags! {
|
||||
const FUTEX_CLOCK_REALTIME = 256;
|
||||
}
|
||||
}
|
||||
const FUTEX_FLAGS_MASK : u32 = 0xFFFF_FFF0;
|
||||
const FUTEX_FLAGS_MASK: u32 = 0xFFFF_FFF0;
|
||||
|
||||
impl FutexFlags {
|
||||
pub fn from_u32(bits: u32) -> Result<FutexFlags, Error> {
|
||||
FutexFlags::from_bits(bits).ok_or_else(||
|
||||
Error::new(Errno::EINVAL, "Unknown futex flags"))
|
||||
FutexFlags::from_bits(bits).ok_or_else(|| Error::new(Errno::EINVAL, "Unknown futex flags"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,12 +64,10 @@ pub fn futex_op_and_flags_from_u32(bits: u32) -> Result<(FutexOp, FutexFlags), E
|
||||
Ok((op, flags))
|
||||
}
|
||||
|
||||
|
||||
/// Do futex wait
|
||||
pub fn futex_wait(futex_addr: *const i32, futex_val: i32) -> Result<(), Error> {
|
||||
let futex_key = FutexKey::new(futex_addr);
|
||||
let futex_item = FUTEX_TABLE.lock().unwrap()
|
||||
.get_or_new_item(futex_key);
|
||||
let futex_item = FUTEX_TABLE.lock().unwrap().get_or_new_item(futex_key);
|
||||
|
||||
futex_item.wait(futex_val);
|
||||
|
||||
@ -87,11 +84,8 @@ pub fn futex_wake(futex_addr: *const i32, max_count: usize) -> Result<usize, Err
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
|
||||
lazy_static! {
|
||||
static ref FUTEX_TABLE : SgxMutex<FutexTable> = {
|
||||
SgxMutex::new(FutexTable::new())
|
||||
};
|
||||
static ref FUTEX_TABLE: SgxMutex<FutexTable> = { SgxMutex::new(FutexTable::new()) };
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
|
||||
@ -126,7 +120,9 @@ impl FutexItem {
|
||||
while count < max_count {
|
||||
let waiter = {
|
||||
let waiter_option = queue.pop_front();
|
||||
if waiter_option.is_none() { break; }
|
||||
if waiter_option.is_none() {
|
||||
break;
|
||||
}
|
||||
waiter_option.unwrap()
|
||||
};
|
||||
waiter.wake();
|
||||
@ -165,15 +161,17 @@ impl FutexTable {
|
||||
|
||||
pub fn get_or_new_item(&mut self, key: FutexKey) -> FutexItemRef {
|
||||
let table = &mut self.table;
|
||||
let item = table.entry(key).or_insert_with(|| {
|
||||
Arc::new(FutexItem::new(key))
|
||||
});
|
||||
let item = table
|
||||
.entry(key)
|
||||
.or_insert_with(|| Arc::new(FutexItem::new(key)));
|
||||
item.clone()
|
||||
}
|
||||
|
||||
pub fn get_item(&mut self, key: FutexKey) -> Result<FutexItemRef, Error> {
|
||||
let table = &mut self.table;
|
||||
table.get_mut(&key).map(|item| item.clone())
|
||||
table
|
||||
.get_mut(&key)
|
||||
.map(|item| item.clone())
|
||||
.ok_or_else(|| Error::new(Errno::ENOENT, "futex key cannot be found"))
|
||||
}
|
||||
|
||||
@ -193,7 +191,6 @@ impl FutexTable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Waiter {
|
||||
thread: *const c_void,
|
||||
|
@ -1,12 +1,12 @@
|
||||
pub use self::process::{Status, IDLE_PROCESS};
|
||||
pub use self::task::{get_current, run_task, current_pid};
|
||||
pub use self::process_table::{get};
|
||||
pub use self::arch_prctl::{do_arch_prctl, ArchPrctlCode};
|
||||
pub use self::exit::{do_exit, do_wait4, ChildProcessFilter};
|
||||
pub use self::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp};
|
||||
pub use self::process::{Status, IDLE_PROCESS};
|
||||
pub use self::process_table::get;
|
||||
pub use self::spawn::{do_spawn, FileAction};
|
||||
pub use self::task::{current_pid, get_current, run_task};
|
||||
pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup};
|
||||
pub use self::wait::{WaitQueue, Waiter};
|
||||
pub use self::thread::{do_clone, CloneFlags, ThreadGroup, do_set_tid_address};
|
||||
pub use self::futex::{FutexOp, FutexFlags, futex_op_and_flags_from_u32, futex_wake, futex_wait};
|
||||
pub use self::arch_prctl::{ArchPrctlCode, do_arch_prctl};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type pid_t = u32;
|
||||
@ -64,18 +64,18 @@ pub fn do_getppid() -> pid_t {
|
||||
parent.get_pid()
|
||||
}
|
||||
|
||||
mod arch_prctl;
|
||||
mod exit;
|
||||
mod futex;
|
||||
mod process;
|
||||
mod process_table;
|
||||
mod spawn;
|
||||
mod task;
|
||||
mod wait;
|
||||
mod thread;
|
||||
mod futex;
|
||||
mod arch_prctl;
|
||||
mod wait;
|
||||
|
||||
use self::task::Task;
|
||||
use super::*;
|
||||
use fs::{File, FileRef, FileTable};
|
||||
use misc::ResourceLimitsRef;
|
||||
use vm::{ProcessVM, VMRangeTrait};
|
||||
use misc::{ResourceLimitsRef};
|
||||
|
@ -88,7 +88,7 @@ impl Process {
|
||||
pub fn get_parent(&self) -> &ProcessRef {
|
||||
self.parent.as_ref().unwrap()
|
||||
}
|
||||
pub fn get_children_iter(&self) -> impl Iterator<Item=ProcessRef> + '_ {
|
||||
pub fn get_children_iter(&self) -> impl Iterator<Item = ProcessRef> + '_ {
|
||||
self.children
|
||||
.iter()
|
||||
.filter_map(|child_weak| child_weak.upgrade())
|
||||
|
@ -15,7 +15,10 @@ pub fn remove(pid: pid_t) {
|
||||
}
|
||||
|
||||
pub fn get(pid: pid_t) -> Result<ProcessRef, Error> {
|
||||
PROCESS_TABLE.lock().unwrap().get(&pid)
|
||||
PROCESS_TABLE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&pid)
|
||||
.map(|pr| pr.clone())
|
||||
.ok_or_else(|| Error::new(Errno::ENOENT, "process not found"))
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
use xmas_elf::{ElfFile, header, program, sections};
|
||||
use xmas_elf::symbol_table::Entry;
|
||||
use xmas_elf::{header, program, sections, ElfFile};
|
||||
|
||||
use fs::{File, FileDesc, FileTable, INodeExt, ROOT_INODE, StdinFile, StdoutFile, OpenFlags};
|
||||
use fs::{File, FileDesc, FileTable, INodeExt, OpenFlags, StdinFile, StdoutFile, ROOT_INODE};
|
||||
use misc::ResourceLimitsRef;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::path::Path;
|
||||
use std::sgxfs::SgxFile;
|
||||
use vm::{ProcessVM, VMRangeTrait};
|
||||
use misc::{ResourceLimitsRef};
|
||||
|
||||
use super::*;
|
||||
use super::task::Task;
|
||||
use super::*;
|
||||
|
||||
use self::init_stack::{AuxKey, AuxTable};
|
||||
|
||||
@ -98,7 +98,12 @@ 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::Open { ref path, mode, oflag, 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(file);
|
||||
@ -151,7 +156,11 @@ fn init_task(
|
||||
})
|
||||
}
|
||||
|
||||
fn init_auxtbl(base_addr: usize, program_entry: usize, elf_file: &ElfFile) -> Result<AuxTable, Error> {
|
||||
fn init_auxtbl(
|
||||
base_addr: usize,
|
||||
program_entry: usize,
|
||||
elf_file: &ElfFile,
|
||||
) -> Result<AuxTable, Error> {
|
||||
let mut auxtbl = AuxTable::new();
|
||||
auxtbl.set_val(AuxKey::AT_PAGESZ, 4096)?;
|
||||
auxtbl.set_val(AuxKey::AT_UID, 0)?;
|
||||
|
@ -4,7 +4,6 @@ pub struct ThreadGroup {
|
||||
threads: Vec<ProcessRef>,
|
||||
}
|
||||
|
||||
|
||||
bitflags! {
|
||||
pub struct CloneFlags : u32 {
|
||||
const CLONE_VM = 0x00000100;
|
||||
@ -40,8 +39,10 @@ pub fn do_clone(
|
||||
ctid: Option<*mut pid_t>,
|
||||
new_tls: Option<usize>,
|
||||
) -> Result<pid_t, Error> {
|
||||
info!("clone: flags: {:?}, stack_addr: {:?}, ptid: {:?}, ctid: {:?}, new_tls: {:?}",
|
||||
flags, stack_addr, ptid, ctid, new_tls);
|
||||
info!(
|
||||
"clone: flags: {:?}, stack_addr: {:?}, ptid: {:?}, ctid: {:?}, new_tls: {:?}",
|
||||
flags, stack_addr, ptid, ctid, new_tls
|
||||
);
|
||||
// TODO: return error for unsupported flags
|
||||
|
||||
let current_ref = get_current();
|
||||
@ -75,7 +76,9 @@ pub fn do_clone(
|
||||
process_table::put(new_thread_pid, new_thread_ref.clone());
|
||||
|
||||
if let Some(ptid) = ptid {
|
||||
unsafe { *ptid = new_thread_pid; }
|
||||
unsafe {
|
||||
*ptid = new_thread_pid;
|
||||
}
|
||||
}
|
||||
|
||||
task::enqueue_task(new_thread_ref);
|
||||
|
@ -921,10 +921,7 @@ fn do_fcntl(fd: FileDesc, cmd: u32, arg: u64) -> Result<isize, Error> {
|
||||
}
|
||||
|
||||
fn do_ioctl(fd: FileDesc, cmd: c_int, argp: *mut c_int) -> Result<isize, Error> {
|
||||
info!(
|
||||
"ioctl: fd: {}, cmd: {}, argp: {:?}",
|
||||
fd, cmd, argp
|
||||
);
|
||||
info!("ioctl: fd: {}, cmd: {}, argp: {:?}", fd, cmd, argp);
|
||||
let current_ref = process::get_current();
|
||||
let mut proc = current_ref.lock().unwrap();
|
||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||
@ -994,7 +991,9 @@ fn do_connect(
|
||||
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
|
||||
let addr = addr as *const libc::sockaddr_un;
|
||||
check_ptr(addr)?; // TODO: check addr_len
|
||||
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?.to_string_lossy().into_owned();
|
||||
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
unix_socket.connect(path)?;
|
||||
Ok(0)
|
||||
} else {
|
||||
@ -1066,7 +1065,9 @@ fn do_bind(
|
||||
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
|
||||
let addr = addr as *const libc::sockaddr_un;
|
||||
check_ptr(addr)?; // TODO: check addr_len
|
||||
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?.to_string_lossy().into_owned();
|
||||
let path = clone_cstring_safely(unsafe { (&*addr).sun_path.as_ptr() })?
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
unix_socket.bind(path)?;
|
||||
Ok(0)
|
||||
} else {
|
||||
@ -1152,20 +1153,22 @@ fn do_getpeername(
|
||||
addr: *mut libc::sockaddr,
|
||||
addr_len: *mut libc::socklen_t,
|
||||
) -> Result<isize, Error> {
|
||||
info!("getpeername: fd: {}, addr: {:?}, addr_len: {:?}", fd, addr, addr_len);
|
||||
info!(
|
||||
"getpeername: fd: {}, addr: {:?}, addr_len: {:?}",
|
||||
fd, addr, addr_len
|
||||
);
|
||||
let current_ref = process::get_current();
|
||||
let mut proc = current_ref.lock().unwrap();
|
||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||
if let Ok(socket) = file_ref.as_socket() {
|
||||
let ret = try_libc!(libc::ocall::getpeername(
|
||||
socket.fd(),
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
let ret = try_libc!(libc::ocall::getpeername(socket.fd(), addr, addr_len));
|
||||
Ok(ret as isize)
|
||||
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
|
||||
warn!("getpeername for unix socket is unimplemented");
|
||||
errno!(ENOTCONN, "hack for php: Transport endpoint is not connected")
|
||||
errno!(
|
||||
ENOTCONN,
|
||||
"hack for php: Transport endpoint is not connected"
|
||||
)
|
||||
} else {
|
||||
errno!(EBADF, "not a socket")
|
||||
}
|
||||
@ -1176,16 +1179,15 @@ fn do_getsockname(
|
||||
addr: *mut libc::sockaddr,
|
||||
addr_len: *mut libc::socklen_t,
|
||||
) -> Result<isize, Error> {
|
||||
info!("getsockname: fd: {}, addr: {:?}, addr_len: {:?}", fd, addr, addr_len);
|
||||
info!(
|
||||
"getsockname: fd: {}, addr: {:?}, addr_len: {:?}",
|
||||
fd, addr, addr_len
|
||||
);
|
||||
let current_ref = process::get_current();
|
||||
let mut proc = current_ref.lock().unwrap();
|
||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||
if let Ok(socket) = file_ref.as_socket() {
|
||||
let ret = try_libc!(libc::ocall::getsockname(
|
||||
socket.fd(),
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
let ret = try_libc!(libc::ocall::getsockname(socket.fd(), addr, addr_len));
|
||||
Ok(ret as isize)
|
||||
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
|
||||
warn!("getsockname for unix socket is unimplemented");
|
||||
|
@ -2,8 +2,8 @@ use alloc::alloc::{alloc, dealloc, Layout};
|
||||
|
||||
use std::cmp::{max, min};
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -5,18 +5,22 @@ use std::fmt;
|
||||
|
||||
#[macro_use]
|
||||
mod vm_range;
|
||||
mod vm_area;
|
||||
mod process_vm;
|
||||
mod vm_area;
|
||||
|
||||
pub use self::vm_range::{VMRange, VMRangeTrait};
|
||||
pub use self::vm_area::{VMSpace, VMDomain, VMArea, VMAreaFlags, VM_AREA_FLAG_R, VM_AREA_FLAG_W, VM_AREA_FLAG_X};
|
||||
pub use self::process_vm::ProcessVM;
|
||||
|
||||
pub use self::vm_area::{
|
||||
VMArea, VMAreaFlags, VMDomain, VMSpace, VM_AREA_FLAG_R, VM_AREA_FLAG_W, VM_AREA_FLAG_X,
|
||||
};
|
||||
pub use self::vm_range::{VMRange, VMRangeTrait};
|
||||
|
||||
// TODO: separate proc and flags
|
||||
// TODO: accept fd and offset
|
||||
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> {
|
||||
info!("mmap: addr: {:#x}, size: {:#x}, flags: {:?}", addr, size, flags);
|
||||
info!(
|
||||
"mmap: addr: {:#x}, size: {:#x}, flags: {:?}",
|
||||
addr, size, flags
|
||||
);
|
||||
let current_ref = get_current();
|
||||
let current_process = current_ref.lock().unwrap();
|
||||
let current_vm_ref = current_process.get_vm();
|
||||
@ -68,7 +72,6 @@ pub enum VMGuardAreaType {
|
||||
Dynamic { size: usize },
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Default)]
|
||||
pub struct VMAllocOptions {
|
||||
size: usize,
|
||||
@ -123,7 +126,6 @@ impl fmt::Debug for VMAllocOptions {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum VMAddrOption {
|
||||
Any, // Free to choose any address
|
||||
@ -156,7 +158,6 @@ impl VMAddrOption {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// How VMRange may grow:
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum VMGrowthType {
|
||||
@ -171,7 +172,6 @@ impl Default for VMGrowthType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct VMResizeOptions {
|
||||
new_size: usize,
|
||||
|
@ -46,24 +46,29 @@ impl ProcessVM {
|
||||
) -> Result<ProcessVM, Error> {
|
||||
// Allocate the data domain from the global data space
|
||||
let mut data_domain = {
|
||||
let data_domain_size = code_size + data_size + heap_size
|
||||
+ stack_size + mmap_size;
|
||||
let data_domain = DATA_SPACE.lock().unwrap().alloc_domain(
|
||||
data_domain_size, "data_domain")?;
|
||||
let data_domain_size = code_size + data_size + heap_size + stack_size + mmap_size;
|
||||
let data_domain = DATA_SPACE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.alloc_domain(data_domain_size, "data_domain")?;
|
||||
data_domain
|
||||
};
|
||||
// Allocate vmas from the data domain
|
||||
let (code_vma, data_vma, heap_vma, stack_vma) =
|
||||
match ProcessVM::alloc_vmas(&mut data_domain, code_size,
|
||||
data_size, heap_size, stack_size) {
|
||||
Err(e) => {
|
||||
// Note: we need to handle error here so that we can
|
||||
// deallocate the data domain explictly.
|
||||
DATA_SPACE.lock().unwrap().dealloc_domain(data_domain);
|
||||
return Err(e);
|
||||
},
|
||||
Ok(vmas) => vmas,
|
||||
};
|
||||
let (code_vma, data_vma, heap_vma, stack_vma) = match ProcessVM::alloc_vmas(
|
||||
&mut data_domain,
|
||||
code_size,
|
||||
data_size,
|
||||
heap_size,
|
||||
stack_size,
|
||||
) {
|
||||
Err(e) => {
|
||||
// Note: we need to handle error here so that we can
|
||||
// deallocate the data domain explictly.
|
||||
DATA_SPACE.lock().unwrap().dealloc_domain(data_domain);
|
||||
return Err(e);
|
||||
}
|
||||
Ok(vmas) => vmas,
|
||||
};
|
||||
// Initial value of the program break
|
||||
let brk = heap_vma.get_start();
|
||||
// No mmapped vmas initially
|
||||
@ -92,7 +97,8 @@ impl ProcessVM {
|
||||
let mut alloc_vma_continuously =
|
||||
|addr: &mut usize, desc, size, flags, growth, fill_zeros| -> Result<_, Error> {
|
||||
let mut options = VMAllocOptions::new(size)?;
|
||||
options.addr(VMAddrOption::Fixed(*addr))?
|
||||
options
|
||||
.addr(VMAddrOption::Fixed(*addr))?
|
||||
.growth(growth)?
|
||||
.description(desc)?
|
||||
.fill_zeros(fill_zeros)?;
|
||||
@ -104,17 +110,41 @@ impl ProcessVM {
|
||||
let rx_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_X);
|
||||
let rw_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_W);
|
||||
|
||||
let code_vma = alloc_vma_continuously(&mut addr, "code_vma", code_size,
|
||||
rx_flags, VMGrowthType::Fixed, true)?;
|
||||
let data_vma = alloc_vma_continuously(&mut addr, "data_vma", data_size,
|
||||
rw_flags, VMGrowthType::Fixed, true)?;
|
||||
let heap_vma = alloc_vma_continuously(&mut addr, "heap_vma", 0,
|
||||
rw_flags, VMGrowthType::Upward, true)?;
|
||||
let code_vma = alloc_vma_continuously(
|
||||
&mut addr,
|
||||
"code_vma",
|
||||
code_size,
|
||||
rx_flags,
|
||||
VMGrowthType::Fixed,
|
||||
true,
|
||||
)?;
|
||||
let data_vma = alloc_vma_continuously(
|
||||
&mut addr,
|
||||
"data_vma",
|
||||
data_size,
|
||||
rw_flags,
|
||||
VMGrowthType::Fixed,
|
||||
true,
|
||||
)?;
|
||||
let heap_vma = alloc_vma_continuously(
|
||||
&mut addr,
|
||||
"heap_vma",
|
||||
0,
|
||||
rw_flags,
|
||||
VMGrowthType::Upward,
|
||||
true,
|
||||
)?;
|
||||
// Preserve the space for heap
|
||||
addr += heap_size;
|
||||
// After the heap is the stack
|
||||
let stack_vma = alloc_vma_continuously(&mut addr, "stack_vma", stack_size,
|
||||
rw_flags, VMGrowthType::Downward, false)?;
|
||||
let stack_vma = alloc_vma_continuously(
|
||||
&mut addr,
|
||||
"stack_vma",
|
||||
stack_size,
|
||||
rw_flags,
|
||||
VMGrowthType::Downward,
|
||||
false,
|
||||
)?;
|
||||
Ok((code_vma, data_vma, heap_vma, stack_vma))
|
||||
}
|
||||
|
||||
@ -178,7 +208,8 @@ impl ProcessVM {
|
||||
alloc_options
|
||||
};
|
||||
// TODO: when failed, try to resize data_domain
|
||||
let new_mmap_vma = self.get_data_domain_mut()
|
||||
let new_mmap_vma = self
|
||||
.get_data_domain_mut()
|
||||
.alloc_area(&alloc_options, flags)?;
|
||||
let addr = new_mmap_vma.get_start();
|
||||
self.mmap_vmas.push(Box::new(new_mmap_vma));
|
||||
@ -201,7 +232,8 @@ impl ProcessVM {
|
||||
};
|
||||
|
||||
let removed_mmap_vma = self.mmap_vmas.swap_remove(mmap_vma_i);
|
||||
self.get_data_domain_mut().dealloc_area(unbox(removed_mmap_vma));
|
||||
self.get_data_domain_mut()
|
||||
.dealloc_area(unbox(removed_mmap_vma));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -229,7 +261,8 @@ impl ProcessVM {
|
||||
let new_heap_end = align_up(new_brk, PAGE_SIZE);
|
||||
let new_heap_size = new_heap_end - heap_start;
|
||||
let mut options = VMResizeOptions::new(new_heap_size)?;
|
||||
options.addr(VMAddrOption::Fixed(heap_start))
|
||||
options
|
||||
.addr(VMAddrOption::Fixed(heap_start))
|
||||
.fill_zeros(true);
|
||||
options
|
||||
};
|
||||
@ -261,7 +294,9 @@ impl Drop for ProcessVM {
|
||||
}
|
||||
|
||||
// Remove the domain from its parent space
|
||||
DATA_SPACE.lock().unwrap().dealloc_domain(
|
||||
unbox(self.data_domain.take().unwrap()));
|
||||
DATA_SPACE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.dealloc_domain(unbox(self.data_domain.take().unwrap()));
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,7 @@ impl VMSpace {
|
||||
|
||||
pub fn alloc_domain(&mut self, size: usize, desc: &str) -> Result<VMDomain, Error> {
|
||||
let mut options = VMAllocOptions::new(size)?;
|
||||
options.growth(VMGrowthType::Upward)?
|
||||
.description(desc)?;
|
||||
options.growth(VMGrowthType::Upward)?.description(desc)?;
|
||||
|
||||
let new_range = self.range.alloc_subrange(&options)?;
|
||||
Ok(VMDomain { range: new_range })
|
||||
@ -44,7 +43,6 @@ impl VMSpace {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VMDomain {
|
||||
range: VMRange,
|
||||
@ -78,7 +76,6 @@ impl VMDomain {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VMArea {
|
||||
range: VMRange,
|
||||
@ -97,7 +94,6 @@ impl VMArea {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct VMAreaFlags(pub u32);
|
||||
|
||||
|
@ -46,7 +46,12 @@ pub struct VMRange {
|
||||
impl_vmrange_trait_for!(VMRange, inner);
|
||||
|
||||
impl VMRange {
|
||||
pub unsafe fn new(start: usize, end: usize, growth: VMGrowthType, description: &str) -> Result<VMRange, Error> {
|
||||
pub unsafe fn new(
|
||||
start: usize,
|
||||
end: usize,
|
||||
growth: VMGrowthType,
|
||||
description: &str,
|
||||
) -> Result<VMRange, Error> {
|
||||
if start % PAGE_SIZE != 0 || end % PAGE_SIZE != 0 {
|
||||
return errno!(EINVAL, "Invalid start and/or end");
|
||||
}
|
||||
@ -75,8 +80,10 @@ impl VMRange {
|
||||
debug_assert!(free_space.contains(new_subrange_start));
|
||||
debug_assert!(free_space.contains(new_subrange_end));
|
||||
|
||||
(free_space.index_in_subranges, VMRangeInner::new(
|
||||
new_subrange_start, new_subrange_end, options.growth))
|
||||
(
|
||||
free_space.index_in_subranges,
|
||||
VMRangeInner::new(new_subrange_start, new_subrange_end, options.growth),
|
||||
)
|
||||
};
|
||||
self.get_subranges_mut()
|
||||
.insert(new_subrange_idx, new_subrange_inner);
|
||||
@ -186,7 +193,7 @@ impl VMRange {
|
||||
let pre_range = &range_pair[0];
|
||||
let next_range = &range_pair[1];
|
||||
|
||||
let (free_range_start, free_range_end)= {
|
||||
let (free_range_start, free_range_end) = {
|
||||
let free_range_start = pre_range.get_end();
|
||||
let free_range_end = next_range.get_start();
|
||||
|
||||
@ -209,7 +216,7 @@ impl VMRange {
|
||||
|
||||
match addr {
|
||||
// Want a minimal free_space
|
||||
VMAddrOption::Any => { },
|
||||
VMAddrOption::Any => {}
|
||||
// Prefer to have free_space.start == addr
|
||||
VMAddrOption::Hint(addr) => {
|
||||
if free_space.contains(addr) {
|
||||
@ -218,7 +225,7 @@ impl VMRange {
|
||||
return Ok(free_space);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
// Must have free_space.start == addr
|
||||
VMAddrOption::Fixed(addr) => {
|
||||
if !free_space.contains(addr) {
|
||||
@ -241,20 +248,24 @@ impl VMRange {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if min_big_enough_free_space == None ||
|
||||
free_space < *min_big_enough_free_space.as_ref().unwrap() {
|
||||
if min_big_enough_free_space == None
|
||||
|| free_space < *min_big_enough_free_space.as_ref().unwrap()
|
||||
{
|
||||
min_big_enough_free_space = Some(free_space);
|
||||
}
|
||||
}
|
||||
|
||||
min_big_enough_free_space
|
||||
.ok_or_else(|| Error::new(Errno::ENOMEM, "not enough space"))
|
||||
min_big_enough_free_space.ok_or_else(|| Error::new(Errno::ENOMEM, "not enough space"))
|
||||
}
|
||||
|
||||
fn alloc_from_free_space(&self, free_space: &FreeSpace, options: &VMAllocOptions) -> (usize, usize) {
|
||||
fn alloc_from_free_space(
|
||||
&self,
|
||||
free_space: &FreeSpace,
|
||||
options: &VMAllocOptions,
|
||||
) -> (usize, usize) {
|
||||
// Get valid parameters from options
|
||||
let size = options.size;
|
||||
let addr_option = options.addr;
|
||||
@ -262,8 +273,7 @@ impl VMRange {
|
||||
|
||||
if let VMAddrOption::Fixed(addr) = addr_option {
|
||||
return (addr, addr + size);
|
||||
}
|
||||
else if let VMAddrOption::Hint(addr) = addr_option {
|
||||
} else if let VMAddrOption::Hint(addr) = addr_option {
|
||||
if free_space.start == addr {
|
||||
return (addr, addr + size);
|
||||
}
|
||||
@ -349,7 +359,12 @@ impl VMRange {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn grow_subrange_to(&mut self, subrange: &mut VMRange, new_size: usize, fill_zeros: bool) -> Result<(), Error> {
|
||||
fn grow_subrange_to(
|
||||
&mut self,
|
||||
subrange: &mut VMRange,
|
||||
new_size: usize,
|
||||
fill_zeros: bool,
|
||||
) -> Result<(), Error> {
|
||||
let subrange_i = self.position_subrange(subrange);
|
||||
let subranges = self.get_subranges_mut();
|
||||
|
||||
@ -379,7 +394,8 @@ impl VMRange {
|
||||
memset(mem_ptr, 0 as c_int, mem_size);
|
||||
}
|
||||
}
|
||||
} else { // self.growth == VMGrowthType::Downward
|
||||
} else {
|
||||
// self.growth == VMGrowthType::Downward
|
||||
// Can we grow downard?
|
||||
let max_new_size = {
|
||||
let pre_subrange = &subranges[subrange_i - 1];
|
||||
@ -429,7 +445,6 @@ impl Drop for VMRange {
|
||||
unsafe impl Send for VMRange {}
|
||||
unsafe impl Sync for VMRange {}
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct VMRangeInner {
|
||||
start: usize,
|
||||
|
Loading…
Reference in New Issue
Block a user