diff --git a/src/libos/Enclave_config.xml b/src/libos/Enclave_config.xml
index 5f853be5..7d9f7639 100644
--- a/src/libos/Enclave_config.xml
+++ b/src/libos/Enclave_config.xml
@@ -3,7 +3,7 @@
0
0
0x100000
- 0x1000000
+ 0x2000000
8
1
0
diff --git a/src/libos/src/fs/file.rs b/src/libos/src/fs/file.rs
index a56fb8a8..82ae1e5e 100644
--- a/src/libos/src/fs/file.rs
+++ b/src/libos/src/fs/file.rs
@@ -373,7 +373,7 @@ impl File for StdoutFile {
atime: Timespec { sec: 0, nsec: 0 },
mtime: Timespec { sec: 0, nsec: 0 },
ctime: Timespec { sec: 0, nsec: 0 },
- type_: FileType::File,
+ type_: FileType::CharDevice,
mode: 0,
nlinks: 0,
uid: 0,
@@ -489,7 +489,7 @@ impl File for StdinFile {
atime: Timespec { sec: 0, nsec: 0 },
mtime: Timespec { sec: 0, nsec: 0 },
ctime: Timespec { sec: 0, nsec: 0 },
- type_: FileType::File,
+ type_: FileType::CharDevice,
mode: 0,
nlinks: 0,
uid: 0,
diff --git a/src/libos/src/fs/io_multiplexing.rs b/src/libos/src/fs/io_multiplexing.rs
index 59e1c962..419a1ab8 100644
--- a/src/libos/src/fs/io_multiplexing.rs
+++ b/src/libos/src/fs/io_multiplexing.rs
@@ -1,5 +1,4 @@
use super::*;
-use crate::syscall::AsSocket;
use std::any::Any;
use std::collections::btree_map::BTreeMap;
use std::fmt;
diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs
index e7e6a74e..ad6c7041 100644
--- a/src/libos/src/fs/mod.rs
+++ b/src/libos/src/fs/mod.rs
@@ -9,7 +9,8 @@ use super::*;
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;
+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::io_multiplexing::*;
@@ -27,6 +28,7 @@ mod sgx_impl;
mod io_multiplexing;
mod access;
mod null;
+mod unix_socket;
pub fn do_open(path: &str, flags: u32, mode: u32) -> Result {
@@ -363,7 +365,7 @@ pub fn do_sendfile(
let in_file = file_table.get(in_fd)?;
let out_file = file_table.get(out_fd)?;
- let mut buffer: [u8; 1024] = unsafe { uninitialized() };
+ let mut buffer: [u8; 1024 * 11] = unsafe { uninitialized() };
let mut read_offset = match offset {
Some(offset) => offset,
diff --git a/src/libos/src/fs/socket_file.rs b/src/libos/src/fs/socket_file.rs
index baaa87f8..7391c05b 100644
--- a/src/libos/src/fs/socket_file.rs
+++ b/src/libos/src/fs/socket_file.rs
@@ -90,7 +90,21 @@ impl File for SocketFile {
}
fn metadata(&self) -> Result {
- unimplemented!()
+ Ok(Metadata {
+ dev: 0,
+ inode: 0,
+ size: 0,
+ blk_size: 0,
+ blocks: 0,
+ atime: Timespec { sec: 0, nsec: 0 },
+ mtime: Timespec { sec: 0, nsec: 0 },
+ ctime: Timespec { sec: 0, nsec: 0 },
+ type_: FileType::Socket,
+ mode: 0,
+ nlinks: 0,
+ uid: 0,
+ gid: 0
+ })
}
fn set_len(&self, len: u64) -> Result<(), Error> {
@@ -113,3 +127,15 @@ impl File for SocketFile {
self
}
}
+
+pub trait AsSocket {
+ fn as_socket(&self) -> Result<&SocketFile, Error>;
+}
+
+impl AsSocket for FileRef {
+ fn as_socket(&self) -> Result<&SocketFile, Error> {
+ self.as_any()
+ .downcast_ref::()
+ .ok_or(Error::new(Errno::EBADF, "not a socket"))
+ }
+}
diff --git a/src/libos/src/fs/unix_socket.rs b/src/libos/src/fs/unix_socket.rs
new file mode 100644
index 00000000..6aeae486
--- /dev/null
+++ b/src/libos/src/fs/unix_socket.rs
@@ -0,0 +1,310 @@
+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::fmt;
+
+pub struct UnixSocketFile {
+ inner: Mutex
+}
+
+impl File for UnixSocketFile {
+ fn read(&self, buf: &mut [u8]) -> Result {
+ let mut inner = self.inner.lock().unwrap();
+ inner.read(buf)
+ }
+
+ fn write(&self, buf: &[u8]) -> Result {
+ let mut inner = self.inner.lock().unwrap();
+ inner.write(buf)
+ }
+
+ fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result {
+ self.read(buf)
+ }
+
+ fn write_at(&self, _offset: usize, buf: &[u8]) -> Result {
+ self.write(buf)
+ }
+
+ fn readv(&self, bufs: &mut [&mut [u8]]) -> Result {
+ let mut inner = self.inner.lock().unwrap();
+ let mut total_len = 0;
+ for buf in bufs {
+ match inner.read(buf) {
+ Ok(len) => {
+ total_len += len;
+ }
+ Err(_) if total_len != 0 => break,
+ Err(e) => return Err(e.into()),
+ }
+ }
+ Ok(total_len)
+ }
+
+ fn writev(&self, bufs: &[&[u8]]) -> Result {
+ let mut inner = self.inner.lock().unwrap();
+ let mut total_len = 0;
+ for buf in bufs {
+ match inner.write(buf) {
+ Ok(len) => {
+ total_len += len;
+ }
+ Err(_) if total_len != 0 => break,
+ Err(e) => return Err(e.into()),
+ }
+ }
+ Ok(total_len)
+ }
+
+ fn seek(&self, pos: SeekFrom) -> Result {
+ errno!(ESPIPE, "UnixSocket does not support seek")
+ }
+
+ fn metadata(&self) -> Result {
+ Ok(Metadata {
+ dev: 0,
+ inode: 0,
+ size: 0,
+ blk_size: 0,
+ blocks: 0,
+ atime: Timespec { sec: 0, nsec: 0 },
+ mtime: Timespec { sec: 0, nsec: 0 },
+ ctime: Timespec { sec: 0, nsec: 0 },
+ type_: FileType::Socket,
+ mode: 0,
+ nlinks: 0,
+ uid: 0,
+ gid: 0
+ })
+ }
+
+ fn set_len(&self, len: u64) -> Result<(), Error> {
+ unimplemented!()
+ }
+
+ fn sync_all(&self) -> Result<(), Error> {
+ unimplemented!()
+ }
+
+ fn sync_data(&self) -> Result<(), Error> {
+ unimplemented!()
+ }
+
+ fn read_entry(&self) -> Result {
+ unimplemented!()
+ }
+
+ fn as_any(&self) -> &Any {
+ self
+ }
+}
+
+impl UnixSocketFile {
+ pub fn new(socket_type: c_int, protocol: c_int) -> Result {
+ let inner = UnixSocket::new(socket_type, protocol)?;
+ Ok(UnixSocketFile { inner: Mutex::new(inner) })
+ }
+
+ pub fn bind(&self, path: impl AsRef) -> Result<(), Error> {
+ let mut inner = self.inner.lock().unwrap();
+ inner.bind(path)
+ }
+
+ pub fn listen(&self) -> Result<(), Error> {
+ let mut inner = self.inner.lock().unwrap();
+ inner.listen()
+ }
+
+ pub fn accept(&self) -> Result {
+ let mut inner = self.inner.lock().unwrap();
+ let new_socket = inner.accept()?;
+ Ok(UnixSocketFile { inner: Mutex::new(new_socket) })
+ }
+
+ pub fn connect(&self, path: impl AsRef) -> Result<(), Error> {
+ let mut inner = self.inner.lock().unwrap();
+ inner.connect(path)
+ }
+}
+
+impl Debug for UnixSocketFile {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "UnixSocketFile {{ ... }}")
+ }
+}
+
+
+pub trait AsUnixSocket {
+ fn as_unix_socket(&self) -> Result<&UnixSocketFile, Error>;
+}
+
+impl AsUnixSocket for FileRef {
+ fn as_unix_socket(&self) -> Result<&UnixSocketFile, Error> {
+ self.as_any()
+ .downcast_ref::()
+ .ok_or(Error::new(Errno::EBADF, "not a unix socket"))
+ }
+}
+
+
+pub struct UnixSocket {
+ obj: Option>,
+ status: Status,
+}
+
+enum Status {
+ None,
+ Listening,
+ Connected(Channel),
+}
+
+impl UnixSocket {
+ /// C/S 1: Create a new unix socket
+ pub fn new(socket_type: c_int, protocol: c_int) -> Result {
+ if socket_type == libc::SOCK_STREAM && protocol == 0 {
+ Ok(UnixSocket {
+ obj: None,
+ status: Status::None
+ })
+ } else {
+ errno!(ENOSYS, "unimplemented unix socket type")
+ }
+ }
+
+ /// Server 2: Bind the socket to a file system path
+ pub fn bind(&mut self, path: impl AsRef) -> Result<(), Error> {
+ // TODO: check permission
+ if self.obj.is_some() {
+ return errno!(EINVAL, "The socket is already bound to an address.");
+ }
+ self.obj = Some(UnixSocketObject::create(path)?);
+ Ok(())
+ }
+
+ /// Server 3: Listen to a socket
+ pub fn listen(&mut self) -> Result<(), Error> {
+ self.status = Status::Listening;
+ Ok(())
+ }
+
+ /// Server 4: Accept a connection on listening. Non-blocking.
+ pub fn accept(&mut self) -> Result {
+ match self.status {
+ Status::Listening => {}
+ _ => return errno!(EINVAL, "unix socket is not listening"),
+ };
+ let socket = self.obj.as_mut().unwrap().pop()
+ .ok_or(Error::new(EAGAIN, "no connections are present to be accepted"))?;
+ Ok(socket)
+ }
+
+ /// Client 2: Connect to a path
+ pub fn connect(&mut self, path: impl AsRef) -> Result<(), Error> {
+ 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 (channel1, channel2) = Channel::new_pair();
+ self.status = Status::Connected(channel1);
+ obj.push(UnixSocket {
+ obj: Some(obj.clone()),
+ status: Status::Connected(channel2),
+ });
+ Ok(())
+ }
+
+ pub fn read(&self, buf: &mut [u8]) -> Result {
+ if let Status::Connected(channel) = &self.status {
+ channel.reader.read(buf)
+ } else {
+ errno!(EBADF, "UnixSocket is not connected")
+ }
+ }
+
+ pub fn write(&self, buf: &[u8]) -> Result {
+ if let Status::Connected(channel) = &self.status {
+ channel.writer.write(buf)
+ } else {
+ errno!(EBADF, "UnixSocket is not connected")
+ }
+ }
+}
+
+impl Drop for UnixSocket {
+ fn drop(&mut self) {
+ if let Status::Listening = self.status {
+ let path = &self.obj.as_ref().unwrap().path;
+ UnixSocketObject::remove(path);
+ }
+ }
+}
+
+pub struct UnixSocketObject {
+ path: String,
+ accepted_sockets: Mutex>,
+}
+
+impl UnixSocketObject {
+ fn push(&self, unix_socket: UnixSocket) {
+ let mut queue = self.accepted_sockets.lock().unwrap();
+ queue.push_back(unix_socket);
+ }
+ fn pop(&self) -> Option {
+ let mut queue = self.accepted_sockets.lock().unwrap();
+ queue.pop_front()
+ }
+ fn get(path: impl AsRef) -> Option> {
+ let mut paths = UNIX_SOCKET_OBJS.lock().unwrap();
+ paths.get(path.as_ref()).map(|obj| obj.clone())
+ }
+ fn create(path: impl AsRef) -> Result, Error> {
+ let mut paths = UNIX_SOCKET_OBJS.lock().unwrap();
+ if paths.contains_key(path.as_ref()) {
+ return errno!(EADDRINUSE, "unix socket path already exists");
+ }
+ let obj = Arc::new(UnixSocketObject {
+ path: path.as_ref().to_string(),
+ accepted_sockets: Mutex::new(VecDeque::new())
+ });
+ paths.insert(path.as_ref().to_string(), obj.clone());
+ Ok(obj)
+ }
+ fn remove(path: impl AsRef) {
+ let mut paths = UNIX_SOCKET_OBJS.lock().unwrap();
+ paths.remove(path.as_ref());
+ }
+}
+
+struct Channel {
+ reader: RingBufReader,
+ writer: RingBufWriter
+}
+
+unsafe impl Send for Channel {}
+unsafe impl Sync for Channel {}
+
+impl Channel {
+ fn new_pair() -> (Channel, Channel) {
+ let buf1 = RingBuf::new(DEFAULT_BUF_SIZE);
+ let buf2 = RingBuf::new(DEFAULT_BUF_SIZE);
+ let channel1 = Channel {
+ reader: buf1.reader,
+ writer: buf2.writer,
+ };
+ let channel2 = Channel {
+ reader: buf2.reader,
+ writer: buf1.writer,
+ };
+ (channel1, channel2)
+ }
+}
+
+pub const DEFAULT_BUF_SIZE: usize = 1 * 1024 * 1024;
+
+lazy_static! {
+ static ref UNIX_SOCKET_OBJS: Mutex>>
+ = Mutex::new(BTreeMap::new());
+}
diff --git a/src/libos/src/prelude.rs b/src/libos/src/prelude.rs
index 74235313..7cddd8ce 100644
--- a/src/libos/src/prelude.rs
+++ b/src/libos/src/prelude.rs
@@ -36,7 +36,7 @@ macro_rules! debug_trace {
macro_rules! errno {
($errno: ident, $msg: expr) => {{
- println!(
+ error!(
"ERROR: {} ({}, line {} in file {})",
$errno,
$msg,
@@ -54,7 +54,7 @@ macro_rules! try_libc {
if ret == -1 {
let errno = unsafe { libc::errno() };
// println will cause libc ocall and overwrite errno
- println!(
+ error!(
"ERROR from libc: {} (line {} in file {})",
errno,
line!(),
diff --git a/src/libos/src/process/exit.rs b/src/libos/src/process/exit.rs
index 621473cc..ab99ba03 100644
--- a/src/libos/src/process/exit.rs
+++ b/src/libos/src/process/exit.rs
@@ -101,7 +101,7 @@ pub fn do_wait4(child_filter: &ChildProcessFilter, exit_status: &mut i32) -> Res
waiter
};
- let child_pid = Waiter::sleep_until_woken_with_result(waiter);
+ let child_pid = waiter.sleep_until_woken_with_result();
let mut current = current_ref.lock().unwrap();
let child_i = {
diff --git a/src/libos/src/process/spawn/init_vm.rs b/src/libos/src/process/spawn/init_vm.rs
index 0a4d0442..246a870a 100644
--- a/src/libos/src/process/spawn/init_vm.rs
+++ b/src/libos/src/process/spawn/init_vm.rs
@@ -4,8 +4,8 @@ use std::ptr;
use xmas_elf::{header, program, sections, ElfFile};
pub const DEFAULT_STACK_SIZE: usize = 1 * 1024 * 1024;
-pub const DEFAULT_HEAP_SIZE: usize = 2 * 1024 * 1024;
-pub const DEFAULT_MMAP_SIZE: usize = 8 * 1024 * 1024;
+pub const DEFAULT_HEAP_SIZE: usize = 10 * 1024 * 1024;
+pub const DEFAULT_MMAP_SIZE: usize = 40 * 1024 * 1024;
pub fn do_init(elf_file: &ElfFile, elf_buf: &[u8]) -> Result {
let mut code_seg = get_code_segment(elf_file)?;
diff --git a/src/libos/src/process/spawn/mod.rs b/src/libos/src/process/spawn/mod.rs
index fee26df7..d2bb6551 100644
--- a/src/libos/src/process/spawn/mod.rs
+++ b/src/libos/src/process/spawn/mod.rs
@@ -113,7 +113,8 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result {
- cloned_file_table.del(fd)?;
+ // ignore error
+ cloned_file_table.del(fd);
}
}
}
diff --git a/src/libos/src/process/wait.rs b/src/libos/src/process/wait.rs
index a753ee9d..23282195 100644
--- a/src/libos/src/process/wait.rs
+++ b/src/libos/src/process/wait.rs
@@ -48,14 +48,14 @@ where
self.inner.lock().unwrap().data
}
- pub fn sleep_until_woken_with_result(waiter: Waiter) -> R {
- while !waiter.inner.lock().unwrap().is_woken {
+ pub fn sleep_until_woken_with_result(self) -> R {
+ while !self.inner.lock().unwrap().is_woken {
unsafe {
- wait_event(waiter.thread);
+ wait_event(self.thread);
}
}
- waiter.inner.lock().unwrap().result.unwrap()
+ self.inner.lock().unwrap().result.unwrap()
}
}
diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs
index 8587a145..42df50de 100644
--- a/src/libos/src/syscall/mod.rs
+++ b/src/libos/src/syscall/mod.rs
@@ -7,7 +7,7 @@
//! 3. Dispatch the syscall to `do_*` (at this file)
//! 4. Do some memory checks then call `mod::do_*` (at each module)
-use fs::{AccessFlags, AccessModes, FcntlCmd, File, FileDesc, FileRef, SocketFile, AT_FDCWD};
+use fs::*;
use misc::{resource_t, rlimit_t, utsname_t};
use prelude::*;
use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp};
@@ -48,10 +48,15 @@ pub extern "C" fn dispatch_syscall(
);
#[cfg(feature = "syscall_timing")]
let time_start = {
- if crate::process::current_pid() == 1 && num == SYS_EXIT {
- print_syscall_timing();
+ static mut LAST_PRINT: usize = 0;
+ let time = crate::time::do_gettimeofday().as_usec();
+ unsafe {
+ if time / 1000000 / 5 > LAST_PRINT {
+ LAST_PRINT = time / 1000000 / 5;
+ print_syscall_timing();
+ }
}
- crate::time::do_gettimeofday().as_usec()
+ time
};
let ret = match num {
@@ -248,6 +253,11 @@ pub extern "C" fn dispatch_syscall(
arg3 as *mut c_void,
arg4 as *mut libc::socklen_t,
),
+ SYS_GETPEERNAME => do_getpeername(
+ arg0 as c_int,
+ arg1 as *mut libc::sockaddr,
+ arg2 as *mut libc::socklen_t,
+ ),
SYS_SENDTO => do_sendto(
arg0 as c_int,
arg1 as *const c_void,
@@ -295,6 +305,9 @@ fn print_syscall_timing() {
}
println!("{:>3}: {:>6} us", i, time);
}
+ for x in unsafe { SYSCALL_TIMING.iter_mut() } {
+ *x = 0;
+ }
}
#[allow(non_camel_case_types)]
@@ -936,8 +949,16 @@ fn do_socket(domain: c_int, socket_type: c_int, protocol: c_int) -> Result> = Arc::new(Box::new(socket));
+ let file_ref: Arc> = match domain {
+// libc::AF_LOCAL => {
+// let unix_socket = UnixSocketFile::new(socket_type, protocol)?;
+// Arc::new(Box::new(unix_socket))
+// }
+ _ => {
+ let socket = SocketFile::new(domain, socket_type, protocol)?;
+ Arc::new(Box::new(socket))
+ }
+ };
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
@@ -958,10 +979,18 @@ fn do_connect(
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)?;
- let socket = file_ref.as_socket()?;
-
- let ret = try_libc!(libc::ocall::connect(socket.fd(), addr, addr_len));
- Ok(ret as isize)
+ if let Ok(socket) = file_ref.as_socket() {
+ let ret = try_libc!(libc::ocall::connect(socket.fd(), addr, addr_len));
+ Ok(ret as isize)
+ } 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();
+ unix_socket.connect(path)?;
+ Ok(0)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_accept4(
@@ -977,13 +1006,26 @@ fn do_accept4(
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)?;
- let socket = file_ref.as_socket()?;
+ if let Ok(socket) = file_ref.as_socket() {
+ let socket = file_ref.as_socket()?;
- let new_socket = socket.accept(addr, addr_len, flags)?;
- let new_file_ref: Arc> = Arc::new(Box::new(new_socket));
- let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
+ let new_socket = socket.accept(addr, addr_len, flags)?;
+ let new_file_ref: Arc> = Arc::new(Box::new(new_socket));
+ let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
- Ok(new_fd as isize)
+ Ok(new_fd as isize)
+ } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
+ let addr = addr as *mut libc::sockaddr_un;
+ check_mut_ptr(addr)?; // TODO: check addr_len
+
+ let new_socket = unix_socket.accept()?;
+ let new_file_ref: Arc> = Arc::new(Box::new(new_socket));
+ let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
+
+ Ok(0)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_shutdown(fd: c_int, how: c_int) -> Result {
@@ -991,10 +1033,12 @@ fn do_shutdown(fd: c_int, how: c_int) -> Result {
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)?;
- let socket = file_ref.as_socket()?;
-
- let ret = try_libc!(libc::ocall::shutdown(socket.fd(), how));
- Ok(ret as isize)
+ if let Ok(socket) = file_ref.as_socket() {
+ let ret = try_libc!(libc::ocall::shutdown(socket.fd(), how));
+ Ok(ret as isize)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_bind(
@@ -1006,10 +1050,19 @@ fn do_bind(
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)?;
- let socket = file_ref.as_socket()?;
-
- let ret = try_libc!(libc::ocall::bind(socket.fd(), addr, addr_len));
- Ok(ret as isize)
+ if let Ok(socket) = file_ref.as_socket() {
+ check_ptr(addr)?; // TODO: check addr_len
+ let ret = try_libc!(libc::ocall::bind(socket.fd(), addr, addr_len));
+ Ok(ret as isize)
+ } 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();
+ unix_socket.bind(path)?;
+ Ok(0)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_listen(fd: c_int, backlog: c_int) -> Result {
@@ -1017,10 +1070,15 @@ fn do_listen(fd: c_int, backlog: c_int) -> Result {
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)?;
- let socket = file_ref.as_socket()?;
-
- let ret = try_libc!(libc::ocall::listen(socket.fd(), backlog));
- Ok(ret as isize)
+ if let Ok(socket) = file_ref.as_socket() {
+ let ret = try_libc!(libc::ocall::listen(socket.fd(), backlog));
+ Ok(ret as isize)
+ } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
+ unix_socket.listen()?;
+ Ok(0)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_setsockopt(
@@ -1037,16 +1095,21 @@ fn do_setsockopt(
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)?;
- let socket = file_ref.as_socket()?;
-
- let ret = try_libc!(libc::ocall::setsockopt(
- socket.fd(),
- level,
- optname,
- optval,
- optlen
- ));
- Ok(ret as isize)
+ if let Ok(socket) = file_ref.as_socket() {
+ let ret = try_libc!(libc::ocall::setsockopt(
+ socket.fd(),
+ level,
+ optname,
+ optval,
+ optlen
+ ));
+ Ok(ret as isize)
+ } else if let Ok(unix_socket) = file_ref.as_unix_socket() {
+ warn!("setsockopt for unix socket is unimplemented");
+ Ok(0)
+ } else {
+ errno!(EBADF, "not a socket")
+ }
}
fn do_getsockopt(
@@ -1075,6 +1138,25 @@ fn do_getsockopt(
Ok(ret as isize)
}
+fn do_getpeername(
+ fd: c_int,
+ addr: *mut libc::sockaddr,
+ addr_len: *mut libc::socklen_t,
+) -> Result {
+ 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)?;
+ let socket = file_ref.as_socket()?;
+
+ let ret = try_libc!(libc::ocall::getpeername(
+ socket.fd(),
+ addr,
+ addr_len
+ ));
+ Ok(ret as isize)
+}
+
fn do_sendto(
fd: c_int,
base: *const c_void,
@@ -1230,18 +1312,6 @@ fn do_epoll_wait(
Ok(count as isize)
}
-pub trait AsSocket {
- fn as_socket(&self) -> Result<&SocketFile, Error>;
-}
-
-impl AsSocket for FileRef {
- fn as_socket(&self) -> Result<&SocketFile, Error> {
- self.as_any()
- .downcast_ref::()
- .ok_or(Error::new(Errno::EBADF, "not a socket"))
- }
-}
-
fn do_uname(name: *mut utsname_t) -> Result {
check_mut_ptr(name)?;
let name = unsafe { &mut *name };
diff --git a/src/libos/src/vm/vm_space_prealloced.c b/src/libos/src/vm/vm_space_prealloced.c
index 62fba785..60f81a87 100644
--- a/src/libos/src/vm/vm_space_prealloced.c
+++ b/src/libos/src/vm/vm_space_prealloced.c
@@ -1,6 +1,6 @@
#include
-#define DATA_SPACE_SIZE (96*1024*1024)
+#define DATA_SPACE_SIZE (128*1024*1024)
static char __prealloced_data_space[DATA_SPACE_SIZE]
__attribute__ ((