fix errno = 0 and introduce macro 'try_libc'
This commit is contained in:
parent
141094e95e
commit
1326924dbb
@ -81,19 +81,111 @@ pub enum Errno {
|
|||||||
ENOLCK = 37,
|
ENOLCK = 37,
|
||||||
ENOSYS = 38,
|
ENOSYS = 38,
|
||||||
ENOTEMPTY = 39,
|
ENOTEMPTY = 39,
|
||||||
|
ELOOP = 40,
|
||||||
|
EWOULDBLOCK = 41,
|
||||||
|
ENOMSG = 42,
|
||||||
|
EIDRM = 43,
|
||||||
|
ECHRNG = 44,
|
||||||
|
EL2NSYNC = 45,
|
||||||
|
EL3HLT = 46,
|
||||||
|
EL3RST = 47,
|
||||||
|
ELNRNG = 48,
|
||||||
|
EUNATCH = 49,
|
||||||
|
ENOCSI = 50,
|
||||||
|
EL2HLT = 51,
|
||||||
|
EBADE = 52,
|
||||||
|
EBADR = 53,
|
||||||
|
EXFULL = 54,
|
||||||
|
ENOANO = 55,
|
||||||
|
EBADRQC = 56,
|
||||||
|
EBADSLT = 57,
|
||||||
|
EDEADLOCK = 58,
|
||||||
|
EBFONT = 59,
|
||||||
|
ENOSTR = 60,
|
||||||
|
ENODATA = 61,
|
||||||
|
ETIME = 62,
|
||||||
|
ENOSR = 63,
|
||||||
|
ENONET = 64,
|
||||||
|
ENOPKG = 65,
|
||||||
|
EREMOTE = 66,
|
||||||
|
ENOLINK = 67,
|
||||||
|
EADV = 68,
|
||||||
|
ESRMNT = 69,
|
||||||
|
ECOMM = 70,
|
||||||
|
EPROTO = 71,
|
||||||
|
EMULTIHOP = 72,
|
||||||
|
EDOTDOT = 73,
|
||||||
|
EBADMSG = 74,
|
||||||
|
EOVERFLOW = 75,
|
||||||
|
ENOTUNIQ = 76,
|
||||||
|
EBADFD = 77,
|
||||||
|
EREMCHG = 78,
|
||||||
|
ELIBACC = 79,
|
||||||
|
ELIBBAD = 80,
|
||||||
|
ELIBSCN = 81,
|
||||||
|
ELIBMAX = 82,
|
||||||
|
ELIBEXEC = 83,
|
||||||
|
EILSEQ = 84,
|
||||||
|
ERESTART = 85,
|
||||||
|
ESTRPIPE = 86,
|
||||||
|
EUSERS = 87,
|
||||||
|
ENOTSOCK = 88,
|
||||||
|
EDESTADDRREQ = 89,
|
||||||
|
EMSGSIZE = 90,
|
||||||
|
EPROTOTYPE = 91,
|
||||||
|
ENOPROTOOPT = 92,
|
||||||
|
EPROTONOSUPPORT = 93,
|
||||||
|
ESOCKTNOSUPPORT = 94,
|
||||||
|
EOPNOTSUPP = 95,
|
||||||
|
EPFNOSUPPORT = 96,
|
||||||
|
EAFNOSUPPORT = 97,
|
||||||
|
EADDRINUSE = 98,
|
||||||
|
EADDRNOTAVAIL = 99,
|
||||||
|
ENETDOWN = 100,
|
||||||
|
ENETUNREACH = 101,
|
||||||
|
ENETRESET = 102,
|
||||||
|
ECONNABORTED = 103,
|
||||||
|
ECONNRESET = 104,
|
||||||
|
ENOBUFS = 105,
|
||||||
|
EISCONN = 106,
|
||||||
|
ENOTCONN = 107,
|
||||||
|
ESHUTDOWN = 108,
|
||||||
|
ETOOMANYREFS = 109,
|
||||||
|
ETIMEDOUT = 110,
|
||||||
|
ECONNREFUSED = 111,
|
||||||
|
EHOSTDOWN = 112,
|
||||||
|
EHOSTUNREACH = 113,
|
||||||
|
EALREADY = 114,
|
||||||
|
EINPROGRESS = 115,
|
||||||
|
ESTALE = 116,
|
||||||
|
EUCLEAN = 117,
|
||||||
|
ENOTNAM = 118,
|
||||||
|
ENAVAIL = 119,
|
||||||
|
EISNAM = 120,
|
||||||
|
EREMOTEIO = 121,
|
||||||
|
EDQUOT = 122,
|
||||||
|
ENOMEDIUM = 123,
|
||||||
|
EMEDIUMTYPE = 124,
|
||||||
|
ECANCELED = 125,
|
||||||
|
ENOKEY = 126,
|
||||||
|
EKEYEXPIRED = 127,
|
||||||
|
EKEYREVOKED = 128,
|
||||||
|
EKEYREJECTED = 129,
|
||||||
|
EOWNERDEAD = 130,
|
||||||
|
ENOTRECOVERABLE = 131,
|
||||||
|
ERFKILL = 132,
|
||||||
|
EHWPOISON = 133,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Errno {
|
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 {
|
pub fn from_errno(mut errno: i32) -> Self {
|
||||||
let ret = if ret <= 0 && ret >= -39 {
|
if errno < 0 || errno > 133 {
|
||||||
(-ret) as u8
|
errno = 0;
|
||||||
} else {
|
}
|
||||||
0
|
unsafe { core::mem::transmute(errno as u8) }
|
||||||
};
|
|
||||||
unsafe { core::mem::transmute(ret) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +57,7 @@ pub fn do_select(
|
|||||||
Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32,
|
Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret = unsafe { 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));
|
||||||
|
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert fd back and write fdset
|
// convert fd back and write fdset
|
||||||
readfds.clear();
|
readfds.clear();
|
||||||
@ -96,14 +92,9 @@ pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize, Erro
|
|||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
poll.fd = socket.fd();
|
poll.fd = socket.fd();
|
||||||
}
|
}
|
||||||
let ret = unsafe { 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 ?
|
// recover fd ?
|
||||||
|
|
||||||
if ret < 0 {
|
|
||||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
|
||||||
} else {
|
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_epoll_create1(flags: c_int) -> Result<FileDesc, Error> {
|
pub fn do_epoll_create1(flags: c_int) -> Result<FileDesc, Error> {
|
||||||
@ -211,10 +202,7 @@ struct EpollFileInner {
|
|||||||
impl EpollFileInner {
|
impl EpollFileInner {
|
||||||
/// Create a new Linux epoll file descriptor
|
/// Create a new Linux epoll file descriptor
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
let ret = unsafe { libc::ocall::epoll_create1(0) };
|
let ret = try_libc!(libc::ocall::epoll_create1(0));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(EpollFileInner { epoll_fd: ret })
|
Ok(EpollFileInner { epoll_fd: ret })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,10 +213,7 @@ impl EpollFileInner {
|
|||||||
event: *const libc::epoll_event,
|
event: *const libc::epoll_event,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let ret =
|
let ret =
|
||||||
unsafe { libc::ocall::epoll_ctl(self.epoll_fd, op, host_fd as c_int, event as *mut _) };
|
try_libc!(libc::ocall::epoll_ctl(self.epoll_fd, op, host_fd as c_int, event as *mut _));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,17 +224,14 @@ impl EpollFileInner {
|
|||||||
events: &mut [libc::epoll_event],
|
events: &mut [libc::epoll_event],
|
||||||
timeout: c_int,
|
timeout: c_int,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
let ret = unsafe {
|
let ret = try_libc!(
|
||||||
libc::ocall::epoll_wait(
|
libc::ocall::epoll_wait(
|
||||||
self.epoll_fd,
|
self.epoll_fd,
|
||||||
events.as_mut_ptr(),
|
events.as_mut_ptr(),
|
||||||
events.len() as c_int,
|
events.len() as c_int,
|
||||||
timeout,
|
timeout,
|
||||||
)
|
)
|
||||||
};
|
);
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,9 @@ pub struct SocketFile {
|
|||||||
|
|
||||||
impl SocketFile {
|
impl SocketFile {
|
||||||
pub fn new(domain: c_int, socket_type: c_int, protocol: c_int) -> Result<Self, Error> {
|
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) };
|
let ret = try_libc!(libc::ocall::socket(domain, socket_type, protocol));
|
||||||
if ret < 0 {
|
|
||||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
|
||||||
} else {
|
|
||||||
Ok(SocketFile { fd: ret })
|
Ok(SocketFile { fd: ret })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn accept(
|
pub fn accept(
|
||||||
&self,
|
&self,
|
||||||
@ -23,13 +19,9 @@ impl SocketFile {
|
|||||||
addr_len: *mut libc::socklen_t,
|
addr_len: *mut libc::socklen_t,
|
||||||
flags: c_int,
|
flags: c_int,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let ret = unsafe { libc::ocall::accept4(self.fd, addr, addr_len, flags) };
|
let ret = try_libc!(libc::ocall::accept4(self.fd, addr, addr_len, flags));
|
||||||
if ret < 0 {
|
|
||||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
|
||||||
} else {
|
|
||||||
Ok(SocketFile { fd: ret })
|
Ok(SocketFile { fd: ret })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fd(&self) -> c_int {
|
pub fn fd(&self) -> c_int {
|
||||||
self.fd
|
self.fd
|
||||||
@ -40,29 +32,22 @@ impl Drop for SocketFile {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let ret = unsafe { libc::ocall::close(self.fd) };
|
let ret = unsafe { libc::ocall::close(self.fd) };
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
warn!("socket (host fd: {}) close failed", self.fd);
|
let errno = unsafe { libc::errno() };
|
||||||
|
warn!("socket (host fd: {}) close failed: errno = {}", self.fd, errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File for SocketFile {
|
impl File for SocketFile {
|
||||||
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
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()) };
|
let ret = try_libc!(libc::ocall::read(self.fd, buf.as_mut_ptr() as *mut c_void, buf.len()));
|
||||||
if ret < 0 {
|
|
||||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
|
||||||
} else {
|
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
|
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()) };
|
let ret = try_libc!(libc::ocall::write(self.fd, buf.as_ptr() as *const c_void, buf.len()));
|
||||||
if ret < 0 {
|
|
||||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
|
||||||
} else {
|
|
||||||
Ok(ret as usize)
|
Ok(ret as usize)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
|
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
self.read(buf)
|
self.read(buf)
|
||||||
|
@ -35,7 +35,7 @@ macro_rules! debug_trace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! errno {
|
macro_rules! errno {
|
||||||
($errno: expr, $msg: expr) => {{
|
($errno: ident, $msg: expr) => {{
|
||||||
println!(
|
println!(
|
||||||
"ERROR: {} ({}, line {} in file {})",
|
"ERROR: {} ({}, line {} in file {})",
|
||||||
$errno,
|
$errno,
|
||||||
@ -47,6 +47,25 @@ macro_rules! errno {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return Err(errno) if libc return -1
|
||||||
|
macro_rules! try_libc {
|
||||||
|
($ret: expr) => {{
|
||||||
|
let ret = unsafe { $ret };
|
||||||
|
if ret == -1 {
|
||||||
|
let errno = unsafe { libc::errno() };
|
||||||
|
// println will cause libc ocall and overwrite errno
|
||||||
|
println!(
|
||||||
|
"ERROR from libc: {} (line {} in file {})",
|
||||||
|
errno,
|
||||||
|
line!(),
|
||||||
|
file!()
|
||||||
|
);
|
||||||
|
return Err(Error::new(Errno::from_errno(errno), "libc error"));
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn align_up(addr: usize, align: usize) -> usize {
|
pub fn align_up(addr: usize, align: usize) -> usize {
|
||||||
(addr + (align - 1)) / align * align
|
(addr + (align - 1)) / align * align
|
||||||
}
|
}
|
||||||
|
@ -941,10 +941,7 @@ fn do_connect(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::connect(socket.fd(), addr, addr_len) };
|
let ret = try_libc!(libc::ocall::connect(socket.fd(), addr, addr_len));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,10 +974,7 @@ fn do_shutdown(fd: c_int, how: c_int) -> Result<isize, Error> {
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::shutdown(socket.fd(), how) };
|
let ret = try_libc!(libc::ocall::shutdown(socket.fd(), how));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,10 +989,7 @@ fn do_bind(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::bind(socket.fd(), addr, addr_len) };
|
let ret = try_libc!(libc::ocall::bind(socket.fd(), addr, addr_len));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,10 +1000,7 @@ fn do_listen(fd: c_int, backlog: c_int) -> Result<isize, Error> {
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::listen(socket.fd(), backlog) };
|
let ret = try_libc!(libc::ocall::listen(socket.fd(), backlog));
|
||||||
if ret < 0 {
|
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
|
||||||
}
|
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,10 +1020,13 @@ fn do_setsockopt(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::setsockopt(socket.fd(), level, optname, optval, optlen) };
|
let ret = try_libc!(libc::ocall::setsockopt(
|
||||||
if ret < 0 {
|
socket.fd(),
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
level,
|
||||||
}
|
optname,
|
||||||
|
optval,
|
||||||
|
optlen
|
||||||
|
));
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1055,10 +1046,13 @@ fn do_getsockopt(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::getsockopt(socket.fd(), level, optname, optval, optlen) };
|
let ret = try_libc!(libc::ocall::getsockopt(
|
||||||
if ret < 0 {
|
socket.fd(),
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
level,
|
||||||
}
|
optname,
|
||||||
|
optval,
|
||||||
|
optlen
|
||||||
|
));
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,10 +1073,14 @@ fn do_sendto(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::sendto(socket.fd(), base, len, flags, addr, addr_len) };
|
let ret = try_libc!(libc::ocall::sendto(
|
||||||
if ret < 0 {
|
socket.fd(),
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
base,
|
||||||
}
|
len,
|
||||||
|
flags,
|
||||||
|
addr,
|
||||||
|
addr_len
|
||||||
|
));
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,10 +1101,14 @@ fn do_recvfrom(
|
|||||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
let socket = file_ref.as_socket()?;
|
let socket = file_ref.as_socket()?;
|
||||||
|
|
||||||
let ret = unsafe { libc::ocall::recvfrom(socket.fd(), base, len, flags, addr, addr_len) };
|
let ret = try_libc!(libc::ocall::recvfrom(
|
||||||
if ret < 0 {
|
socket.fd(),
|
||||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
base,
|
||||||
}
|
len,
|
||||||
|
flags,
|
||||||
|
addr,
|
||||||
|
addr_len
|
||||||
|
));
|
||||||
Ok(ret as isize)
|
Ok(ret as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user