implement SocketFile. pass socket test
This commit is contained in:
parent
0dda84d7f2
commit
5b90d90643
@ -64,7 +64,7 @@ fn parse_arguments(
|
|||||||
|
|
||||||
// TODO: make sure do_boot can only be called once
|
// TODO: make sure do_boot can only be called once
|
||||||
fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> {
|
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()?;
|
util::mpx_util::mpx_enable()?;
|
||||||
|
|
||||||
let envp = std::vec::Vec::new();
|
let envp = std::vec::Vec::new();
|
||||||
|
@ -39,6 +39,7 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
#[repr(u8)]
|
||||||
pub enum Errno {
|
pub enum Errno {
|
||||||
EUNDEF = 0,
|
EUNDEF = 0,
|
||||||
EPERM = 1,
|
EPERM = 1,
|
||||||
@ -86,6 +87,14 @@ impl Errno {
|
|||||||
pub fn as_retval(&self) -> i32 {
|
pub fn as_retval(&self) -> i32 {
|
||||||
-(*self as i32)
|
-(*self as i32)
|
||||||
}
|
}
|
||||||
|
pub fn from_retval(ret: i32) -> Self {
|
||||||
|
let ret = if ret <= 0 && ret >= -39 {
|
||||||
|
(-ret) as u8
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
unsafe { core::mem::transmute(ret) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Errno {
|
impl fmt::Display for Errno {
|
||||||
|
@ -3,8 +3,9 @@ use std;
|
|||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
pub trait File: Debug + Sync + Send {
|
pub trait File: Debug + Sync + Send + Any {
|
||||||
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
|
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
|
||||||
fn write(&self, buf: &[u8]) -> Result<usize, Error>;
|
fn write(&self, buf: &[u8]) -> Result<usize, Error>;
|
||||||
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error>;
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error>;
|
||||||
@ -17,6 +18,7 @@ pub trait File: Debug + Sync + Send {
|
|||||||
fn sync_all(&self) -> Result<(), Error>;
|
fn sync_all(&self) -> Result<(), Error>;
|
||||||
fn sync_data(&self) -> Result<(), Error>;
|
fn sync_data(&self) -> Result<(), Error>;
|
||||||
fn read_entry(&self) -> Result<String, Error>;
|
fn read_entry(&self) -> Result<String, Error>;
|
||||||
|
fn as_any(&self) -> &Any { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FileRef = Arc<Box<File>>;
|
pub type FileRef = Arc<Box<File>>;
|
||||||
|
@ -9,12 +9,14 @@ use super::*;
|
|||||||
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
|
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
|
||||||
pub use self::file_table::{FileDesc, FileTable};
|
pub use self::file_table::{FileDesc, FileTable};
|
||||||
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
|
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
|
||||||
|
pub use self::socket_file::SocketFile;
|
||||||
use self::inode_file::OpenOptions;
|
use self::inode_file::OpenOptions;
|
||||||
pub use self::pipe::Pipe;
|
pub use self::pipe::Pipe;
|
||||||
|
|
||||||
mod file;
|
mod file;
|
||||||
mod file_table;
|
mod file_table;
|
||||||
mod inode_file;
|
mod inode_file;
|
||||||
|
mod socket_file;
|
||||||
mod pipe;
|
mod pipe;
|
||||||
mod sgx_impl;
|
mod sgx_impl;
|
||||||
|
|
||||||
@ -206,6 +208,7 @@ pub fn do_getdents64(fd: FileDesc, buf: &mut [u8]) -> Result<usize, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_close(fd: FileDesc) -> Result<(), Error> {
|
pub fn do_close(fd: FileDesc) -> Result<(), Error> {
|
||||||
|
info!("close: fd: {}", fd);
|
||||||
let current_ref = process::get_current();
|
let current_ref = process::get_current();
|
||||||
let current_process = current_ref.lock().unwrap();
|
let current_process = current_ref.lock().unwrap();
|
||||||
let file_table_ref = current_process.get_files();
|
let file_table_ref = current_process.get_files();
|
||||||
|
110
src/libos/src/fs/socket_file.rs
Normal file
110
src/libos/src/fs/socket_file.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use super::*;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
/// Native Linux socket
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SocketFile {
|
||||||
|
fd: c_int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SocketFile {
|
||||||
|
pub fn new(domain: c_int, socket_type: c_int, protocol: c_int) -> Result<Self, Error> {
|
||||||
|
let ret = unsafe { libc::ocall::socket(domain, socket_type, protocol) };
|
||||||
|
if ret < 0 {
|
||||||
|
Err(Error::new(Errno::from_retval(ret as i32), ""))
|
||||||
|
} else {
|
||||||
|
Ok(SocketFile { fd: ret })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn accept(
|
||||||
|
&self,
|
||||||
|
addr: *mut libc::sockaddr,
|
||||||
|
addr_len: *mut libc::socklen_t,
|
||||||
|
flags: c_int,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let ret = unsafe { libc::ocall::accept4(self.fd, addr, addr_len, flags) };
|
||||||
|
if ret < 0 {
|
||||||
|
Err(Error::new(Errno::from_retval(ret as i32), ""))
|
||||||
|
} else {
|
||||||
|
Ok(SocketFile { fd: ret })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fd(&self) -> c_int {
|
||||||
|
self.fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for SocketFile {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let ret = unsafe { libc::ocall::close(self.fd) };
|
||||||
|
if ret < 0 {
|
||||||
|
warn!("socket (host fd: {}) close failed", self.fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl File for SocketFile {
|
||||||
|
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
let ret = unsafe { libc::ocall::read(self.fd, buf.as_mut_ptr() as *mut c_void, buf.len()) };
|
||||||
|
if ret < 0 {
|
||||||
|
Err(Error::new(Errno::from_retval(ret as i32), ""))
|
||||||
|
} else {
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
|
||||||
|
let ret = unsafe { libc::ocall::write(self.fd, buf.as_ptr() as *const c_void, buf.len()) };
|
||||||
|
if ret < 0 {
|
||||||
|
Err(Error::new(Errno::from_retval(ret as i32), ""))
|
||||||
|
} else {
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek(&self, pos: SeekFrom) -> Result<off_t, Error> {
|
||||||
|
Err(Error::new(Errno::ESPIPE, "Socket does not support seek"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> Result<Metadata, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
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<String, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
@ -7,8 +7,7 @@
|
|||||||
//! 3. Dispatch the syscall to `do_*` (at this file)
|
//! 3. Dispatch the syscall to `do_*` (at this file)
|
||||||
//! 4. Do some memory checks then call `mod::do_*` (at each module)
|
//! 4. Do some memory checks then call `mod::do_*` (at each module)
|
||||||
|
|
||||||
use fs::File;
|
use fs::{File, SocketFile, off_t, FileDesc, FileRef};
|
||||||
use fs::{off_t, FileDesc};
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use process::{ChildProcessFilter, FileAction, pid_t, CloneFlags, FutexFlags, FutexOp};
|
use process::{ChildProcessFilter, FileAction, pid_t, CloneFlags, FutexFlags, FutexOp};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
@ -21,6 +20,7 @@ use {fs, process, std, vm};
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use self::consts::*;
|
use self::consts::*;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
// Use the internal syscall wrappers from sgx_tstd
|
// Use the internal syscall wrappers from sgx_tstd
|
||||||
//use std::libc_fs as fs;
|
//use std::libc_fs as fs;
|
||||||
@ -177,6 +177,22 @@ pub extern "C" fn dispatch_syscall(
|
|||||||
arg3 as *mut c_void,
|
arg3 as *mut c_void,
|
||||||
arg4 as *mut libc::socklen_t,
|
arg4 as *mut libc::socklen_t,
|
||||||
),
|
),
|
||||||
|
SYS_SENDTO => do_sendto(
|
||||||
|
arg0 as c_int,
|
||||||
|
arg1 as *const c_void,
|
||||||
|
arg2 as size_t,
|
||||||
|
arg3 as c_int,
|
||||||
|
arg4 as *const libc::sockaddr,
|
||||||
|
arg5 as libc::socklen_t,
|
||||||
|
),
|
||||||
|
SYS_RECVFROM => do_recvfrom(
|
||||||
|
arg0 as c_int,
|
||||||
|
arg1 as *mut c_void,
|
||||||
|
arg2 as size_t,
|
||||||
|
arg3 as c_int,
|
||||||
|
arg4 as *mut libc::sockaddr,
|
||||||
|
arg5 as *mut libc::socklen_t,
|
||||||
|
),
|
||||||
|
|
||||||
_ => do_unknown(num, arg0, arg1, arg2, arg3, arg4, arg5),
|
_ => do_unknown(num, arg0, arg1, arg2, arg3, arg4, arg5),
|
||||||
};
|
};
|
||||||
@ -654,6 +670,7 @@ fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<isize, Error> {
|
|||||||
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;
|
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;
|
||||||
|
|
||||||
fn do_exit(status: i32) -> ! {
|
fn do_exit(status: i32) -> ! {
|
||||||
|
info!("exit: {}", status);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn do_exit_task() -> !;
|
fn do_exit_task() -> !;
|
||||||
}
|
}
|
||||||
@ -749,8 +766,15 @@ fn do_socket(domain: c_int, socket_type: c_int, protocol: c_int) -> Result<isize
|
|||||||
"socket: domain: {}, socket_type: {}, protocol: {}",
|
"socket: domain: {}, socket_type: {}, protocol: {}",
|
||||||
domain, socket_type, protocol
|
domain, socket_type, protocol
|
||||||
);
|
);
|
||||||
let ret = unsafe { libc::ocall::socket(domain, socket_type, protocol) };
|
|
||||||
Ok(ret as isize)
|
let socket = SocketFile::new(domain, socket_type, protocol)?;
|
||||||
|
let file_ref: Arc<Box<File>> = Arc::new(Box::new(socket));
|
||||||
|
|
||||||
|
let current_ref = process::get_current();
|
||||||
|
let mut proc = current_ref.lock().unwrap();
|
||||||
|
|
||||||
|
let fd = proc.get_files().lock().unwrap().put(file_ref, false);
|
||||||
|
Ok(fd as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_connect(
|
fn do_connect(
|
||||||
@ -762,7 +786,12 @@ fn do_connect(
|
|||||||
"connect: fd: {}, addr: {:?}, addr_len: {}",
|
"connect: fd: {}, addr: {:?}, addr_len: {}",
|
||||||
fd, addr, addr_len
|
fd, addr, addr_len
|
||||||
);
|
);
|
||||||
let ret = unsafe { libc::ocall::connect(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 = unsafe { libc::ocall::connect(socket.fd(), addr, addr_len) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,13 +805,26 @@ fn do_accept(
|
|||||||
"accept: fd: {}, addr: {:?}, addr_len: {:?}, flags: {:#x}",
|
"accept: fd: {}, addr: {:?}, addr_len: {:?}, flags: {:#x}",
|
||||||
fd, addr, addr_len, flags
|
fd, addr, addr_len, flags
|
||||||
);
|
);
|
||||||
let ret = unsafe { libc::ocall::accept4(fd, addr, addr_len, flags) };
|
let current_ref = process::get_current();
|
||||||
Ok(ret as isize)
|
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 new_socket = socket.accept(addr, addr_len, flags)?;
|
||||||
|
let new_file_ref: Arc<Box<File>> = Arc::new(Box::new(new_socket));
|
||||||
|
let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
|
||||||
|
|
||||||
|
Ok(new_fd as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_shutdown(fd: c_int, how: c_int) -> Result<isize, Error> {
|
fn do_shutdown(fd: c_int, how: c_int) -> Result<isize, Error> {
|
||||||
info!("shutdown: fd: {}, how: {}", fd, how);
|
info!("shutdown: fd: {}, how: {}", fd, how);
|
||||||
let ret = unsafe { libc::ocall::shutdown(fd, how) };
|
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 = unsafe { libc::ocall::shutdown(socket.fd(), how) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,13 +834,23 @@ fn do_bind(
|
|||||||
addr_len: libc::socklen_t,
|
addr_len: libc::socklen_t,
|
||||||
) -> Result<isize, Error> {
|
) -> Result<isize, Error> {
|
||||||
info!("bind: fd: {}, addr: {:?}, addr_len: {}", fd, addr, addr_len);
|
info!("bind: fd: {}, addr: {:?}, addr_len: {}", fd, addr, addr_len);
|
||||||
let ret = unsafe { libc::ocall::bind(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 = unsafe { libc::ocall::bind(socket.fd(), addr, addr_len) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_listen(fd: c_int, backlog: c_int) -> Result<isize, Error> {
|
fn do_listen(fd: c_int, backlog: c_int) -> Result<isize, Error> {
|
||||||
info!("listen: fd: {}, backlog: {}", fd, backlog);
|
info!("listen: fd: {}, backlog: {}", fd, backlog);
|
||||||
let ret = unsafe { libc::ocall::listen(fd, backlog) };
|
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 = unsafe { libc::ocall::listen(socket.fd(), backlog) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,7 +865,12 @@ fn do_setsockopt(
|
|||||||
"setsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
|
"setsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
|
||||||
fd, level, optname, optval, optlen
|
fd, level, optname, optval, optlen
|
||||||
);
|
);
|
||||||
let ret = unsafe { libc::ocall::setsockopt(fd, level, optname, optval, optlen) };
|
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 = unsafe { libc::ocall::setsockopt(socket.fd(), level, optname, optval, optlen) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,6 +885,65 @@ fn do_getsockopt(
|
|||||||
"getsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
|
"getsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
|
||||||
fd, level, optname, optval, optlen
|
fd, level, optname, optval, optlen
|
||||||
);
|
);
|
||||||
let ret = unsafe { libc::ocall::getsockopt(fd, level, optname, optval, optlen) };
|
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 = unsafe { libc::ocall::getsockopt(socket.fd(), level, optname, optval, optlen) };
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn do_sendto(
|
||||||
|
fd: c_int,
|
||||||
|
base: *const c_void,
|
||||||
|
len: size_t,
|
||||||
|
flags: c_int,
|
||||||
|
addr: *const libc::sockaddr,
|
||||||
|
addr_len: libc::socklen_t,
|
||||||
|
) -> Result<isize, Error> {
|
||||||
|
info!(
|
||||||
|
"sendto: fd: {}, base: {:?}, len: {}, addr: {:?}, addr_len: {}",
|
||||||
|
fd, base, len, 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 = unsafe { libc::ocall::sendto(socket.fd(), base, len, flags, addr, addr_len) };
|
||||||
|
Ok(ret as isize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_recvfrom(
|
||||||
|
fd: c_int,
|
||||||
|
base: *mut c_void,
|
||||||
|
len: size_t,
|
||||||
|
flags: c_int,
|
||||||
|
addr: *mut libc::sockaddr,
|
||||||
|
addr_len: *mut libc::socklen_t,
|
||||||
|
) -> Result<isize, Error> {
|
||||||
|
info!(
|
||||||
|
"recvfrom: fd: {}, base: {:?}, len: {}, flags: {}, addr: {:?}, addr_len: {:?}",
|
||||||
|
fd, base, len, flags, 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 = unsafe { libc::ocall::recvfrom(socket.fd(), base, len, flags, addr, addr_len) };
|
||||||
|
Ok(ret as isize)
|
||||||
|
}
|
||||||
|
|
||||||
|
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::<SocketFile>()
|
||||||
|
.ok_or(Error::new(Errno::EBADF, "not a socket"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -23,9 +23,10 @@ impl Log for SimpleLogger {
|
|||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
let color = Color::from(record.level());
|
let color = Color::from(record.level());
|
||||||
println!(
|
println!(
|
||||||
"\u{1B}[{}m[{:>5}] {}\u{1B}[0m",
|
"\u{1B}[{}m[{:>5}][{}] {}\u{1B}[0m",
|
||||||
color as u8,
|
color as u8,
|
||||||
record.level(),
|
record.level(),
|
||||||
|
crate::process::do_getpid(),
|
||||||
record.args()
|
record.args()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ PROJECT_DIR := $(realpath $(CUR_DIR)/../)
|
|||||||
# Dependencies: need to be compiled but not to run by any Makefile target
|
# Dependencies: need to be compiled but not to run by any Makefile target
|
||||||
TEST_DEPS := dev_null
|
TEST_DEPS := dev_null
|
||||||
# Tests: need to be compiled and run by test-% target
|
# Tests: need to be compiled and run by test-% target
|
||||||
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread clone server
|
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread client server
|
||||||
# Benchmarks: need to be compiled and run by bench-% target
|
# Benchmarks: need to be compiled and run by bench-% target
|
||||||
BENCHES := spawn_and_exit_latency pipe_throughput
|
BENCHES := spawn_and_exit_latency pipe_throughput
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
printf("usage: ./client <ipaddress>\n");
|
printf("usage: ./client <ipaddress>\n");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user