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