use crate::ffi::CString;
use crate::io::ErrorKind;
use sgx_oc::ocall::{self, OCallResult};
use sgx_oc as libc;
use sgx_trts::error::abort;
pub use self::rand::hashmap_random_keys;
pub mod args;
#[cfg(feature = "backtrace")]
pub mod backtrace;
pub mod cmath;
pub mod common;
pub mod env;
pub mod fd;
pub mod fs;
pub mod futex;
pub mod io;
pub mod kernel_copy;
pub mod memchr;
#[cfg(feature = "net")]
pub mod net;
pub mod os;
pub mod os_str;
pub mod path;
#[cfg(feature = "pipe")]
pub mod pipe;
#[cfg(feature = "unsupported_process")]
#[path = "unsupported/process.rs"]
pub mod process;
pub mod rand;
#[cfg(feature = "stdio")]
pub mod stdio;
#[cfg(feature = "thread")]
pub mod thread;
#[cfg(feature = "thread")]
pub mod thread_local_dtor;
#[cfg(feature = "thread")]
pub mod thread_local_key;
pub mod time;
pub mod unsupported;
mod personality;
pub unsafe fn init(env: Vec<CString>, args: Vec<CString>) {
let _ = ocall::initenv(Some(env));
let _ = ocall::initargs(Some(args));
}
pub unsafe fn cleanup() {}
#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> ErrorKind {
use ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => FilesystemQuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
libc::ENOTEMPTY => DirectoryNotEmpty,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EACCES | libc::EPERM => PermissionDenied,
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
pub type RawOsError = i32;
#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
impl_is_minus_one! { i8 i16 i32 i64 isize }
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) }
}
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
where
T: IsMinusOne,
F: FnMut() -> T,
{
loop {
match cvt(f()) {
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
other => return other,
}
}
}
pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> {
if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) }
}
pub fn cvt_ocall<T>(result: OCallResult<T>) -> crate::io::Result<T> {
result.map_err(|e| e.into())
}
pub fn cvt_ocall_r<T, F>(mut f: F) -> crate::io::Result<T>
where
F: FnMut() -> OCallResult<T>,
{
loop {
match cvt_ocall(f()) {
Err(ref e) if e.is_interrupted() => {}
other => return other,
}
}
}
pub fn abort_internal() -> ! {
abort()
}
pub unsafe fn strlen(mut s: *const i8) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
n
}