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( | ||||
|         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,7 +43,6 @@ impl Default for rlimit_t { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug, Copy, Clone)] | ||||
| #[allow(non_camel_case_types)] | ||||
| pub enum resource_t { | ||||
| @ -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 => { | ||||
|             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 => { | ||||
|             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); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ pub enum FutexOp { | ||||
|     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,22 +46,27 @@ 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) { | ||||
|         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
 | ||||
| @ -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