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,
|
||||
ENOSYS = 38,
|
||||
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 {
|
||||
pub fn as_retval(&self) -> 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) }
|
||||
pub fn from_errno(mut errno: i32) -> Self {
|
||||
if errno < 0 || errno > 133 {
|
||||
errno = 0;
|
||||
}
|
||||
unsafe { core::mem::transmute(errno as u8) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,7 @@ pub fn do_select(
|
||||
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) };
|
||||
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::poll(polls.as_mut_ptr(), polls.len() as u64, timeout));
|
||||
|
||||
// convert fd back and write fdset
|
||||
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()?;
|
||||
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 ?
|
||||
|
||||
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> {
|
||||
@ -211,10 +202,7 @@ struct EpollFileInner {
|
||||
impl EpollFileInner {
|
||||
/// Create a new Linux epoll file descriptor
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
let ret = unsafe { libc::ocall::epoll_create1(0) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::epoll_create1(0));
|
||||
Ok(EpollFileInner { epoll_fd: ret })
|
||||
}
|
||||
|
||||
@ -225,10 +213,7 @@ impl EpollFileInner {
|
||||
event: *const libc::epoll_event,
|
||||
) -> Result<(), Error> {
|
||||
let ret =
|
||||
unsafe { 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() }), "");
|
||||
}
|
||||
try_libc!(libc::ocall::epoll_ctl(self.epoll_fd, op, host_fd as c_int, event as *mut _));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -239,17 +224,14 @@ impl EpollFileInner {
|
||||
events: &mut [libc::epoll_event],
|
||||
timeout: c_int,
|
||||
) -> Result<usize, Error> {
|
||||
let ret = unsafe {
|
||||
let ret = try_libc!(
|
||||
libc::ocall::epoll_wait(
|
||||
self.epoll_fd,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
timeout,
|
||||
)
|
||||
};
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
);
|
||||
Ok(ret as usize)
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,8 @@ pub struct SocketFile {
|
||||
|
||||
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 {
|
||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
||||
} else {
|
||||
Ok(SocketFile { fd: ret })
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::socket(domain, socket_type, protocol));
|
||||
Ok(SocketFile { fd: ret })
|
||||
}
|
||||
|
||||
pub fn accept(
|
||||
@ -23,12 +19,8 @@ impl SocketFile {
|
||||
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 {
|
||||
errno!(Errno::from_retval(unsafe { libc::errno() }), "")
|
||||
} else {
|
||||
Ok(SocketFile { fd: ret })
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::accept4(self.fd, addr, addr_len, flags));
|
||||
Ok(SocketFile { fd: ret })
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> c_int {
|
||||
@ -40,28 +32,21 @@ 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);
|
||||
let errno = unsafe { libc::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 = unsafe { 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)
|
||||
}
|
||||
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 = unsafe { 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)
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::write(self.fd, buf.as_ptr() as *const c_void, buf.len()));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
|
@ -35,7 +35,7 @@ macro_rules! debug_trace {
|
||||
}
|
||||
|
||||
macro_rules! errno {
|
||||
($errno: expr, $msg: expr) => {{
|
||||
($errno: ident, $msg: expr) => {{
|
||||
println!(
|
||||
"ERROR: {} ({}, line {} in file {})",
|
||||
$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 {
|
||||
(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 socket = file_ref.as_socket()?;
|
||||
|
||||
let ret = unsafe { libc::ocall::connect(socket.fd(), addr, addr_len) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::connect(socket.fd(), addr, addr_len));
|
||||
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 socket = file_ref.as_socket()?;
|
||||
|
||||
let ret = unsafe { libc::ocall::shutdown(socket.fd(), how) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::shutdown(socket.fd(), how));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
@ -995,10 +989,7 @@ fn do_bind(
|
||||
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) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::bind(socket.fd(), addr, addr_len));
|
||||
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 socket = file_ref.as_socket()?;
|
||||
|
||||
let ret = unsafe { libc::ocall::listen(socket.fd(), backlog) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::listen(socket.fd(), backlog));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
@ -1032,10 +1020,13 @@ fn do_setsockopt(
|
||||
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) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::setsockopt(
|
||||
socket.fd(),
|
||||
level,
|
||||
optname,
|
||||
optval,
|
||||
optlen
|
||||
));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
@ -1055,10 +1046,13 @@ fn do_getsockopt(
|
||||
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) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::getsockopt(
|
||||
socket.fd(),
|
||||
level,
|
||||
optname,
|
||||
optval,
|
||||
optlen
|
||||
));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
@ -1079,10 +1073,14 @@ fn do_sendto(
|
||||
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) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::sendto(
|
||||
socket.fd(),
|
||||
base,
|
||||
len,
|
||||
flags,
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
@ -1103,10 +1101,14 @@ fn do_recvfrom(
|
||||
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) };
|
||||
if ret < 0 {
|
||||
return errno!(Errno::from_retval(unsafe { libc::errno() }), "");
|
||||
}
|
||||
let ret = try_libc!(libc::ocall::recvfrom(
|
||||
socket.fd(),
|
||||
base,
|
||||
len,
|
||||
flags,
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
Ok(ret as isize)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user