You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by zf...@apache.org on 2021/04/15 06:40:36 UTC
[incubator-teaclave-sgx-sdk] 01/01: Change sgx_libc interface.
This is an automated email from the ASF dual-hosted git repository.
zfc pushed a commit to branch sec-liboc
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-sgx-sdk.git
commit a1728f2d910e4da342940e834d2c43130d4a68ff
Author: Zhaofeng Chen <zf...@apache.com>
AuthorDate: Wed Apr 14 23:38:51 2021 -0700
Change sgx_libc interface.
Fix hw_test test_file.
Update epoll_wait
Update patch for crates taking sgx_oc as dependency
Comment workflow matrix for xargo.
Patch dependency for sim-example action.
Clean up hello-rust.
Bring back Xargo actions.
---
.github/workflows/dep_patch.txt | 9 +
.github/workflows/patch.txt | 2 +-
.github/workflows/sgx-world.yml | 6 +-
.github/workflows/sim-example.yml | 5 +
edl/sgx_env.edl | 12 +-
edl/sgx_fd.edl | 4 -
edl/sgx_file.edl | 4 +-
edl/sgx_net.edl | 7 +-
edl/sgx_pipe.edl | 1 -
edl/sgx_socket.edl | 7 -
samplecode/hello-rust/enclave/Enclave.edl | 3 +
samplecode/http_req/Makefile | 4 +-
samplecode/unit-test/enclave/Cargo.toml | 2 +-
samplecode/unit-test/enclave/Enclave.edl | 2 +
samplecode/unit-test/enclave/src/lib.rs | 8 +-
samplecode/unit-test/enclave/src/test_env.rs | 7 +-
samplecode/unit-test/enclave/src/test_file.rs | 3 +-
samplecode/unit-test/enclave/src/test_net.rs | 77 +
samplecode/unit-test/enclave/src/test_path.rs | 70 +
samplecode/unit-test/enclave/src/test_rts.rs | 150 +-
samplecode/unit-test/enclave/src/test_signal.rs | 2 +-
sgx_edl/edl/sgx_env.edl | 12 +-
sgx_edl/edl/sgx_fd.edl | 4 -
sgx_edl/edl/sgx_file.edl | 4 +-
sgx_edl/edl/sgx_net.edl | 7 +-
sgx_edl/edl/sgx_pipe.edl | 1 -
sgx_edl/edl/sgx_socket.edl | 7 -
sgx_edl/edl/sgx_sys.edl | 1 -
{sgx_trts => sgx_libc}/src/ascii.rs | 0
{sgx_trts => sgx_libc}/src/c_str.rs | 5 +-
sgx_libc/src/lib.rs | 9 +
sgx_libc/src/linux/mod.rs | 1 +
sgx_libc/src/linux/x86_64/mod.rs | 571 +--
sgx_libc/src/linux/x86_64/ocall.rs | 4498 ++++++++++-------------
sgx_libc/src/macros.rs | 43 +
{sgx_trts => sgx_libc}/src/memchr.rs | 52 +-
sgx_trts/src/lib.rs | 8 +-
sgx_tstd/src/io/error.rs | 47 +-
sgx_tstd/src/net/addr.rs | 82 +-
sgx_tstd/src/sys/ext/net.rs | 125 +-
sgx_tstd/src/sys/fd.rs | 99 +-
sgx_tstd/src/sys/fs.rs | 231 +-
sgx_tstd/src/sys/mod.rs | 62 +-
sgx_tstd/src/sys/net.rs | 126 +-
sgx_tstd/src/sys/os.rs | 184 +-
sgx_tstd/src/sys/pipe.rs | 13 +-
sgx_tstd/src/sys/thread.rs | 7 +-
sgx_tstd/src/sys/time.rs | 76 +-
sgx_tstd/src/sys_common/net.rs | 245 +-
sgx_urts/src/env.rs | 52 +-
sgx_urts/src/fd.rs | 84 +-
sgx_urts/src/file.rs | 25 +-
sgx_urts/src/net.rs | 47 +-
sgx_urts/src/socket.rs | 22 -
sgx_ustdc/net.c | 5 -
sgx_ustdc/socket.c | 13 -
56 files changed, 3409 insertions(+), 3744 deletions(-)
diff --git a/.github/workflows/dep_patch.txt b/.github/workflows/dep_patch.txt
new file mode 100644
index 0000000..4e1d426
--- /dev/null
+++ b/.github/workflows/dep_patch.txt
@@ -0,0 +1,9 @@
+
+[patch.'https://github.com/mesalock-linux/net2-rs-sgx']
+net2 = { git = "https://github.com/m4sterchain/net2-rs-sgx", branch = "sgx_oc" }
+
+[patch.'https://github.com/mesalock-linux/mio-sgx']
+mio = { git = "https://github.com/m4sterchain/mio-sgx", branch = "sgx_oc" }
+
+[patch.'https://github.com/mesalock-linux/rusty_leveldb_sgx']
+rusty-leveldb = { git = "https://github.com/m4sterchain/rusty_leveldb_sgx", branch = "sgx_oc" }
\ No newline at end of file
diff --git a/.github/workflows/patch.txt b/.github/workflows/patch.txt
index 71b3847..e728d06 100644
--- a/.github/workflows/patch.txt
+++ b/.github/workflows/patch.txt
@@ -28,4 +28,4 @@ sgx_tunittest = { path = "../../sgx_tunittest" }
sgx_types = { path = "../../sgx_types" }
sgx_ucrypto = { path = "../../sgx_ucrypto" }
sgx_unwind = { path = "../../sgx_unwind" }
-sgx_urts = { path = "../../sgx_urts" }
+sgx_urts = { path = "../../sgx_urts" }
\ No newline at end of file
diff --git a/.github/workflows/sgx-world.yml b/.github/workflows/sgx-world.yml
index f509a3a..8ec3055 100644
--- a/.github/workflows/sgx-world.yml
+++ b/.github/workflows/sgx-world.yml
@@ -22,8 +22,8 @@ jobs:
build-command:
- "cp ../../.github/workflows/Xargo.toml . && RUST_TARGET_PATH=$(pwd) xargo build --target x86_64-unknown-linux-sgx"
- "cp ../../.github/workflows/Xargo.toml . && RUST_TARGET_PATH=$(pwd) xargo build --target x86_64-unknown-linux-sgx --release"
- - "cat ../../.github/workflows/patch.txt >> ./Cargo.toml && cargo build"
- - "cat ../../.github/workflows/patch.txt >> ./Cargo.toml && cargo build --release"
+ - "cargo build"
+ - "cargo build --release"
runs-on: ${{ matrix.runs-on }}
container:
image: ${{ matrix.image }}
@@ -49,6 +49,8 @@ jobs:
. /opt/sgxsdk/environment &&
git clone https://github.com/dingelish/sgx-world &&
cd sgx-world/dumb-all &&
+ cat ../../.github/workflows/patch.txt >> ./Cargo.toml &&
+ cat ../../.github/workflows/dep_patch.txt >> ./Cargo.toml &&
${{ matrix.build-command }} &&
cd ../.. &&
rm -rf sgx-world
diff --git a/.github/workflows/sim-example.yml b/.github/workflows/sim-example.yml
index 29f9a6d..b04389c 100644
--- a/.github/workflows/sim-example.yml
+++ b/.github/workflows/sim-example.yml
@@ -69,6 +69,7 @@ jobs:
. /opt/sgxsdk/environment &&
export SGX_SDK_RUST=`git worktree list | head | cut -d ' ' -f 1` &&
cd samplecode/${{ matrix.single-sample }} &&
+ cat ../../.github/workflows/dep_patch.txt >> ./enclave/Cargo.toml &&
if [ "${{ matrix.single-sample }}" == "protobuf" ]; then cargo install protobuf-codegen --vers=2.8.1; fi
SGX_MODE=SW make &&
cd bin &&
@@ -115,6 +116,8 @@ jobs:
IFS=$(echo -en "\n\b")
compiles=('make' 'XARGO_SGX=1 make')
cd samplecode/tls
+ cat ../../.github/workflows/dep_patch.txt >> tlsclient/enclave/Cargo.toml
+ cat ../../.github/workflows/dep_patch.txt >> tlsserver/enclave/Cargo.toml
for client in ${compiles[@]}
do
for server in ${compiles[@]}
@@ -183,6 +186,8 @@ jobs:
IFS=$(echo -en "\n\b")
compiles=('make' 'XARGO_SGX=1 make')
cd samplecode/mio
+ cat ../../.github/workflows/dep_patch.txt >> client/enclave/Cargo.toml
+ cat ../../.github/workflows/dep_patch.txt >> server/enclave/Cargo.toml
for client in ${compiles[@]}
do
for server in ${compiles[@]}
diff --git a/edl/sgx_env.edl b/edl/sgx_env.edl
index d4a77cc..3139ca4 100644
--- a/edl/sgx_env.edl
+++ b/edl/sgx_env.edl
@@ -24,17 +24,9 @@ enclave {
};
untrusted {
- char **u_environ_ocall();
- char *u_getenv_ocall([in, string] const char *name);
- int u_setenv_ocall([out] int *error, [in, string] const char *name, [in, string] const char *value, int overwrite);
- int u_unsetenv_ocall([out] int *error, [in, string] const char *name);
+ int u_getenv_ocall([out] int *error, [in, string] const char *name, [out, size=bufsz] char *buf, size_t bufsz, [out] int *isset);
int u_chdir_ocall([out] int *error, [in, string] const char *dir);
- char *u_getcwd_ocall([out] int *error, [out, size=buflen] char *buf, size_t buflen);
- int u_getpwuid_r_ocall(unsigned int uid,
- [out] struct passwd *pwd,
- [out, size=buflen] char *buf,
- size_t buflen,
- [out] struct passwd **passwd_result);
+ int u_getcwd_ocall([out] int *error, [out, size=buflen] char *buf, size_t buflen);
unsigned int u_getuid_ocall();
};
};
diff --git a/edl/sgx_fd.edl b/edl/sgx_fd.edl
index 8cfc822..e2ea291 100644
--- a/edl/sgx_fd.edl
+++ b/edl/sgx_fd.edl
@@ -29,13 +29,9 @@ enclave {
untrusted {
size_t u_read_ocall([out] int *error, int fd, [user_check] void *buf, size_t count);
size_t u_pread64_ocall([out] int *error, int fd, [user_check] void *buf, size_t count, int64_t offset);
- size_t u_readv_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt);
- size_t u_preadv64_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt, int64_t offset);
size_t u_write_ocall([out] int *error, int fd, [user_check] const void *buf, size_t count);
size_t u_pwrite64_ocall([out] int *error, int fd, [user_check] const void *buf, size_t count, int64_t offset);
- size_t u_writev_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt);
- size_t u_pwritev64_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt, int64_t offset);
int u_fcntl_arg0_ocall([out] int *error, int fd, int cmd);
int u_fcntl_arg1_ocall([out] int *error, int fd, int cmd, int arg);
diff --git a/edl/sgx_file.edl b/edl/sgx_file.edl
index 1e28036..215ac1a 100644
--- a/edl/sgx_file.edl
+++ b/edl/sgx_file.edl
@@ -50,11 +50,11 @@ enclave {
int u_chmod_ocall([out] int *error, [in, string] const char *path, uint32_t mode);
size_t u_readlink_ocall([out] int *error, [in, string] const char *path, [out, size=bufsz] char *buf, size_t bufsz);
int u_symlink_ocall([out] int *error, [in, string] const char *path1, [in, string] const char *path2);
- char *u_realpath_ocall([out] int *error, [in, string] const char *pathname);
+ int u_realpath_ocall([out] int *error, [in, string] const char *pathname, [out, size=bufsz] char *buf, size_t bufsz);
int u_mkdir_ocall([out] int *error, [in, string] const char *pathname, uint32_t mode);
int u_rmdir_ocall([out] int *error, [in, string] const char *pathname);
void *u_opendir_ocall([out] int *error, [in, string] const char *pathname);
- int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] struct dirent64_t **result);
+ int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] int *eods);
int u_closedir_ocall([out] int *error, [user_check] void *dirp);
int u_dirfd_ocall([out] int *error, [user_check] void *dirp);
int u_fstatat64_ocall([out] int *error, int dirfd, [in, string] const char *pathname, [out] struct stat64_t *buf, int flags);
diff --git a/edl/sgx_net.edl b/edl/sgx_net.edl
index a803b53..64692de 100644
--- a/edl/sgx_net.edl
+++ b/edl/sgx_net.edl
@@ -34,8 +34,9 @@ enclave {
[in, string] const char *node,
[in, string] const char *service,
[in] const struct addrinfo *hints,
- [out] struct addrinfo **res);
- void u_freeaddrinfo_ocall([user_check] struct addrinfo *res);
- char *u_gai_strerror_ocall(int errcode);
+ size_t entry_size,
+ [out, size=bufsz] uint8_t *buf,
+ size_t bufsz,
+ [out] size_t *entry_count);
};
};
diff --git a/edl/sgx_pipe.edl b/edl/sgx_pipe.edl
index 00c12f5..1729fe1 100644
--- a/edl/sgx_pipe.edl
+++ b/edl/sgx_pipe.edl
@@ -25,7 +25,6 @@ enclave {
};
untrusted {
- int u_pipe_ocall([out] int *error, [out, count=2] int *pipefd);
int u_pipe2_ocall([out] int *error, [out, count=2] int *pipefd, int flags);
};
};
diff --git a/edl/sgx_socket.edl b/edl/sgx_socket.edl
index 68ce3b6..d6d9f8f 100644
--- a/edl/sgx_socket.edl
+++ b/edl/sgx_socket.edl
@@ -30,11 +30,6 @@ enclave {
int u_socketpair_ocall([out] int *error, int domain, int ty, int protocol, [out] int sv[2]);
int u_bind_ocall([out] int *error, int sockfd, [in, size=addrlen] const struct sockaddr *addr, socklen_t addrlen);
int u_listen_ocall([out] int *error, int sockfd, int backlog);
- int u_accept_ocall([out] int *error,
- int sockfd,
- [in, out, size=addrlen_in] struct sockaddr *addr,
- socklen_t addrlen_in,
- [out] socklen_t *addrlen_out);
int u_accept4_ocall([out] int *error,
int sockfd,
[in, out, size=addrlen_in] struct sockaddr *addr,
@@ -54,7 +49,6 @@ enclave {
[out, size=addrlen_in] struct sockaddr *src_addr,
socklen_t addrlen_in,
[out] socklen_t *addrlen_out);
- size_t u_recvmsg_ocall([out] int *error, int sockfd, [in, out] struct msghdr *msg, int flags);
size_t u_send_ocall([out] int *error, int sockfd, [user_check] const void *buf, size_t len, int flags);
size_t u_sendto_ocall([out] int *error,
int sockfd,
@@ -63,7 +57,6 @@ enclave {
int flags,
[in, size=addrlen] const struct sockaddr *dest_addr,
socklen_t addrlen);
- size_t u_sendmsg_ocall([out] int *error, int sockfd, [in] const struct msghdr *msg, int flags);
int u_getsockopt_ocall([out] int *error,
int sockfd,
int level,
diff --git a/samplecode/hello-rust/enclave/Enclave.edl b/samplecode/hello-rust/enclave/Enclave.edl
index 0263761..9b173b4 100644
--- a/samplecode/hello-rust/enclave/Enclave.edl
+++ b/samplecode/hello-rust/enclave/Enclave.edl
@@ -20,6 +20,9 @@ enclave {
from "sgx_stdio.edl" import *;
from "sgx_backtrace.edl" import *;
from "sgx_tstdc.edl" import *;
+ from "sgx_net.edl" import *;
+ from "sgx_socket.edl" import *;
+
trusted {
/* define ECALLs here. */
diff --git a/samplecode/http_req/Makefile b/samplecode/http_req/Makefile
index fee080a..bb39037 100644
--- a/samplecode/http_req/Makefile
+++ b/samplecode/http_req/Makefile
@@ -46,8 +46,8 @@ SGX_COMMON_CFLAGS += -fstack-protector
CUSTOM_LIBRARY_PATH := ./lib
CUSTOM_BIN_PATH := ./bin
-CUSTOM_EDL_PATH := $(SGX_SDK_RUST)/edl
-CUSTOM_COMMON_PATH := $(SGX_SDK_RUST)/common
+CUSTOM_EDL_PATH := ../../edl
+CUSTOM_COMMON_PATH := ../../common
######## EDL Settings ########
diff --git a/samplecode/unit-test/enclave/Cargo.toml b/samplecode/unit-test/enclave/Cargo.toml
index 1e0e6d9..1410ce4 100644
--- a/samplecode/unit-test/enclave/Cargo.toml
+++ b/samplecode/unit-test/enclave/Cargo.toml
@@ -13,7 +13,7 @@ hw_test = []
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
-sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["untrusted_fs", "thread", "backtrace"] }
+sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["untrusted_fs", "thread", "backtrace", "net", "pipe"] }
sgx_tcrypto = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_tunittest = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
diff --git a/samplecode/unit-test/enclave/Enclave.edl b/samplecode/unit-test/enclave/Enclave.edl
index 59eff09..eb13833 100644
--- a/samplecode/unit-test/enclave/Enclave.edl
+++ b/samplecode/unit-test/enclave/Enclave.edl
@@ -23,10 +23,12 @@ enclave {
from "sgx_fs.edl" import *;
from "sgx_time.edl" import *;
from "sgx_thread.edl" import *;
+ from "sgx_pthread.edl" import *;
from "sgx_sys.edl" import *;
from "sgx_backtrace.edl" import *;
from "sgx_signal.edl" import*;
from "sgx_process.edl" import*;
+ from "sgx_net.edl" import*;
trusted {
/* define ECALLs here. */
diff --git a/samplecode/unit-test/enclave/src/lib.rs b/samplecode/unit-test/enclave/src/lib.rs
index e010cd5..6a06d3d 100644
--- a/samplecode/unit-test/enclave/src/lib.rs
+++ b/samplecode/unit-test/enclave/src/lib.rs
@@ -93,6 +93,9 @@ use test_env::*;
mod test_path;
use test_path::*;
+mod test_net;
+use test_net::*;
+
mod test_thread;
use test_thread::*;
@@ -178,7 +181,6 @@ fn test_main_entrance() -> size_t {
check_metadata_size,
check_version,
// env
- test_env_vars_os,
test_env_self_exe_path,
test_env_current_dir,
test_env_home_dir,
@@ -205,6 +207,10 @@ fn test_main_entrance() -> size_t {
test_path_mkdir_trailing_slash,
test_path_create_dir_all_with_junctions,
test_path_copy_file_follows_dst_symlink,
+ test_rwv,
+ // net
+ test_gai_error,
+ test_udp,
// thread
test_thread_unnamed_thread,
test_thread_named_thread,
diff --git a/samplecode/unit-test/enclave/src/test_env.rs b/samplecode/unit-test/enclave/src/test_env.rs
index 3f177e7..756a978 100644
--- a/samplecode/unit-test/enclave/src/test_env.rs
+++ b/samplecode/unit-test/enclave/src/test_env.rs
@@ -1,11 +1,6 @@
use std::env::*;
use std::path::Path;
-pub fn test_env_vars_os() {
- let p = vars_os();
- assert_ne!(0, p.size_hint().0);
-}
-
pub fn test_env_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
@@ -22,5 +17,5 @@ pub fn test_env_current_dir() {
pub fn test_env_home_dir() {
let dir = home_dir();
- println!("{:?}", dir.unwrap());
+ println!("[ENV] HOME: {:?}", dir.unwrap());
}
diff --git a/samplecode/unit-test/enclave/src/test_file.rs b/samplecode/unit-test/enclave/src/test_file.rs
index 715794f..eb0f622 100644
--- a/samplecode/unit-test/enclave/src/test_file.rs
+++ b/samplecode/unit-test/enclave/src/test_file.rs
@@ -71,7 +71,8 @@ pub fn test_sgxfs() {
{
let opt1 = SgxFile::open("/dev/isgx");
let opt2 = SgxFile::open("/dev/sgx/enclave");
- assert_eq!(opt1.is_ok() || opt2.is_ok(), true);
+ let opt3 = SgxFile::open("/dev/sgx");
+ assert_eq!(opt1.is_ok() || opt2.is_ok() || opt3.is_ok(), true);
}
{
let opt = SgxFile::create("/");
diff --git a/samplecode/unit-test/enclave/src/test_net.rs b/samplecode/unit-test/enclave/src/test_net.rs
new file mode 100644
index 0000000..3e492f4
--- /dev/null
+++ b/samplecode/unit-test/enclave/src/test_net.rs
@@ -0,0 +1,77 @@
+use std::net::ToSocketAddrs;
+
+pub fn test_gai_error() {
+ let result = ("rust-lang.org", 80).to_socket_addrs();
+ assert!(result.is_ok());
+ let result = ("rust-lang.or", 80).to_socket_addrs();
+ assert!(result.is_err());
+}
+
+
+use std::thread;
+use std::net;
+use std::vec::Vec;
+
+fn socket(listen_on: net::SocketAddr) -> net::UdpSocket {
+ let attempt = net::UdpSocket::bind(listen_on);
+ let socket;
+ match attempt {
+ Ok(sock) => {
+ println!("Bound socket to {}", listen_on);
+ socket = sock;
+ },
+ Err(err) => panic!("Could not bind: {}", err)
+ }
+ socket
+}
+
+fn read_message(socket: net::UdpSocket) -> Vec<u8> {
+ let mut buf: [u8; 1] = [0; 1];
+ println!("Reading data");
+ let result = socket.recv_from(&mut buf);
+ drop(socket);
+ let data;
+ match result {
+ Ok((amt, src)) => {
+ println!("Received data from {}", src);
+ data = Vec::from(&buf[0..amt]);
+ },
+ Err(err) => panic!("Read error: {}", err)
+ }
+ data
+}
+
+pub fn send_message(send_addr: net::SocketAddr, target: net::SocketAddr, data: Vec<u8>) {
+ let socket = socket(send_addr);
+ println!("Sending data");
+ let result = socket.send_to(&data, target);
+ drop(socket);
+ match result {
+ Ok(amt) => println!("Sent {} bytes", amt),
+ Err(err) => panic!("Write error: {}", err)
+ }
+}
+
+fn listen(listen_on: net::SocketAddr) -> thread::JoinHandle<Vec<u8>> {
+ let socket = socket(listen_on);
+ let handle = thread::spawn(move || {
+ read_message(socket)
+ });
+ handle
+}
+
+pub fn test_udp() {
+ println!("UDP");
+ let ip = net::Ipv4Addr::new(127, 0, 0, 1);
+ let listen_addr = net::SocketAddrV4::new(ip, 8888);
+ let send_addr = net::SocketAddrV4::new(ip, 8889);
+ let future = listen(net::SocketAddr::V4(listen_addr));
+ let message: Vec<u8> = vec![10];
+ thread::sleep_ms(3000);
+ send_message(net::SocketAddr::V4(send_addr), net::SocketAddr::V4(listen_addr), message);
+ println!("Waiting");
+ let received = future.join().unwrap();
+ println!("Got {} bytes", received.len());
+ assert_eq!(1, received.len());
+ assert_eq!(10, received[0]);
+ }
\ No newline at end of file
diff --git a/samplecode/unit-test/enclave/src/test_path.rs b/samplecode/unit-test/enclave/src/test_path.rs
index b550d39..b7e6c8e 100644
--- a/samplecode/unit-test/enclave/src/test_path.rs
+++ b/samplecode/unit-test/enclave/src/test_path.rs
@@ -6,6 +6,7 @@ use std::fs;
use std::panic;
use core::str;
use std::io::{Read, Write, ErrorKind};
+use std::io::{IoSliceMut, IoSlice};
macro_rules! check { ($e:expr) => (
match $e {
@@ -315,3 +316,72 @@ pub fn test_path_copy_file_follows_dst_symlink() {
assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec());
assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec());
}
+
+pub fn test_rwv() {
+ let chunck_size = 100;
+ let n = 6;
+ let block_size = n * chunck_size;
+
+ let buffer1 = vec![1; block_size];
+ let buffer2 = vec![2; block_size];
+ let buffer3 = vec![3; block_size];
+ let buffer4 = vec![4; block_size];
+
+ let fname = "foo.txt";
+
+ {
+ let mut file = File::create(&fname).unwrap();
+ let input = &[
+ IoSlice::new(&buffer1),
+ ][..];
+ file.write_vectored(input).unwrap();
+
+ let input = &[
+ IoSlice::new(&buffer2),
+ IoSlice::new(&buffer3),
+ IoSlice::new(&buffer4),
+ ][..];
+ file.write_vectored(input).unwrap();
+ }
+
+
+ let mut b1 = vec![0; chunck_size];
+ let mut b2 = vec![0; chunck_size];
+ let mut b3 = vec![0; chunck_size];
+ let mut b4 = vec![0; chunck_size];
+ let mut b5 = vec![0; chunck_size];
+ let mut b6 = vec![0; chunck_size];
+ {
+ let mut file2 = File::open(&fname).unwrap();
+
+ let mut i = 1;
+ loop {
+ {
+ let mut bufs = &mut [
+ IoSliceMut::new(&mut b1),
+ IoSliceMut::new(&mut b2),
+ IoSliceMut::new(&mut b3),
+ IoSliceMut::new(&mut b4),
+ IoSliceMut::new(&mut b5),
+ IoSliceMut::new(&mut b6),
+ ][..];
+
+ if file2.read_vectored(&mut bufs).unwrap() == 0 {
+ break
+ }
+ }
+
+ let data = vec![i; chunck_size];
+ assert_eq!(&data[..], &b1[..]);
+ assert_eq!(&b1[..], &b2[..]);
+ assert_eq!(&b2[..], &b3[..]);
+ assert_eq!(&b3[..], &b4[..]);
+ assert_eq!(&b4[..], &b5[..]);
+ assert_eq!(&b5[..], &b6[..]);
+
+ i += 1;
+ }
+ }
+
+ check!(fs::remove_file(&fname));
+}
\ No newline at end of file
diff --git a/samplecode/unit-test/enclave/src/test_rts.rs b/samplecode/unit-test/enclave/src/test_rts.rs
index 668e50f..a11c71f 100644
--- a/samplecode/unit-test/enclave/src/test_rts.rs
+++ b/samplecode/unit-test/enclave/src/test_rts.rs
@@ -16,17 +16,17 @@
// under the License..
use sgx_types::*;
-use std::vec::Vec;
use std::string::String;
+use std::vec::Vec;
-use sgx_trts::trts::*;
-use sgx_trts::veh::*;
use sgx_trts::ascii::AsciiExt;
use sgx_trts::c_str::*;
+use sgx_trts::enclave::*;
use sgx_trts::error;
-use sgx_trts::memchr;
use sgx_trts::libc;
-use sgx_trts::enclave::*;
+use sgx_trts::memchr;
+use sgx_trts::trts::*;
+use sgx_trts::veh::*;
//Only during dev
//use core::mem;
@@ -36,7 +36,7 @@ global_ctors_object! {
}
// veh
-extern "C" fn sample_exception_handler(_ : *mut sgx_exception_info_t) -> int32_t {
+extern "C" fn sample_exception_handler(_: *mut sgx_exception_info_t) -> int32_t {
0
}
@@ -63,12 +63,11 @@ pub fn test_register_last_exception_handler() {
}
pub fn test_register_multiple_exception_handler() {
- let mut handler_vec : Vec<exception_handle> = Vec::new();
- let ntest:usize = 100;
+ let mut handler_vec: Vec<exception_handle> = Vec::new();
+ let ntest: usize = 100;
for i in 0..ntest {
- let handle = rsgx_register_exception_handler(i as uint32_t % 2,
- sample_exception_handler);
+ let handle = rsgx_register_exception_handler(i as uint32_t % 2, sample_exception_handler);
assert!(handle.is_some());
handler_vec.push(handle.unwrap());
}
@@ -85,7 +84,7 @@ pub fn test_register_multiple_exception_handler() {
}
// trts
-pub fn test_read_rand(){
+pub fn test_read_rand() {
let mut rand_arr = [0; 100];
assert_eq!(rsgx_read_rand(&mut rand_arr[..]), Ok(()));
// Cannot all be zero
@@ -96,7 +95,7 @@ pub fn test_read_rand(){
pub fn test_data_is_within_enclave() {
#[allow(dead_code)]
#[derive(Clone, Copy)]
- struct SampleDs{
+ struct SampleDs {
x: i32,
y: i32,
z: [i32; 100],
@@ -110,7 +109,7 @@ pub fn test_data_is_within_enclave() {
let ooo;
unsafe {
- let ppp = 0xdeadbeafdeadbeaf as * const u8;
+ let ppp = 0xdeadbeafdeadbeaf as *const u8;
ooo = &*ppp;
}
assert_eq!(rsgx_data_is_within_enclave(ooo), false);
@@ -129,19 +128,21 @@ pub fn test_slice_is_within_enlave() {
//assert_eq!(rsgx_slice_is_within_enclave(ooo), false);
}
-pub fn test_raw_is_within_enclave(){
- assert_eq!(rsgx_raw_is_within_enclave(test_raw_is_within_enclave as * const u8,
- 10),
- true);
- assert_eq!(rsgx_raw_is_within_enclave(0xdeadbeafdeadbeaf as * const u8,
- 10),
- false);
+pub fn test_raw_is_within_enclave() {
+ assert_eq!(
+ rsgx_raw_is_within_enclave(test_raw_is_within_enclave as *const u8, 10),
+ true
+ );
+ assert_eq!(
+ rsgx_raw_is_within_enclave(0xdeadbeafdeadbeaf as *const u8, 10),
+ false
+ );
}
pub fn test_data_is_outside_enclave() {
#[allow(dead_code)]
#[derive(Clone, Copy)]
- struct SampleDs{
+ struct SampleDs {
x: i32,
y: i32,
z: [i32; 100],
@@ -155,7 +156,7 @@ pub fn test_data_is_outside_enclave() {
let ooo;
unsafe {
- let ppp = 0xdeadbeafdeadbeaf as * const u8;
+ let ppp = 0xdeadbeafdeadbeaf as *const u8;
ooo = &*ppp;
}
assert_eq!(rsgx_data_is_outside_enclave(ooo), true);
@@ -174,18 +175,20 @@ pub fn test_slice_is_outside_enclave() {
//assert_eq!(rsgx_slice_is_within_enclave(ooo), true);
}
-pub fn test_raw_is_outside_enclave(){
- assert_eq!(rsgx_raw_is_outside_enclave(test_raw_is_outside_enclave as * const u8,
- 10),
- false);
- assert_eq!(rsgx_raw_is_outside_enclave(0xdeadbeafdeadbeaf as * const u8,
- 10),
- true);
+pub fn test_raw_is_outside_enclave() {
+ assert_eq!(
+ rsgx_raw_is_outside_enclave(test_raw_is_outside_enclave as *const u8, 10),
+ false
+ );
+ assert_eq!(
+ rsgx_raw_is_outside_enclave(0xdeadbeafdeadbeaf as *const u8, 10),
+ true
+ );
}
// macros
-pub fn test_global_ctors_object (){
+pub fn test_global_ctors_object() {
assert_eq!(VARNAME(), ());
}
@@ -195,72 +198,54 @@ pub fn test_global_ctors_object (){
// error
pub fn test_error() {
// XXX: Top 11 should be the same in all unix?
- let errorinfo_vec:Vec<(i32,&'static str)> = vec![
- (1 , "Operation not permitted"),
- (2 , "No such file or directory"),
- (3 , "No such process"),
- (4 , "Interrupted system call"),
- (5 , "Input/output error"),
- (6 , "Device not configured"),
- (7 , "Argument list too long"),
- (8 , "Exec format error"),
- (9 , "Bad file descriptor"),
+ let errorinfo_vec: Vec<(i32, &'static str)> = vec![
+ (1, "Operation not permitted"),
+ (2, "No such file or directory"),
+ (3, "No such process"),
+ (4, "Interrupted system call"),
+ (5, "Input/output error"),
+ (6, "Device not configured"),
+ (7, "Argument list too long"),
+ (8, "Exec format error"),
+ (9, "Bad file descriptor"),
(10, "No child processes"),
(11, "Resource deadlock avoided"),
- ];
+ ];
for case in errorinfo_vec {
- let mut buf:[i8;64] = [0;64];
+ let mut buf: [i8; 64] = [0; 64];
error::set_errno(case.0);
- unsafe { error::error_string(error::errno(),&mut buf[..]);}
- let answer:Vec<u8> = buf.iter().map(|&x| x as u8).collect();
+ unsafe {
+ error::error_string(error::errno(), &mut buf[..]);
+ }
+ let answer: Vec<u8> = buf.iter().map(|&x| x as u8).collect();
let ans_str = String::from_utf8(answer).unwrap();
- assert_eq!(ans_str.trim_matches('\0'),
- case.1);
+ assert_eq!(ans_str.trim_matches('\0'), case.1);
}
-
}
// libc
-pub fn test_rts_libc_memchr(){
+pub fn test_rts_libc_memchr() {
let test_str = "abcdedfg";
assert_eq!(
- unsafe {
- libc::memchr(
- test_str.as_ptr() as * const u8,
- 'd' as u8,
- test_str.len())},
- test_str[3..].as_ptr());
- assert_eq!(
- unsafe {
- libc::memchr(
- "abcdefg".as_ptr() as * const u8,
- 'z' as u8,
- test_str.len())},
- 0 as * const u8);
+ libc::memchr::memchr('d' as u8, test_str.as_bytes()),
+ Some(3)
+ );
+ assert_eq!(libc::memchr::memchr('z' as u8, "abcdefg".as_bytes()), None);
}
-pub fn test_rts_libc_memrchr(){
+pub fn test_rts_libc_memrchr() {
let test_str = "abcdedfg";
assert_eq!(
- unsafe {
- libc::memrchr(
- test_str.as_ptr() as * const u8,
- 'd' as u8,
- test_str.len())},
- test_str[5..].as_ptr());
- assert_eq!(
- unsafe {
- libc::memrchr(
- "abcdefg".as_ptr() as * const u8,
- 'z' as u8,
- test_str.len())},
- 0 as * const u8);
+ libc::memchr::memrchr('d' as u8, test_str.as_bytes()),
+ Some(5)
+ );
+ assert_eq!(libc::memchr::memrchr('z' as u8, "abcdefg".as_bytes()), None);
}
// memchr
-pub fn test_rts_memchr_memchr(){
+pub fn test_rts_memchr_memchr() {
let test_str = "abcdedfg".as_bytes();
let needle = 'd' as u8;
assert_eq!(memchr::memchr(needle, test_str), Some(3));
@@ -268,7 +253,7 @@ pub fn test_rts_memchr_memchr(){
assert_eq!(memchr::memchr(needle, test_str), None);
}
-pub fn test_rts_memchr_memrchr(){
+pub fn test_rts_memchr_memrchr() {
let test_str = "abcdedfg".as_bytes();
let needle = 'd' as u8;
assert_eq!(memchr::memrchr(needle, test_str), Some(5));
@@ -277,7 +262,7 @@ pub fn test_rts_memchr_memrchr(){
}
// ascii
-pub fn test_ascii(){
+pub fn test_ascii() {
assert_eq!("café".to_ascii_uppercase(), "CAFÉ");
assert_eq!("café".to_ascii_uppercase(), "CAFé");
@@ -292,7 +277,6 @@ pub fn test_ascii(){
assert_eq!('❤', non_ascii.to_ascii_uppercase());
assert_eq!(65, int_ascii.to_ascii_uppercase());
-
let ascii = 'A';
let non_ascii = '❤';
let int_ascii = 65;
@@ -320,7 +304,7 @@ pub fn test_ascii(){
}
// c_str
-pub fn test_cstr(){
+pub fn test_cstr() {
let c_string = CString::new("foo").unwrap();
let ptr = c_string.into_raw();
@@ -373,7 +357,7 @@ pub fn test_cstr(){
let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0").unwrap();
assert_eq!(
- c_str.to_string_lossy(),
- Cow::Owned(String::from("Hello �World")) as Cow<str>
- );
+ c_str.to_string_lossy(),
+ Cow::Owned(String::from("Hello �World")) as Cow<str>
+ );
}
diff --git a/samplecode/unit-test/enclave/src/test_signal.rs b/samplecode/unit-test/enclave/src/test_signal.rs
index c944e14..e6f13a4 100644
--- a/samplecode/unit-test/enclave/src/test_signal.rs
+++ b/samplecode/unit-test/enclave/src/test_signal.rs
@@ -63,7 +63,7 @@ pub fn test_signal_with_pid() {
}
};
- let pid = unsafe { getpid() };
+ let pid = unsafe { getpid().unwrap() };
register_sigaction(SIGUSR2, action).unwrap();
raise_signal(SIGUSR2);
diff --git a/sgx_edl/edl/sgx_env.edl b/sgx_edl/edl/sgx_env.edl
index d4a77cc..3139ca4 100644
--- a/sgx_edl/edl/sgx_env.edl
+++ b/sgx_edl/edl/sgx_env.edl
@@ -24,17 +24,9 @@ enclave {
};
untrusted {
- char **u_environ_ocall();
- char *u_getenv_ocall([in, string] const char *name);
- int u_setenv_ocall([out] int *error, [in, string] const char *name, [in, string] const char *value, int overwrite);
- int u_unsetenv_ocall([out] int *error, [in, string] const char *name);
+ int u_getenv_ocall([out] int *error, [in, string] const char *name, [out, size=bufsz] char *buf, size_t bufsz, [out] int *isset);
int u_chdir_ocall([out] int *error, [in, string] const char *dir);
- char *u_getcwd_ocall([out] int *error, [out, size=buflen] char *buf, size_t buflen);
- int u_getpwuid_r_ocall(unsigned int uid,
- [out] struct passwd *pwd,
- [out, size=buflen] char *buf,
- size_t buflen,
- [out] struct passwd **passwd_result);
+ int u_getcwd_ocall([out] int *error, [out, size=buflen] char *buf, size_t buflen);
unsigned int u_getuid_ocall();
};
};
diff --git a/sgx_edl/edl/sgx_fd.edl b/sgx_edl/edl/sgx_fd.edl
index 8cfc822..e2ea291 100644
--- a/sgx_edl/edl/sgx_fd.edl
+++ b/sgx_edl/edl/sgx_fd.edl
@@ -29,13 +29,9 @@ enclave {
untrusted {
size_t u_read_ocall([out] int *error, int fd, [user_check] void *buf, size_t count);
size_t u_pread64_ocall([out] int *error, int fd, [user_check] void *buf, size_t count, int64_t offset);
- size_t u_readv_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt);
- size_t u_preadv64_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt, int64_t offset);
size_t u_write_ocall([out] int *error, int fd, [user_check] const void *buf, size_t count);
size_t u_pwrite64_ocall([out] int *error, int fd, [user_check] const void *buf, size_t count, int64_t offset);
- size_t u_writev_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt);
- size_t u_pwritev64_ocall([out] int *error, int fd, [in, count=iovcnt] const struct iovec *iov, int iovcnt, int64_t offset);
int u_fcntl_arg0_ocall([out] int *error, int fd, int cmd);
int u_fcntl_arg1_ocall([out] int *error, int fd, int cmd, int arg);
diff --git a/sgx_edl/edl/sgx_file.edl b/sgx_edl/edl/sgx_file.edl
index 1e28036..1c95f3e 100644
--- a/sgx_edl/edl/sgx_file.edl
+++ b/sgx_edl/edl/sgx_file.edl
@@ -50,11 +50,11 @@ enclave {
int u_chmod_ocall([out] int *error, [in, string] const char *path, uint32_t mode);
size_t u_readlink_ocall([out] int *error, [in, string] const char *path, [out, size=bufsz] char *buf, size_t bufsz);
int u_symlink_ocall([out] int *error, [in, string] const char *path1, [in, string] const char *path2);
- char *u_realpath_ocall([out] int *error, [in, string] const char *pathname);
+ int u_realpath_ocall([out] int *error, [in, string] const char *pathname, [out, size=bufsz] char *buf, size_t bufsz);
int u_mkdir_ocall([out] int *error, [in, string] const char *pathname, uint32_t mode);
int u_rmdir_ocall([out] int *error, [in, string] const char *pathname);
void *u_opendir_ocall([out] int *error, [in, string] const char *pathname);
- int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] struct dirent64_t **result);
+ int u_readdir64_r_ocall([user_check] void *dirp, [in, out] struct dirent64_t *entry, [out] int * eods);
int u_closedir_ocall([out] int *error, [user_check] void *dirp);
int u_dirfd_ocall([out] int *error, [user_check] void *dirp);
int u_fstatat64_ocall([out] int *error, int dirfd, [in, string] const char *pathname, [out] struct stat64_t *buf, int flags);
diff --git a/sgx_edl/edl/sgx_net.edl b/sgx_edl/edl/sgx_net.edl
index a803b53..64692de 100644
--- a/sgx_edl/edl/sgx_net.edl
+++ b/sgx_edl/edl/sgx_net.edl
@@ -34,8 +34,9 @@ enclave {
[in, string] const char *node,
[in, string] const char *service,
[in] const struct addrinfo *hints,
- [out] struct addrinfo **res);
- void u_freeaddrinfo_ocall([user_check] struct addrinfo *res);
- char *u_gai_strerror_ocall(int errcode);
+ size_t entry_size,
+ [out, size=bufsz] uint8_t *buf,
+ size_t bufsz,
+ [out] size_t *entry_count);
};
};
diff --git a/sgx_edl/edl/sgx_pipe.edl b/sgx_edl/edl/sgx_pipe.edl
index 00c12f5..1729fe1 100644
--- a/sgx_edl/edl/sgx_pipe.edl
+++ b/sgx_edl/edl/sgx_pipe.edl
@@ -25,7 +25,6 @@ enclave {
};
untrusted {
- int u_pipe_ocall([out] int *error, [out, count=2] int *pipefd);
int u_pipe2_ocall([out] int *error, [out, count=2] int *pipefd, int flags);
};
};
diff --git a/sgx_edl/edl/sgx_socket.edl b/sgx_edl/edl/sgx_socket.edl
index 68ce3b6..d6d9f8f 100644
--- a/sgx_edl/edl/sgx_socket.edl
+++ b/sgx_edl/edl/sgx_socket.edl
@@ -30,11 +30,6 @@ enclave {
int u_socketpair_ocall([out] int *error, int domain, int ty, int protocol, [out] int sv[2]);
int u_bind_ocall([out] int *error, int sockfd, [in, size=addrlen] const struct sockaddr *addr, socklen_t addrlen);
int u_listen_ocall([out] int *error, int sockfd, int backlog);
- int u_accept_ocall([out] int *error,
- int sockfd,
- [in, out, size=addrlen_in] struct sockaddr *addr,
- socklen_t addrlen_in,
- [out] socklen_t *addrlen_out);
int u_accept4_ocall([out] int *error,
int sockfd,
[in, out, size=addrlen_in] struct sockaddr *addr,
@@ -54,7 +49,6 @@ enclave {
[out, size=addrlen_in] struct sockaddr *src_addr,
socklen_t addrlen_in,
[out] socklen_t *addrlen_out);
- size_t u_recvmsg_ocall([out] int *error, int sockfd, [in, out] struct msghdr *msg, int flags);
size_t u_send_ocall([out] int *error, int sockfd, [user_check] const void *buf, size_t len, int flags);
size_t u_sendto_ocall([out] int *error,
int sockfd,
@@ -63,7 +57,6 @@ enclave {
int flags,
[in, size=addrlen] const struct sockaddr *dest_addr,
socklen_t addrlen);
- size_t u_sendmsg_ocall([out] int *error, int sockfd, [in] const struct msghdr *msg, int flags);
int u_getsockopt_ocall([out] int *error,
int sockfd,
int level,
diff --git a/sgx_edl/edl/sgx_sys.edl b/sgx_edl/edl/sgx_sys.edl
index f5f3d2c..6561725 100644
--- a/sgx_edl/edl/sgx_sys.edl
+++ b/sgx_edl/edl/sgx_sys.edl
@@ -24,7 +24,6 @@ enclave {
};
untrusted {
- long u_sysconf_ocall([out] int *error, int name);
int u_prctl_ocall([out] int *error, int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
int u_sched_setaffinity_ocall([out] int *error, pid_t pid, size_t cpusetsize, [in, size=cpusetsize]cpu_set_t *mask);
int u_sched_getaffinity_ocall([out] int *error, pid_t pid, size_t cpusetsize, [out, size=cpusetsize]cpu_set_t *mask);
diff --git a/sgx_trts/src/ascii.rs b/sgx_libc/src/ascii.rs
similarity index 100%
rename from sgx_trts/src/ascii.rs
rename to sgx_libc/src/ascii.rs
diff --git a/sgx_trts/src/c_str.rs b/sgx_libc/src/c_str.rs
similarity index 99%
rename from sgx_trts/src/c_str.rs
rename to sgx_libc/src/c_str.rs
index 8e55c92..30b37fd 100644
--- a/sgx_trts/src/c_str.rs
+++ b/sgx_libc/src/c_str.rs
@@ -24,7 +24,6 @@
/// bytes ("nul characters") and that the final byte is 0 ("nul terminator").
///
use sgx_types::c_char;
-use crate::libc;
use crate::memchr;
use crate::ascii;
@@ -267,7 +266,7 @@ impl CString {
/// [`CStr`]: struct.CStr.html
///
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
- let len = libc::strlen(ptr) + 1; // Including the NUL byte
+ let len = crate::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts_mut(ptr, len as usize);
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
}
@@ -634,7 +633,7 @@ impl CStr {
/// > the string. This is not guaranteed to always be the case.
///
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
- let len = libc::strlen(ptr);
+ let len = crate::strlen(ptr);
let ptr = ptr as *const u8;
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
}
diff --git a/sgx_libc/src/lib.rs b/sgx_libc/src/lib.rs
index d669e18..61b751f 100644
--- a/sgx_libc/src/lib.rs
+++ b/sgx_libc/src/lib.rs
@@ -25,6 +25,11 @@
#![allow(non_snake_case)]
#![allow(unused_macros)]
#![allow(unused_assignments)]
+#![feature(const_raw_ptr_deref)]
+#![feature(min_specialization)]
+#![feature(vec_into_raw_parts)]
+#![feature(toowned_clone_into)]
+#![feature(slice_index_methods)]
#[macro_use]
extern crate alloc;
@@ -46,3 +51,7 @@ cfg_if! {
}
}
+
+pub mod memchr;
+pub mod ascii;
+pub mod c_str;
\ No newline at end of file
diff --git a/sgx_libc/src/linux/mod.rs b/sgx_libc/src/linux/mod.rs
index f05c8e9..9d79204 100644
--- a/sgx_libc/src/linux/mod.rs
+++ b/sgx_libc/src/linux/mod.rs
@@ -17,6 +17,7 @@
cfg_if! {
if #[cfg(all(target_os = "linux", target_arch = "x86_64"))] {
+ #[macro_use]
mod x86_64;
pub use self::x86_64::*;
} else {
diff --git a/sgx_libc/src/linux/x86_64/mod.rs b/sgx_libc/src/linux/x86_64/mod.rs
index 4477875..40f85df 100644
--- a/sgx_libc/src/linux/x86_64/mod.rs
+++ b/sgx_libc/src/linux/x86_64/mod.rs
@@ -21,15 +21,19 @@
//! It is a c-style interface and self-explained. Currently we don't have much
//! time for documenting it.
-pub use sgx_types::{int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t};
-pub use sgx_types::{c_void, c_schar, c_char, c_uchar, c_short, c_ushort, c_int, c_uint, c_float,
- c_double, c_longlong, c_ulonglong, intmax_t, uintmax_t, c_ulong, c_long};
-pub use sgx_types::{size_t, ptrdiff_t, intptr_t, uintptr_t, ssize_t};
pub use sgx_types::time_t;
+pub use sgx_types::{
+ c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
+ c_ulong, c_ulonglong, c_ushort, c_void, intmax_t, uintmax_t,
+};
+pub use sgx_types::{int16_t, int32_t, int64_t, int8_t, uint16_t, uint32_t, uint64_t, uint8_t};
+pub use sgx_types::{intptr_t, ptrdiff_t, size_t, ssize_t, uintptr_t};
-use sgx_types::{sgx_thread_mutex_t, sgx_thread_mutex_attr_t, sgx_thread_cond_t, sgx_thread_cond_attr_t};
-use core::ptr;
use core::mem;
+use core::ptr;
+use sgx_types::{
+ sgx_thread_cond_attr_t, sgx_thread_cond_t, sgx_thread_mutex_attr_t, sgx_thread_mutex_t,
+};
extern "C" {
pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void;
@@ -41,35 +45,38 @@ extern "C" {
#[link(name = "sgx_pthread")]
extern "C" {
- pub fn pthread_create(native: *mut pthread_t,
- attr: *const pthread_attr_t,
- f: extern "C" fn(*mut c_void) -> *mut c_void,
- value: *mut c_void) -> c_int;
- pub fn pthread_join(native: pthread_t,
- value: *mut *mut c_void) -> c_int;
+ pub fn pthread_create(
+ native: *mut pthread_t,
+ attr: *const pthread_attr_t,
+ f: extern "C" fn(*mut c_void) -> *mut c_void,
+ value: *mut c_void,
+ ) -> c_int;
+ pub fn pthread_join(native: pthread_t, value: *mut *mut c_void) -> c_int;
pub fn pthread_exit(value: *mut c_void);
pub fn pthread_self() -> pthread_t;
pub fn pthread_equal(t1: pthread_t, t2: pthread_t) -> c_int;
pub fn pthread_once(once_control: *mut pthread_once_t, init_routine: extern "C" fn()) -> c_int;
- pub fn pthread_key_create(key: *mut pthread_key_t,
- dtor: Option<unsafe extern "C" fn(*mut c_void)>) -> c_int;
+ pub fn pthread_key_create(
+ key: *mut pthread_key_t,
+ dtor: Option<unsafe extern "C" fn(*mut c_void)>,
+ ) -> c_int;
pub fn pthread_key_delete(key: pthread_key_t) -> c_int;
pub fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
pub fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int;
-
- pub fn pthread_mutex_init(lock: *mut pthread_mutex_t,
- attr: *const pthread_mutexattr_t) -> c_int;
+
+ pub fn pthread_mutex_init(
+ lock: *mut pthread_mutex_t,
+ attr: *const pthread_mutexattr_t,
+ ) -> c_int;
pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> c_int;
pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int;
pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> c_int;
pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> c_int;
- pub fn pthread_cond_init(cond: *mut pthread_cond_t,
- attr: *const pthread_condattr_t) -> c_int;
- pub fn pthread_cond_wait(cond: *mut pthread_cond_t,
- lock: *mut pthread_mutex_t) -> c_int;
+ pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) -> c_int;
+ pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> c_int;
pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int;
pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int;
pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int;
@@ -100,16 +107,12 @@ extern "C" {
/// Get the last error number.
pub fn errno() -> i32 {
- unsafe {
- (*errno_location()) as i32
- }
+ unsafe { (*errno_location()) as i32 }
}
/// Set the last error number.
pub fn set_errno(e: i32) {
- unsafe {
- *errno_location() = e as c_int
- }
+ unsafe { *errno_location() = e as c_int }
}
/// Gets a detailed string description for the given error number.
@@ -118,33 +121,6 @@ pub unsafe fn error_string(errno: i32, buf: &mut [i8]) -> i32 {
strerror_r(errno as c_int, p as *mut c_char, buf.len()) as i32
}
-pub unsafe fn memchr(s: *const u8, c: u8, n: usize) -> *const u8 {
- let mut ret = ptr::null();
- let mut p = s;
- for _ in 0..n {
- if *p == c {
- ret = p;
- break;
- }
- p = p.offset(1);
- }
- ret
-}
-
-pub unsafe fn memrchr(s: *const u8, c: u8, n: usize) -> *const u8 {
- if n == 0 { return ptr::null(); }
- let mut ret = ptr::null();
- let mut p: *const u8 = (s as usize + (n - 1)) as *const u8;
- for _ in 0..n {
- if *p == c {
- ret = p;
- break;
- }
- p = p.offset(-1);
- }
- ret
-}
-
// intentionally not public, only used for fd_set
cfg_if! {
if #[cfg(target_pointer_width = "32")] {
@@ -193,8 +169,8 @@ pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = ptr::null_mut();
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = ptr::null_mut();
pub const PTHREAD_ONCE_INIT: pthread_once_t = pthread_once_t {
state: PTHREAD_NEEDS_INIT,
- mutex: PTHREAD_MUTEX_INITIALIZER
- };
+ mutex: PTHREAD_MUTEX_INITIALIZER,
+};
#[derive(Copy, Clone, Debug)]
pub enum DIR {}
@@ -271,7 +247,6 @@ s! {
pub sin6_addr: in6_addr,
pub sin6_scope_id: u32,
}
-
pub struct sockaddr_un {
pub sun_family: sa_family_t,
pub sun_path: [c_char; 108],
@@ -761,7 +736,6 @@ pub const _IOLBF: c_int = 1;
pub const FILENAME_MAX: c_uint = 4096;
pub const FOPEN_MAX: c_uint = 16;
-
pub const IFF_UP: c_int = 0x1;
pub const IFF_BROADCAST: c_int = 0x2;
pub const IFF_DEBUG: c_int = 0x4;
@@ -1003,6 +977,16 @@ pub const EAI_SOCKTYPE: c_int = -7;
pub const EAI_SERVICE: c_int = -8;
pub const EAI_MEMORY: c_int = -10;
pub const EAI_OVERFLOW: c_int = -12;
+pub const EAI_SYSTEM: c_int = -11;
+
+pub const EAI_NODATA: c_int = -5;
+pub const EAI_ADDRFAMILY: c_int = -9;
+pub const EAI_INPROGRESS: c_int = -100;
+pub const EAI_CANCELED: c_int = -101;
+pub const EAI_NOTCANCELED: c_int = -102;
+pub const EAI_ALLDONE: c_int = -103;
+pub const EAI_INTR: c_int = -104;
+pub const EAI_IDN_ENCODE: c_int = -105;
pub const NI_NUMERICHOST: c_int = 1;
pub const NI_NUMERICSERV: c_int = 2;
@@ -1014,8 +998,6 @@ pub const SYNC_FILE_RANGE_WAIT_BEFORE: c_uint = 1;
pub const SYNC_FILE_RANGE_WRITE: c_uint = 2;
pub const SYNC_FILE_RANGE_WAIT_AFTER: c_uint = 4;
-pub const EAI_SYSTEM: c_int = -11;
-
pub const AIO_CANCELED: c_int = 0;
pub const AIO_NOTCANCELED: c_int = 1;
pub const AIO_ALLDONE: c_int = 2;
@@ -1257,141 +1239,141 @@ pub const _SC_THREAD_ROBUST_PRIO_PROTECT: c_int = 248;
pub const CPU_SETSIZE: c_int = 0x400;
-pub const EPERM: int32_t = 1;
-pub const ENOENT: int32_t = 2;
-pub const ESRCH: int32_t = 3;
-pub const EINTR: int32_t = 4;
-pub const EIO: int32_t = 5;
-pub const ENXIO: int32_t = 6;
-pub const E2BIG: int32_t = 7;
-pub const ENOEXEC: int32_t = 8;
-pub const EBADF: int32_t = 9;
-pub const ECHILD: int32_t = 10;
-pub const EAGAIN: int32_t = 11;
-pub const ENOMEM: int32_t = 12;
-pub const EACCES: int32_t = 13;
-pub const EFAULT: int32_t = 14;
-pub const ENOTBLK: int32_t = 15;
-pub const EBUSY: int32_t = 16;
-pub const EEXIST: int32_t = 17;
-pub const EXDEV: int32_t = 18;
-pub const ENODEV: int32_t = 19;
-pub const ENOTDIR: int32_t = 20;
-pub const EISDIR: int32_t = 21;
-pub const EINVAL: int32_t = 22;
-pub const ENFILE: int32_t = 23;
-pub const EMFILE: int32_t = 24;
-pub const ENOTTY: int32_t = 25;
-pub const ETXTBSY: int32_t = 26;
-pub const EFBIG: int32_t = 27;
-pub const ENOSPC: int32_t = 28;
-pub const ESPIPE: int32_t = 29;
-pub const EROFS: int32_t = 30;
-pub const EMLINK: int32_t = 31;
-pub const EPIPE: int32_t = 32;
-pub const EDOM: int32_t = 33;
-pub const ERANGE: int32_t = 34;
-pub const EDEADLK: int32_t = 35;
-pub const ENAMETOOLONG: int32_t = 36;
-pub const ENOLCK: int32_t = 37;
-pub const ENOSYS: int32_t = 38;
-pub const ENOTEMPTY: int32_t = 39;
-pub const ELOOP: int32_t = 40;
-pub const EWOULDBLOCK: int32_t = EAGAIN;
-pub const ENOMSG: int32_t = 42;
-pub const EIDRM: int32_t = 43;
-pub const ECHRNG: int32_t = 44;
-pub const EL2NSYNC: int32_t = 45;
-pub const EL3HLT: int32_t = 46;
-pub const EL3RST: int32_t = 47;
-pub const ELNRNG: int32_t = 48;
-pub const EUNATCH: int32_t = 49;
-pub const ENOCSI: int32_t = 50;
-pub const EL2HLT: int32_t = 51;
-pub const EBADE: int32_t = 52;
-pub const EBADR: int32_t = 53;
-pub const EXFULL: int32_t = 54;
-pub const ENOANO: int32_t = 55;
-pub const EBADRQC: int32_t = 56;
-pub const EBADSLT: int32_t = 57;
-pub const EDEADLOCK: int32_t = EDEADLK;
-pub const EBFONT: int32_t = 59;
-pub const ENOSTR: int32_t = 60;
-pub const ENODATA: int32_t = 61;
-pub const ETIME: int32_t = 62;
-pub const ENOSR: int32_t = 63;
-pub const ENONET: int32_t = 64;
-pub const ENOPKG: int32_t = 65;
-pub const EREMOTE: int32_t = 66;
-pub const ENOLINK: int32_t = 67;
-pub const EADV: int32_t = 68;
-pub const ESRMNT: int32_t = 69;
-pub const ECOMM: int32_t = 70;
-pub const EPROTO: int32_t = 71;
-pub const EMULTIHOP: int32_t = 72;
-pub const EDOTDOT: int32_t = 73;
-pub const EBADMSG: int32_t = 74;
-pub const EOVERFLOW: int32_t = 75;
-pub const ENOTUNIQ: int32_t = 76;
-pub const EBADFD: int32_t = 77;
-pub const EREMCHG: int32_t = 78;
-pub const ELIBACC: int32_t = 79;
-pub const ELIBBAD: int32_t = 80;
-pub const ELIBSCN: int32_t = 81;
-pub const ELIBMAX: int32_t = 82;
-pub const ELIBEXEC: int32_t = 83;
-pub const EILSEQ: int32_t = 84;
-pub const ERESTART: int32_t = 85;
-pub const ESTRPIPE: int32_t = 86;
-pub const EUSERS: int32_t = 87;
-pub const ENOTSOCK: int32_t = 88;
-pub const EDESTADDRREQ: int32_t = 89;
-pub const EMSGSIZE: int32_t = 90;
-pub const EPROTOTYPE: int32_t = 91;
-pub const ENOPROTOOPT: int32_t = 92;
-pub const EPROTONOSUPPORT: int32_t = 93;
-pub const ESOCKTNOSUPPORT: int32_t = 94;
-pub const EOPNOTSUPP: int32_t = 95;
-pub const EPFNOSUPPORT: int32_t = 96;
-pub const EAFNOSUPPORT: int32_t = 97;
-pub const EADDRINUSE: int32_t = 98;
-pub const EADDRNOTAVAIL: int32_t = 99;
-pub const ENETDOWN: int32_t = 100;
-pub const ENETUNREACH: int32_t = 101;
-pub const ENETRESET: int32_t = 102;
-pub const ECONNABORTED: int32_t = 103;
-pub const ECONNRESET: int32_t = 104;
-pub const ENOBUFS: int32_t = 105;
-pub const EISCONN: int32_t = 106;
-pub const ENOTCONN: int32_t = 107;
-pub const ESHUTDOWN: int32_t = 108;
-pub const ETOOMANYREFS: int32_t = 109;
-pub const ETIMEDOUT: int32_t = 110;
-pub const ECONNREFUSED: int32_t = 111;
-pub const EHOSTDOWN: int32_t = 112;
-pub const EHOSTUNREACH: int32_t = 113;
-pub const EALREADY: int32_t = 114;
-pub const EINPROGRESS: int32_t = 115;
-pub const ESTALE: int32_t = 116;
-pub const EUCLEAN: int32_t = 117;
-pub const ENOTNAM: int32_t = 118;
-pub const ENAVAIL: int32_t = 119;
-pub const EISNAM: int32_t = 120;
-pub const EREMOTEIO: int32_t = 121;
-pub const EDQUOT: int32_t = 122;
-pub const ENOMEDIUM: int32_t = 123;
-pub const EMEDIUMTYPE: int32_t = 124;
-pub const ECANCELED: int32_t = 125;
-pub const ENOKEY: int32_t = 126;
-pub const EKEYEXPIRED: int32_t = 127;
-pub const EKEYREVOKED: int32_t = 128;
-pub const EKEYREJECTED: int32_t = 129;
-pub const EOWNERDEAD: int32_t = 130;
-pub const ENOTRECOVERABLE: int32_t = 131;
-pub const ERFKILL: int32_t = 132;
-pub const EHWPOISON: int32_t = 133;
-pub const ENOTSUP: int32_t = EOPNOTSUPP;
-pub const ESGX: int32_t = 0x0000_FFFF;
+pub const EPERM: int32_t = 1;
+pub const ENOENT: int32_t = 2;
+pub const ESRCH: int32_t = 3;
+pub const EINTR: int32_t = 4;
+pub const EIO: int32_t = 5;
+pub const ENXIO: int32_t = 6;
+pub const E2BIG: int32_t = 7;
+pub const ENOEXEC: int32_t = 8;
+pub const EBADF: int32_t = 9;
+pub const ECHILD: int32_t = 10;
+pub const EAGAIN: int32_t = 11;
+pub const ENOMEM: int32_t = 12;
+pub const EACCES: int32_t = 13;
+pub const EFAULT: int32_t = 14;
+pub const ENOTBLK: int32_t = 15;
+pub const EBUSY: int32_t = 16;
+pub const EEXIST: int32_t = 17;
+pub const EXDEV: int32_t = 18;
+pub const ENODEV: int32_t = 19;
+pub const ENOTDIR: int32_t = 20;
+pub const EISDIR: int32_t = 21;
+pub const EINVAL: int32_t = 22;
+pub const ENFILE: int32_t = 23;
+pub const EMFILE: int32_t = 24;
+pub const ENOTTY: int32_t = 25;
+pub const ETXTBSY: int32_t = 26;
+pub const EFBIG: int32_t = 27;
+pub const ENOSPC: int32_t = 28;
+pub const ESPIPE: int32_t = 29;
+pub const EROFS: int32_t = 30;
+pub const EMLINK: int32_t = 31;
+pub const EPIPE: int32_t = 32;
+pub const EDOM: int32_t = 33;
+pub const ERANGE: int32_t = 34;
+pub const EDEADLK: int32_t = 35;
+pub const ENAMETOOLONG: int32_t = 36;
+pub const ENOLCK: int32_t = 37;
+pub const ENOSYS: int32_t = 38;
+pub const ENOTEMPTY: int32_t = 39;
+pub const ELOOP: int32_t = 40;
+pub const EWOULDBLOCK: int32_t = EAGAIN;
+pub const ENOMSG: int32_t = 42;
+pub const EIDRM: int32_t = 43;
+pub const ECHRNG: int32_t = 44;
+pub const EL2NSYNC: int32_t = 45;
+pub const EL3HLT: int32_t = 46;
+pub const EL3RST: int32_t = 47;
+pub const ELNRNG: int32_t = 48;
+pub const EUNATCH: int32_t = 49;
+pub const ENOCSI: int32_t = 50;
+pub const EL2HLT: int32_t = 51;
+pub const EBADE: int32_t = 52;
+pub const EBADR: int32_t = 53;
+pub const EXFULL: int32_t = 54;
+pub const ENOANO: int32_t = 55;
+pub const EBADRQC: int32_t = 56;
+pub const EBADSLT: int32_t = 57;
+pub const EDEADLOCK: int32_t = EDEADLK;
+pub const EBFONT: int32_t = 59;
+pub const ENOSTR: int32_t = 60;
+pub const ENODATA: int32_t = 61;
+pub const ETIME: int32_t = 62;
+pub const ENOSR: int32_t = 63;
+pub const ENONET: int32_t = 64;
+pub const ENOPKG: int32_t = 65;
+pub const EREMOTE: int32_t = 66;
+pub const ENOLINK: int32_t = 67;
+pub const EADV: int32_t = 68;
+pub const ESRMNT: int32_t = 69;
+pub const ECOMM: int32_t = 70;
+pub const EPROTO: int32_t = 71;
+pub const EMULTIHOP: int32_t = 72;
+pub const EDOTDOT: int32_t = 73;
+pub const EBADMSG: int32_t = 74;
+pub const EOVERFLOW: int32_t = 75;
+pub const ENOTUNIQ: int32_t = 76;
+pub const EBADFD: int32_t = 77;
+pub const EREMCHG: int32_t = 78;
+pub const ELIBACC: int32_t = 79;
+pub const ELIBBAD: int32_t = 80;
+pub const ELIBSCN: int32_t = 81;
+pub const ELIBMAX: int32_t = 82;
+pub const ELIBEXEC: int32_t = 83;
+pub const EILSEQ: int32_t = 84;
+pub const ERESTART: int32_t = 85;
+pub const ESTRPIPE: int32_t = 86;
+pub const EUSERS: int32_t = 87;
+pub const ENOTSOCK: int32_t = 88;
+pub const EDESTADDRREQ: int32_t = 89;
+pub const EMSGSIZE: int32_t = 90;
+pub const EPROTOTYPE: int32_t = 91;
+pub const ENOPROTOOPT: int32_t = 92;
+pub const EPROTONOSUPPORT: int32_t = 93;
+pub const ESOCKTNOSUPPORT: int32_t = 94;
+pub const EOPNOTSUPP: int32_t = 95;
+pub const EPFNOSUPPORT: int32_t = 96;
+pub const EAFNOSUPPORT: int32_t = 97;
+pub const EADDRINUSE: int32_t = 98;
+pub const EADDRNOTAVAIL: int32_t = 99;
+pub const ENETDOWN: int32_t = 100;
+pub const ENETUNREACH: int32_t = 101;
+pub const ENETRESET: int32_t = 102;
+pub const ECONNABORTED: int32_t = 103;
+pub const ECONNRESET: int32_t = 104;
+pub const ENOBUFS: int32_t = 105;
+pub const EISCONN: int32_t = 106;
+pub const ENOTCONN: int32_t = 107;
+pub const ESHUTDOWN: int32_t = 108;
+pub const ETOOMANYREFS: int32_t = 109;
+pub const ETIMEDOUT: int32_t = 110;
+pub const ECONNREFUSED: int32_t = 111;
+pub const EHOSTDOWN: int32_t = 112;
+pub const EHOSTUNREACH: int32_t = 113;
+pub const EALREADY: int32_t = 114;
+pub const EINPROGRESS: int32_t = 115;
+pub const ESTALE: int32_t = 116;
+pub const EUCLEAN: int32_t = 117;
+pub const ENOTNAM: int32_t = 118;
+pub const ENAVAIL: int32_t = 119;
+pub const EISNAM: int32_t = 120;
+pub const EREMOTEIO: int32_t = 121;
+pub const EDQUOT: int32_t = 122;
+pub const ENOMEDIUM: int32_t = 123;
+pub const EMEDIUMTYPE: int32_t = 124;
+pub const ECANCELED: int32_t = 125;
+pub const ENOKEY: int32_t = 126;
+pub const EKEYEXPIRED: int32_t = 127;
+pub const EKEYREVOKED: int32_t = 128;
+pub const EKEYREJECTED: int32_t = 129;
+pub const EOWNERDEAD: int32_t = 130;
+pub const ENOTRECOVERABLE: int32_t = 131;
+pub const ERFKILL: int32_t = 132;
+pub const EHWPOISON: int32_t = 133;
+pub const ENOTSUP: int32_t = EOPNOTSUPP;
+pub const ESGX: int32_t = 0x0000_FFFF;
pub const SA_NODEFER: c_int = 0x40000000;
pub const SA_RESETHAND: c_int = 0x80000000;
@@ -1440,14 +1422,14 @@ pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () {
let fd = fd as usize;
let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
(*set).fds_bits[fd / size] &= !(1 << (fd % size));
- return
+ return;
}
#[inline]
pub unsafe fn FD_ISSET(fd: c_int, set: *mut fd_set) -> bool {
let fd = fd as usize;
let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
- return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
+ return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0;
}
#[inline]
@@ -1455,7 +1437,7 @@ pub unsafe fn FD_SET(fd: c_int, set: *mut fd_set) -> () {
let fd = fd as usize;
let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
(*set).fds_bits[fd / size] |= 1 << (fd % size);
- return
+ return;
}
#[inline]
@@ -1474,8 +1456,7 @@ pub unsafe fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () {
#[inline]
pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
- let size_in_bits
- = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+ let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
cpuset.bits[idx] |= 1 << offset;
()
@@ -1483,8 +1464,7 @@ pub unsafe fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
#[inline]
pub unsafe fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
- let size_in_bits
- = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+ let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
cpuset.bits[idx] &= !(1 << offset);
()
@@ -1509,32 +1489,28 @@ unsafe fn __sigmask(sig: c_int) -> u64 {
#[inline]
unsafe fn __sigword(sig: c_int) -> u64 {
- ((sig - 1) / ((8 * mem::size_of::<u64>()) as i32)) as u64
+ ((sig - 1) / ((8 * mem::size_of::<u64>()) as i32)) as u64
}
#[inline]
unsafe fn __sigaddset(set: *mut sigset_t, sig: c_int) {
- let mask: u64 = __sigmask (sig);
- let word: u64 = __sigword (sig);
+ let mask: u64 = __sigmask(sig);
+ let word: u64 = __sigword(sig);
(*set).__val[word as usize] |= mask;
}
#[inline]
unsafe fn __sigdelset(set: *mut sigset_t, sig: c_int) {
- let mask: u64 = __sigmask (sig);
- let word: u64 = __sigword (sig);
+ let mask: u64 = __sigmask(sig);
+ let word: u64 = __sigword(sig);
(*set).__val[word as usize] &= !mask;
}
#[inline]
unsafe fn __sigismember(set: *const sigset_t, sig: c_int) -> c_int {
- let mask: u64 = __sigmask (sig);
- let word: u64 = __sigword (sig);
- let val = if mask != 0 {
- 1
- } else {
- 0
- };
+ let mask: u64 = __sigmask(sig);
+ let word: u64 = __sigword(sig);
+ let val = if mask != 0 { 1 } else { 0 };
((*set).__val[word as usize] & val) as c_int
}
@@ -1543,7 +1519,7 @@ pub unsafe fn sigemptyset(set: *mut sigset_t) -> c_int {
set_errno(EINVAL);
return -1;
}
- ptr::write_bytes(set as * mut sigset_t, 0, 1);
+ ptr::write_bytes(set as *mut sigset_t, 0, 1);
0
}
@@ -1582,4 +1558,169 @@ pub unsafe fn sigismember(set: *const sigset_t, signum: c_int) -> c_int {
__sigismember(set, signum)
}
+pub const DIRENT64_NAME_OFFSET: usize = 20;
+
+#[macro_export]
+macro_rules! align8 {
+ ($v:expr) => {
+ (($v + 7) & (!7))
+ };
+}
+
+pub enum PolledOk {
+ TimeLimitExpired,
+ ReadyDescsCount(usize),
+}
+
+#[derive(Debug)]
+pub enum OCallError {
+ SgxError(sgx_types::sgx_status_t),
+ OsError(i32),
+ GaiError(i32),
+ CustomError(&'static str),
+}
+
+impl OCallError {
+ fn from_sgx_error(errno: sgx_types::sgx_status_t) -> Self {
+ OCallError::SgxError(errno)
+ }
+
+ fn from_os_error(errno: i32) -> Self {
+ set_errno(errno);
+ OCallError::OsError(errno)
+ }
+
+ fn from_gai_error(err: i32) -> Self {
+ OCallError::GaiError(err)
+ }
+
+ fn from_custom_error(err: &'static str) -> Self {
+ OCallError::CustomError(err)
+ }
+
+ pub fn equal_to_os_error(&self, other: i32) -> bool {
+ match self {
+ OCallError::OsError(e) if *e == other => true,
+ _ => false,
+ }
+ }
+}
+
+pub type OCallResult<T> = Result<T, OCallError>;
+
+#[macro_export]
+macro_rules! as_u8_slice {
+ ($p:expr, $len:expr) => {
+ core::slice::from_raw_parts($p as *const _ as *const u8, $len)
+ };
+}
+
+pub enum SockAddr {
+ IN4(sockaddr_in),
+ IN6(sockaddr_in6),
+ UN((sockaddr_un, socklen_t)),
+}
+
+impl SockAddr {
+ pub fn as_bytes(&self) -> &[u8] {
+ unsafe {
+ match self {
+ SockAddr::IN4(addr) => as_u8_slice!(addr, core::mem::size_of::<sockaddr_in>()),
+ SockAddr::IN6(addr) => as_u8_slice!(addr, core::mem::size_of::<sockaddr_in6>()),
+ SockAddr::UN((addr, len)) => as_u8_slice!(addr, *len as usize),
+ }
+ }
+ }
+
+ pub unsafe fn try_from_storage(
+ storage: sockaddr_storage,
+ len_out: socklen_t,
+ ) -> OCallResult<Self> {
+ let addr = match storage.ss_family as i32 {
+ AF_INET => {
+ ensure!(
+ len_out as usize == mem::size_of::<sockaddr_in>(),
+ ecust!("Malformed addr_len")
+ );
+ let sockaddr: *const sockaddr_in = mem::transmute(&storage);
+ SockAddr::IN4(*sockaddr)
+ }
+ AF_INET6 => {
+ ensure!(
+ len_out as usize == mem::size_of::<sockaddr_in6>(),
+ ecust!("Malformed addr_len")
+ );
+ let sockaddr: *const sockaddr_in6 = mem::transmute(&storage);
+ SockAddr::IN6(*sockaddr)
+ }
+ AF_UNIX => {
+ ensure!(
+ len_out as usize <= mem::size_of::<sockaddr_un>(),
+ ecust!("Malformed addr_len")
+ );
+ let sockaddr: *const sockaddr_un = mem::transmute(&storage);
+ SockAddr::UN((*sockaddr, len_out))
+ }
+ _ => bail!(ecust!("Unsupported family info")),
+ };
+
+ Ok(addr)
+ }
+}
+
+pub struct AddrInfoHints {
+ pub socktype: i32,
+ pub protocol: i32,
+ pub family: i32,
+ pub flags: i32,
+}
+
+impl AddrInfoHints {
+ fn to_addrinfo(&self) -> addrinfo {
+ let mut addrinfo: addrinfo = unsafe { mem::zeroed() };
+ addrinfo.ai_socktype = self.socktype;
+ addrinfo.ai_protocol = self.protocol;
+ addrinfo.ai_family = self.family;
+ addrinfo.ai_flags = self.flags;
+ addrinfo
+ }
+}
+
+impl Default for AddrInfoHints {
+ fn default() -> Self {
+ AddrInfoHints {
+ socktype: 0,
+ protocol: 0,
+ family: AF_UNSPEC,
+ flags: 0,
+ }
+ }
+}
+
+pub fn gai_error_str(errcode: c_int) -> &'static str {
+ match errcode {
+ EAI_BADFLAGS => "Bad value for ai_flags",
+ EAI_NONAME => "Name or service not known",
+ EAI_AGAIN => "Temporary failure in name resolution",
+ EAI_FAIL => "Non-recoverable failure in name resolution",
+ EAI_FAMILY => "ai_family not supported",
+ EAI_SOCKTYPE => "ai_socktype not supported",
+ EAI_SERVICE => "Servname not supported for ai_socktype",
+ EAI_MEMORY => "Memory allocation failure",
+ EAI_SYSTEM => "System error",
+ EAI_OVERFLOW => "Argument buffer overflow",
+
+ EAI_NODATA => "No address associated with hostname",
+ EAI_ADDRFAMILY => "Address family for hostname not supported",
+ EAI_INPROGRESS => "Processing request in progress",
+ EAI_CANCELED => "Request canceled",
+ EAI_NOTCANCELED => "Request not canceled",
+ EAI_ALLDONE => "All requests done",
+ EAI_INTR => "Interrupted by a signal",
+ EAI_IDN_ENCODE => "Parameter string not correctly encoded",
+
+ _ => "Unknown gai_error_code",
+ }
+}
+
pub mod ocall;
diff --git a/sgx_libc/src/linux/x86_64/ocall.rs b/sgx_libc/src/linux/x86_64/ocall.rs
index 650845a..4d36659 100644
--- a/sgx_libc/src/linux/x86_64/ocall.rs
+++ b/sgx_libc/src/linux/x86_64/ocall.rs
@@ -15,2910 +15,2230 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_types::*;
use super::*;
-use alloc::slice;
+use crate::c_str::CStr;
+use crate::memchr;
use alloc::vec::Vec;
-use alloc::boxed::Box;
-use core::ptr;
+use core::cmp;
use core::mem;
+use core::ptr;
+use sgx_types::*;
-const MAX_OCALL_ALLOC_SIZE: size_t = 0x4000; //16K
extern "C" {
// memory
- pub fn u_malloc_ocall(result: *mut *mut c_void, error: *mut c_int, size: size_t) -> sgx_status_t;
+ pub fn u_malloc_ocall(
+ result: *mut *mut c_void,
+ error: *mut c_int,
+ size: size_t,
+ ) -> sgx_status_t;
pub fn u_free_ocall(p: *mut c_void) -> sgx_status_t;
- pub fn u_mmap_ocall(result: *mut *mut c_void,
- error: *mut c_int,
- start: *mut c_void,
- length: size_t,
- prot: c_int,
- flags: c_int,
- fd: c_int,
- offset: off_t) -> sgx_status_t;
- pub fn u_munmap_ocall(result: *mut c_int,
- error: *mut c_int,
- start: *mut c_void,
- length: size_t) -> sgx_status_t;
- pub fn u_msync_ocall(result: *mut c_int,
- error: *mut c_int,
- addr: *mut c_void,
- length: size_t,
- flags: c_int) -> sgx_status_t;
-
- pub fn u_mprotect_ocall(result: *mut c_int,
- error: *mut c_int,
- addr: *mut c_void,
- length: size_t,
- prot: c_int) -> sgx_status_t;
+ pub fn u_mmap_ocall(
+ result: *mut *mut c_void,
+ error: *mut c_int,
+ start: *mut c_void,
+ length: size_t,
+ prot: c_int,
+ flags: c_int,
+ fd: c_int,
+ offset: off_t,
+ ) -> sgx_status_t;
+ pub fn u_munmap_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ start: *mut c_void,
+ length: size_t,
+ ) -> sgx_status_t;
+ pub fn u_msync_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ addr: *mut c_void,
+ length: size_t,
+ flags: c_int,
+ ) -> sgx_status_t;
+
+ pub fn u_mprotect_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ addr: *mut c_void,
+ length: size_t,
+ prot: c_int,
+ ) -> sgx_status_t;
// env
pub fn u_getuid_ocall(result: *mut uid_t) -> sgx_status_t;
- pub fn u_environ_ocall(result: *mut *const *const c_char) -> sgx_status_t;
- pub fn u_getenv_ocall(result: *mut *const c_char,
- name: *const c_char) -> sgx_status_t;
- pub fn u_setenv_ocall(result: *mut c_int,
- error: *mut c_int,
- name: *const c_char,
- value: *const c_char,
- overwrite: c_int) -> sgx_status_t;
- pub fn u_unsetenv_ocall(result: *mut c_int,
- error: *mut c_int,
- name: *const c_char) -> sgx_status_t;
- pub fn u_getcwd_ocall(result: *mut *mut c_char,
- error: *mut c_int,
- buf: *mut c_char,
- size: size_t) -> sgx_status_t;
- pub fn u_chdir_ocall(result: *mut c_int, error: *mut c_int, dir: *const c_char) -> sgx_status_t;
- pub fn u_getpwuid_r_ocall(result: *mut c_int,
- uid: uid_t,
- pwd: *mut passwd,
- buf: *mut c_char,
- buflen: size_t,
- passwd_result: *mut *mut passwd) -> sgx_status_t;
+ pub fn u_getenv_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ name: *const c_char,
+ buf: *mut c_char,
+ size: size_t,
+ isset: *mut c_int,
+ ) -> sgx_status_t;
+ pub fn u_getcwd_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ buf: *mut c_char,
+ size: size_t,
+ ) -> sgx_status_t;
+ pub fn u_chdir_ocall(result: *mut c_int, error: *mut c_int, dir: *const c_char)
+ -> sgx_status_t;
// file
- pub fn u_open_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- flags: c_int) -> sgx_status_t;
- pub fn u_open64_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- oflag: c_int,
- mode: c_int) -> sgx_status_t;
- pub fn u_fstat_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int,
- buf: *mut stat) -> sgx_status_t;
- pub fn u_fstat64_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int,
- buf: *mut stat64) -> sgx_status_t;
- pub fn u_stat_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- buf: *mut stat) -> sgx_status_t;
- pub fn u_stat64_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- buf: *mut stat64) -> sgx_status_t;
- pub fn u_lstat_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- buf: *mut stat) -> sgx_status_t;
- pub fn u_lstat64_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- buf: *mut stat64) -> sgx_status_t;
- pub fn u_lseek_ocall(result: *mut off_t,
- error: *mut c_int,
- fd: c_int,
- offset: off_t,
- whence: c_int) -> sgx_status_t;
- pub fn u_lseek64_ocall(result: *mut off64_t,
- error: *mut c_int,
- fd: c_int,
- offset: off64_t,
- whence: c_int) -> sgx_status_t;
- pub fn u_ftruncate_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int,
- length: off_t) -> sgx_status_t;
- pub fn u_ftruncate64_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int,
- length: off64_t) -> sgx_status_t;
- pub fn u_truncate_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- length: off_t) -> sgx_status_t;
- pub fn u_truncate64_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- length: off64_t) -> sgx_status_t;
- pub fn u_fsync_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int) -> sgx_status_t;
- pub fn u_fdatasync_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int) -> sgx_status_t;
- pub fn u_fchmod_ocall(result: *mut c_int,
- error: *mut c_int,
- fd: c_int,
- mode: mode_t) -> sgx_status_t;
- pub fn u_unlink_ocall(result: *mut c_int,
- error: *mut c_int,
- pathname: *const c_char) -> sgx_status_t;
- pub fn u_link_ocall(result: *mut c_int,
- error: *mut c_int,
- oldpath: *const c_char,
- newpath: *const c_char) -> sgx_status_t;
- pub fn u_rename_ocall(result: *mut c_int,
- error: *mut c_int,
- oldpath: *const c_char,
- newpath: *const c_char) -> sgx_status_t;
- pub fn u_chmod_ocall(result: *mut c_int,
- error: *mut c_int,
- path: *const c_char,
- mode: mode_t) -> sgx_status_t;
- pub fn u_readlink_ocall(result: *mut ssize_t,
- error: *mut c_int,
- path: *const c_char,
- buf: *mut c_char,
- bufsz: size_t) -> sgx_status_t;
- pub fn u_symlink_ocall(result: *mut c_int,
- error: *mut c_int,
- path1: *const c_char,
- path2: *const c_char) -> sgx_status_t;
- pub fn u_realpath_ocall(result: *mut *mut c_char,
- error: *mut c_int,
- pathname: *const c_char) -> sgx_status_t;
- pub fn u_mkdir_ocall(result: *mut c_int,
- error: *mut c_int,
- pathname: *const c_char,
- mode: mode_t) -> sgx_status_t;
- pub fn u_rmdir_ocall(result: *mut c_int,
- error: *mut c_int,
- pathname: *const c_char) -> sgx_status_t;
- pub fn u_opendir_ocall(result: *mut *mut DIR,
- error: *mut c_int,
- pathname: *const c_char) -> sgx_status_t;
- pub fn u_readdir64_r_ocall(result: *mut c_int,
- dirp: *mut DIR,
- entry: *mut dirent64,
- dirresult: *mut *mut dirent64) -> sgx_status_t;
- pub fn u_closedir_ocall(result: *mut c_int,
- error: *mut c_int,
- dirp: *mut DIR) -> sgx_status_t;
- pub fn u_dirfd_ocall(result: *mut c_int,
- error: *mut c_int,
- dirp: *mut DIR) -> sgx_status_t;
- pub fn u_fstatat64_ocall(result: *mut c_int,
- error: *mut c_int,
- dirfd: c_int,
- pathname: *const c_char,
- buf: *mut stat64,
- flags: c_int) -> sgx_status_t;
+ pub fn u_open_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_open64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ oflag: c_int,
+ mode: c_int,
+ ) -> sgx_status_t;
+ pub fn u_fstat_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fd: c_int,
+ buf: *mut stat,
+ ) -> sgx_status_t;
+ pub fn u_fstat64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fd: c_int,
+ buf: *mut stat64,
+ ) -> sgx_status_t;
+ pub fn u_stat_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ buf: *mut stat,
+ ) -> sgx_status_t;
+ pub fn u_stat64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ buf: *mut stat64,
+ ) -> sgx_status_t;
+ pub fn u_lstat_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ buf: *mut stat,
+ ) -> sgx_status_t;
+ pub fn u_lstat64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ buf: *mut stat64,
+ ) -> sgx_status_t;
+ pub fn u_lseek_ocall(
+ result: *mut off_t,
+ error: *mut c_int,
+ fd: c_int,
+ offset: off_t,
+ whence: c_int,
+ ) -> sgx_status_t;
+ pub fn u_lseek64_ocall(
+ result: *mut off64_t,
+ error: *mut c_int,
+ fd: c_int,
+ offset: off64_t,
+ whence: c_int,
+ ) -> sgx_status_t;
+ pub fn u_ftruncate_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fd: c_int,
+ length: off_t,
+ ) -> sgx_status_t;
+ pub fn u_ftruncate64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fd: c_int,
+ length: off64_t,
+ ) -> sgx_status_t;
+ pub fn u_truncate_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ length: off_t,
+ ) -> sgx_status_t;
+ pub fn u_truncate64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ length: off64_t,
+ ) -> sgx_status_t;
+ pub fn u_fsync_ocall(result: *mut c_int, error: *mut c_int, fd: c_int) -> sgx_status_t;
+ pub fn u_fdatasync_ocall(result: *mut c_int, error: *mut c_int, fd: c_int) -> sgx_status_t;
+ pub fn u_fchmod_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fd: c_int,
+ mode: mode_t,
+ ) -> sgx_status_t;
+ pub fn u_unlink_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pathname: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_link_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ oldpath: *const c_char,
+ newpath: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_rename_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ oldpath: *const c_char,
+ newpath: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_chmod_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path: *const c_char,
+ mode: mode_t,
+ ) -> sgx_status_t;
+ pub fn u_readlink_ocall(
+ result: *mut ssize_t,
+ error: *mut c_int,
+ path: *const c_char,
+ buf: *mut c_char,
+ bufsz: size_t,
+ ) -> sgx_status_t;
+ pub fn u_symlink_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ path1: *const c_char,
+ path2: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_realpath_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pathname: *const c_char,
+ resolved_buf: *mut c_char,
+ bufsz: size_t,
+ ) -> sgx_status_t;
+ pub fn u_mkdir_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pathname: *const c_char,
+ mode: mode_t,
+ ) -> sgx_status_t;
+ pub fn u_rmdir_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pathname: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_opendir_ocall(
+ result: *mut *mut DIR,
+ error: *mut c_int,
+ pathname: *const c_char,
+ ) -> sgx_status_t;
+ pub fn u_readdir64_r_ocall(
+ result: *mut c_int,
+ dirp: *mut DIR,
+ entry: *mut dirent64,
+ eods: *mut c_int,
+ ) -> sgx_status_t;
+ pub fn u_closedir_ocall(result: *mut c_int, error: *mut c_int, dirp: *mut DIR) -> sgx_status_t;
+ pub fn u_dirfd_ocall(result: *mut c_int, error: *mut c_int, dirp: *mut DIR) -> sgx_status_t;
+ pub fn u_fstatat64_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ dirfd: c_int,
+ pathname: *const c_char,
+ buf: *mut stat64,
+ flags: c_int,
+ ) -> sgx_status_t;
// fd
- pub fn u_read_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- buf: *mut c_void,
- count: size_t) -> sgx_status_t;
- pub fn u_pread64_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- buf: *mut c_void,
- count: size_t,
- offset: off64_t) -> sgx_status_t;
- pub fn u_readv_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int) -> sgx_status_t;
- pub fn u_preadv64_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
- offset: off64_t) -> sgx_status_t;
- pub fn u_write_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- buf: *const c_void,
- count: size_t) -> sgx_status_t;
- pub fn u_pwrite64_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- buf: *const c_void,
- count: size_t,
- offset: off64_t) -> sgx_status_t;
- pub fn u_writev_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int) -> sgx_status_t;
- pub fn u_pwritev64_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
- offset: off64_t) -> sgx_status_t;
- pub fn u_fcntl_arg0_ocall(result: *mut c_int,
- errno: *mut c_int,
- fd: c_int,
- cmd: c_int) -> sgx_status_t;
- pub fn u_fcntl_arg1_ocall(result: *mut c_int,
- errno: *mut c_int,
- fd: c_int,
- cmd: c_int,
- arg: c_int) -> sgx_status_t;
- pub fn u_ioctl_arg0_ocall(result: *mut c_int,
- errno: *mut c_int,
- fd: c_int,
- request: c_int) -> sgx_status_t;
- pub fn u_ioctl_arg1_ocall(result: *mut c_int,
- errno: *mut c_int,
- fd: c_int,
- request: c_int,
- arg: *mut c_int) -> sgx_status_t;
- pub fn u_close_ocall(result: *mut c_int,
- errno: *mut c_int,
- fd: c_int) -> sgx_status_t;
+ pub fn u_read_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ fd: c_int,
+ buf: *mut c_void,
+ count: size_t,
+ ) -> sgx_status_t;
+ pub fn u_pread64_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ fd: c_int,
+ buf: *mut c_void,
+ count: size_t,
+ offset: off64_t,
+ ) -> sgx_status_t;
+ pub fn u_write_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ fd: c_int,
+ buf: *const c_void,
+ count: size_t,
+ ) -> sgx_status_t;
+ pub fn u_pwrite64_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ fd: c_int,
+ buf: *const c_void,
+ count: size_t,
+ offset: off64_t,
+ ) -> sgx_status_t;
+ pub fn u_fcntl_arg0_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ fd: c_int,
+ cmd: c_int,
+ ) -> sgx_status_t;
+ pub fn u_fcntl_arg1_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ fd: c_int,
+ cmd: c_int,
+ arg: c_int,
+ ) -> sgx_status_t;
+ pub fn u_ioctl_arg0_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ fd: c_int,
+ request: c_int,
+ ) -> sgx_status_t;
+ pub fn u_ioctl_arg1_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ fd: c_int,
+ request: c_int,
+ arg: *mut c_int,
+ ) -> sgx_status_t;
+ pub fn u_close_ocall(result: *mut c_int, errno: *mut c_int, fd: c_int) -> sgx_status_t;
// time
- pub fn u_clock_gettime_ocall(result: *mut c_int,
- errno: *mut c_int,
- clk_id: clockid_t,
- tp: *mut timespec) -> sgx_status_t;
+ pub fn u_clock_gettime_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ clk_id: clockid_t,
+ tp: *mut timespec,
+ ) -> sgx_status_t;
// socket
- pub fn u_socket_ocall(result: *mut c_int,
- errno: *mut c_int,
- domain: c_int,
- ty: c_int,
- protocol: c_int) -> sgx_status_t;
- pub fn u_socketpair_ocall(result: *mut c_int,
- errno: *mut c_int,
- domain: c_int,
- ty: c_int,
- protocol: c_int,
- sv: *mut c_int) -> sgx_status_t;
- pub fn u_bind_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- address: *const sockaddr,
- addrlen: socklen_t) -> sgx_status_t;
- pub fn u_listen_ocall(result: *mut c_int,
- error: *mut c_int,
- sockfd: c_int,
- backlog: c_int) -> sgx_status_t;
- pub fn u_accept_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- addr: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t) -> sgx_status_t;
- pub fn u_accept4_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- addr: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t,
- flags: c_int) -> sgx_status_t;
- pub fn u_connect_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- address: *const sockaddr,
- addrlen: socklen_t) -> sgx_status_t;
- pub fn u_send_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- sockfd: c_int,
- buf: *const c_void,
- len: size_t,
- flags: c_int) -> sgx_status_t;
- pub fn u_sendto_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- sockfd: c_int,
- buf: *const c_void,
- len: size_t,
- flags: c_int,
- addr: *const sockaddr,
- addrlen: socklen_t) -> sgx_status_t;
- pub fn u_sendmsg_ocall(result: *mut ssize_t,
- error: *mut c_int,
- sockfd: c_int,
- msg: *const msghdr,
- flags: c_int) -> sgx_status_t;
- pub fn u_recv_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- sockfd: c_int,
- buf: *mut c_void,
- len: size_t,
- flags: c_int) -> sgx_status_t;
- pub fn u_recvfrom_ocall(result: *mut ssize_t,
- errno: *mut c_int,
- sockfd: c_int,
- buf: *mut c_void,
- len: size_t,
- flags: c_int,
- addr: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t) -> sgx_status_t;
- pub fn u_recvmsg_ocall(result: *mut ssize_t,
- error: *mut c_int,
- sockfd: c_int,
- msg: *mut msghdr,
- flags: c_int) -> sgx_status_t;
- pub fn u_setsockopt_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- level: c_int,
- optname: c_int,
- optval: *const c_void,
- optlen: socklen_t) -> sgx_status_t;
- pub fn u_getsockopt_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- level: c_int,
- optname: c_int,
- optval: *mut c_void,
- optlen_in: socklen_t,
- optlen_out: *mut socklen_t) -> sgx_status_t;
- pub fn u_getpeername_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- address: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t) -> sgx_status_t;
- pub fn u_getsockname_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- address: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t) -> sgx_status_t;
- pub fn u_shutdown_ocall(result: *mut c_int,
- errno: *mut c_int,
- sockfd: c_int,
- how: c_int) -> sgx_status_t;
+ pub fn u_socket_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ domain: c_int,
+ ty: c_int,
+ protocol: c_int,
+ ) -> sgx_status_t;
+ pub fn u_socketpair_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ domain: c_int,
+ ty: c_int,
+ protocol: c_int,
+ sv: *mut c_int,
+ ) -> sgx_status_t;
+ pub fn u_bind_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ address: *const sockaddr,
+ addrlen: socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_listen_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ sockfd: c_int,
+ backlog: c_int,
+ ) -> sgx_status_t;
+ pub fn u_accept4_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ addr: *mut sockaddr,
+ addrlen_in: socklen_t,
+ addrlen_out: *mut socklen_t,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_connect_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ address: *const sockaddr,
+ addrlen: socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_send_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ sockfd: c_int,
+ buf: *const c_void,
+ len: size_t,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_sendto_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ sockfd: c_int,
+ buf: *const c_void,
+ len: size_t,
+ flags: c_int,
+ addr: *const sockaddr,
+ addrlen: socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_sendmsg_ocall(
+ result: *mut ssize_t,
+ error: *mut c_int,
+ sockfd: c_int,
+ msg: *const msghdr,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_recv_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ sockfd: c_int,
+ buf: *mut c_void,
+ len: size_t,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_recvfrom_ocall(
+ result: *mut ssize_t,
+ errno: *mut c_int,
+ sockfd: c_int,
+ buf: *mut c_void,
+ len: size_t,
+ flags: c_int,
+ addr: *mut sockaddr,
+ addrlen_in: socklen_t,
+ addrlen_out: *mut socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_recvmsg_ocall(
+ result: *mut ssize_t,
+ error: *mut c_int,
+ sockfd: c_int,
+ msg: *mut msghdr,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_setsockopt_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ level: c_int,
+ optname: c_int,
+ optval: *const c_void,
+ optlen: socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_getsockopt_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ level: c_int,
+ optname: c_int,
+ optval: *mut c_void,
+ optlen_in: socklen_t,
+ optlen_out: *mut socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_getpeername_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ address: *mut sockaddr,
+ addrlen_in: socklen_t,
+ addrlen_out: *mut socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_getsockname_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ address: *mut sockaddr,
+ addrlen_in: socklen_t,
+ addrlen_out: *mut socklen_t,
+ ) -> sgx_status_t;
+ pub fn u_shutdown_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ sockfd: c_int,
+ how: c_int,
+ ) -> sgx_status_t;
// net
- pub fn u_getaddrinfo_ocall(result: *mut c_int,
- errno: *mut c_int,
- node: *const c_char,
- service: *const c_char,
- hints: *const addrinfo,
- res: *mut *mut addrinfo) -> sgx_status_t;
- pub fn u_freeaddrinfo_ocall(res: *mut addrinfo) -> sgx_status_t;
- pub fn u_gai_strerror_ocall(result: *mut *const c_char, errcode: c_int) -> sgx_status_t;
+ pub fn u_getaddrinfo_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ node: *const c_char,
+ service: *const c_char,
+ hints: *const addrinfo,
+ entry_size: size_t,
+ buf: *mut u8,
+ bufsz: size_t,
+ out_entry_count: *mut size_t,
+ ) -> sgx_status_t;
// async io
- pub fn u_poll_ocall(result: *mut c_int,
- errno: *mut c_int,
- fds: *mut pollfd,
- nfds: nfds_t,
- timeout: c_int) -> sgx_status_t;
- pub fn u_epoll_create1_ocall(result: *mut c_int,
- error: *mut c_int,
- flags: c_int) -> sgx_status_t;
- pub fn u_epoll_ctl_ocall(result: *mut c_int,
- error: *mut c_int,
- epfd: c_int,
- op: c_int,
- fd: c_int,
- event: *mut epoll_event) -> sgx_status_t;
- pub fn u_epoll_wait_ocall(result: *mut c_int,
- error: *mut c_int,
- epfd: c_int,
- events: *mut epoll_event,
- maxevents: c_int,
- timeout: c_int) -> sgx_status_t;
+ pub fn u_poll_ocall(
+ result: *mut c_int,
+ errno: *mut c_int,
+ fds: *mut pollfd,
+ nfds: nfds_t,
+ timeout: c_int,
+ ) -> sgx_status_t;
+ pub fn u_epoll_create1_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ flags: c_int,
+ ) -> sgx_status_t;
+ pub fn u_epoll_ctl_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ epfd: c_int,
+ op: c_int,
+ fd: c_int,
+ event: *mut epoll_event,
+ ) -> sgx_status_t;
+ pub fn u_epoll_wait_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ epfd: c_int,
+ events: *mut epoll_event,
+ maxevents: c_int,
+ timeout: c_int,
+ ) -> sgx_status_t;
// sys
- pub fn u_sysconf_ocall(result: *mut c_long,
- error: *mut c_int,
- name: c_int) -> sgx_status_t;
- pub fn u_prctl_ocall(result: *mut c_int,
- error: *mut c_int,
- option: c_int,
- arg2: c_ulong,
- arg3: c_ulong,
- arg4: c_ulong,
- arg5: c_ulong) -> sgx_status_t;
- pub fn u_sched_setaffinity_ocall(result: *mut c_int,
- error: *mut c_int,
- pid: pid_t,
- cpusetsize: size_t,
- mask: *const cpu_set_t) -> sgx_status_t;
- pub fn u_sched_getaffinity_ocall(result: *mut c_int,
- error: *mut c_int,
- pid: pid_t,
- cpusetsize: size_t,
- mask: *mut cpu_set_t) -> sgx_status_t;
+ pub fn u_sysconf_ocall(result: *mut c_long, error: *mut c_int, name: c_int) -> sgx_status_t;
+ pub fn u_prctl_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ option: c_int,
+ arg2: c_ulong,
+ arg3: c_ulong,
+ arg4: c_ulong,
+ arg5: c_ulong,
+ ) -> sgx_status_t;
+ pub fn u_sched_setaffinity_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pid: pid_t,
+ cpusetsize: size_t,
+ mask: *const cpu_set_t,
+ ) -> sgx_status_t;
+ pub fn u_sched_getaffinity_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ pid: pid_t,
+ cpusetsize: size_t,
+ mask: *mut cpu_set_t,
+ ) -> sgx_status_t;
// pipe
- pub fn u_pipe_ocall(result: *mut c_int,
- error: *mut c_int,
- fds: *mut c_int) -> sgx_status_t;
- pub fn u_pipe2_ocall(result: *mut c_int,
- error: *mut c_int,
- fds: *mut c_int,
- flags: c_int) -> sgx_status_t;
+ pub fn u_pipe2_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ fds: *mut c_int,
+ flags: c_int,
+ ) -> sgx_status_t;
//thread
- pub fn u_sched_yield_ocall(result: *mut c_int,
- error: *mut c_int) -> sgx_status_t;
- pub fn u_nanosleep_ocall(result: *mut c_int,
- error: *mut c_int,
- rqtp: *const timespec,
- rmtp: *mut timespec) -> sgx_status_t;
+ pub fn u_sched_yield_ocall(result: *mut c_int, error: *mut c_int) -> sgx_status_t;
+ pub fn u_nanosleep_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ rqtp: *const timespec,
+ rmtp: *mut timespec,
+ ) -> sgx_status_t;
//signal
- pub fn u_sigaction_ocall(result: *mut c_int,
- error: *mut c_int,
- signum: c_int,
- act: *const sigaction,
- oldact: *mut sigaction,
- enclave_id: uint64_t) -> sgx_status_t;
- pub fn u_sigprocmask_ocall(result: *mut c_int,
- error: *mut c_int,
- signum: c_int,
- set: *const sigset_t,
- oldset: *mut sigset_t) -> sgx_status_t;
+ pub fn u_sigaction_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ signum: c_int,
+ act: *const sigaction,
+ oldact: *mut sigaction,
+ enclave_id: uint64_t,
+ ) -> sgx_status_t;
+ pub fn u_sigprocmask_ocall(
+ result: *mut c_int,
+ error: *mut c_int,
+ signum: c_int,
+ set: *const sigset_t,
+ oldset: *mut sigset_t,
+ ) -> sgx_status_t;
pub fn u_raise_ocall(result: *mut c_int, signum: c_int) -> sgx_status_t;
//process
pub fn u_getpid_ocall(result: *mut pid_t) -> sgx_status_t;
}
-pub unsafe fn malloc(size: size_t) -> *mut c_void {
- let mut result: *mut c_void = ptr::null_mut();
- let mut error: c_int = 0;
- let status = u_malloc_ocall(&mut result as *mut *mut c_void,
- &mut error as *mut c_int,
- size);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result.is_null() {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = ptr::null_mut();
- }
+pub unsafe fn shrink_to_fit_os_string<T: Into<Vec<u8>>>(buf: T) -> OCallResult<Vec<u8>> {
+ let mut buf = buf.into();
+ if let Some(i) = memchr::memchr(0, &buf) {
+ buf.set_len(i);
+ buf.shrink_to_fit();
+ return Ok(buf);
+ };
+ return Err(ecust!("Malformed Linux OsString Vec: not null terminated"));
+}
- if sgx_is_outside_enclave(result, size) == 0 {
- set_errno(ESGX);
- result = ptr::null_mut();
- }
+pub unsafe fn getuid() -> OCallResult<uid_t> {
+ let mut result: uid_t = 0;
- result
-}
+ let status = u_getuid_ocall(&mut result as *mut uid_t);
-pub unsafe fn free(p: *mut c_void) {
- let _ = u_free_ocall(p);
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ Ok(result)
}
-pub unsafe fn mmap(start: *mut c_void,
- length: size_t,
- prot: c_int,
- flags: c_int,
- fd: c_int,
- offset: off_t) -> *mut c_void {
- let mut result: *mut c_void = ptr::null_mut();
+const MAX_ENV_VALUE_SIZE: usize = 1024;
+pub unsafe fn getenv(name: &CStr) -> OCallResult<Option<Vec<u8>>> {
+ let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_mmap_ocall(&mut result as *mut *mut c_void,
- &mut error as *mut c_int,
- start,
- length,
- prot,
- flags,
- fd,
- offset);
+ let mut isset: c_int = 0;
- if status == sgx_status_t::SGX_SUCCESS {
- if result as isize == -1 {
- set_errno(error);
- }
+ let bufsz = MAX_ENV_VALUE_SIZE;
+ let mut buf = vec![0; bufsz];
+
+ // a) isset is used to indicate the NULL return value of conventional libc::getenv function
+ // b) if isset, a '\0' terminated string is expected in the buf
+ let status = u_getenv_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ name.as_ptr(),
+ buf.as_mut_ptr() as *mut c_char,
+ bufsz,
+ &mut isset as *mut c_int,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ if isset == 1 {
+ let v = shrink_to_fit_os_string(buf)?;
+ Ok(Some(v))
} else {
- set_errno(ESGX);
- result = -1 as isize as *mut c_void;
+ Ok(None)
}
+}
- if sgx_is_outside_enclave(result, length) == 0 {
- set_errno(ESGX);
- result = -1 as isize as *mut c_void;
- }
+pub unsafe fn getcwd() -> OCallResult<Vec<u8>> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let bufsz = PATH_MAX as usize;
+ let mut buf = vec![0; bufsz];
- result
+ let status = u_getcwd_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ buf.as_mut_ptr() as *mut c_char,
+ bufsz,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ shrink_to_fit_os_string(buf)
}
-pub unsafe fn munmap(start: *mut c_void, length: size_t) -> c_int {
+pub unsafe fn chdir(dir: &CStr) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_munmap_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- start,
- length);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_chdir_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ dir.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: c_int) -> c_int {
+pub unsafe fn open(path: &CStr, flags: c_int) -> OCallResult<c_int> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_msync_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- addr,
- length,
- flags);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_open_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ flags,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
}
-pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int {
+pub unsafe fn open64(path: &CStr, oflag: c_int, mode: c_int) -> OCallResult<c_int> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_mprotect_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- addr,
- length,
- prot);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
+ let status = u_open64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ oflag,
+ mode,
+ );
-pub unsafe fn getuid() -> uid_t {
- let mut result: uid_t = 0;
- let status = u_getuid_ocall(&mut result as *mut uid_t);
- if status != sgx_status_t::SGX_SUCCESS {
- set_errno(ESGX);
- result = 0;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
}
-pub unsafe fn environ() -> *const *const c_char {
- let mut result: *const *const c_char = ptr::null();
- let status = u_environ_ocall(&mut result as *mut *const *const c_char);
+pub unsafe fn fstat(fd: c_int, buf: &mut stat) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
- if status != sgx_status_t::SGX_SUCCESS {
- result = ptr::null();
- }
- result
+ let status = u_fstat_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ buf as *mut stat,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn getenv(name: *const c_char) -> *const c_char {
- let mut result: *const c_char = ptr::null();
- let status = u_getenv_ocall(&mut result as *mut *const c_char, name);
+pub unsafe fn fstat64(fd: c_int, buf: &mut stat64) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+
+ let status = u_fstat64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ buf as *mut stat64,
+ );
- if status != sgx_status_t::SGX_SUCCESS {
- result = ptr::null();
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn setenv(name: *const c_char, value: *const c_char, overwrite: c_int) -> c_int {
+pub unsafe fn stat(path: &CStr, buf: &mut stat) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_setenv_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- name,
- value,
- overwrite);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_stat_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ buf as *mut stat,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn unsetenv(name: *const c_char) -> c_int {
+pub unsafe fn stat64(path: &CStr, buf: &mut stat64) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_unsetenv_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- name);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_stat64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ buf as *mut stat64,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
- let mut result: *mut c_char = ptr::null_mut();
+pub unsafe fn lstat(path: &CStr, buf: &mut stat) -> OCallResult<()> {
+ let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_getcwd_ocall(&mut result as *mut *mut c_char, &mut error as *mut c_int, buf, size);
- if status == sgx_status_t::SGX_SUCCESS {
- if result.is_null() {
- set_errno(error);
- } else {
- result = buf;
- }
- } else {
- set_errno(ESGX);
- result = ptr::null_mut();
- }
- result
+
+ let status = u_lstat_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ buf as *mut stat,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn chdir(dir: *const c_char) -> c_int {
+pub unsafe fn lstat64(path: &CStr, buf: &mut stat64) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_chdir_ocall(&mut result as *mut c_int, &mut error as *mut c_int, dir);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_lstat64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ buf as *mut stat64,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn getpwuid_r(uid: uid_t,
- pwd: *mut passwd,
- buf: *mut c_char,
- buflen: size_t,
- passwd_result: *mut *mut passwd) -> c_int {
- let mut result: c_int = 0;
- let status = u_getpwuid_r_ocall(&mut result as *mut c_int,
- uid,
- pwd,
- buf,
- buflen,
- passwd_result);
- if status == sgx_status_t::SGX_SUCCESS && result == 0 {
- let pwd_ret = *passwd_result;
- if !pwd_ret.is_null() {
- let mut temp_pwd = &mut *pwd;
- let mut temp_buf = buf;
- if temp_pwd.pw_name as usize != -1_isize as usize {
- temp_pwd.pw_name = temp_buf.offset(temp_pwd.pw_name as isize);
- } else {
- temp_pwd.pw_name = ptr::null_mut();
- }
- temp_buf = buf;
- if temp_pwd.pw_passwd as usize != -1_isize as usize {
- temp_pwd.pw_passwd = temp_buf.offset(temp_pwd.pw_passwd as isize);
- } else {
- temp_pwd.pw_passwd = ptr::null_mut();
- }
- temp_buf = buf;
- if temp_pwd.pw_gecos as usize != -1_isize as usize {
- temp_pwd.pw_gecos = temp_buf.offset(temp_pwd.pw_gecos as isize);
- } else {
- temp_pwd.pw_gecos = ptr::null_mut();
- }
- temp_buf = buf;
- if temp_pwd.pw_dir as usize != -1_isize as usize {
- temp_pwd.pw_dir = temp_buf.offset(temp_pwd.pw_dir as isize);
- } else {
- temp_pwd.pw_dir = ptr::null_mut();
- }
- temp_buf = buf;
- if temp_pwd.pw_shell as usize != -1_isize as usize {
- temp_pwd.pw_shell = temp_buf.offset(temp_pwd.pw_shell as isize);
- } else {
- temp_pwd.pw_shell = ptr::null_mut();
- }
- *passwd_result = pwd;
- }
- } else {
- *passwd_result = ptr::null_mut();
- if status != sgx_status_t::SGX_SUCCESS {
- result = ESGX;
- }
- }
- result
+pub unsafe fn lseek(fd: c_int, offset: off_t, whence: c_int) -> OCallResult<u64> {
+ let mut result: off_t = 0;
+ let mut error: c_int = 0;
+
+ let status = u_lseek_ocall(
+ &mut result as *mut off_t,
+ &mut error as *mut c_int,
+ fd,
+ offset,
+ whence,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result as u64)
+}
+
+pub unsafe fn lseek64(fd: c_int, offset: off64_t, whence: c_int) -> OCallResult<u64> {
+ let mut result: off64_t = 0;
+ let mut error: c_int = 0;
+
+ let status = u_lseek64_ocall(
+ &mut result as *mut off64_t,
+ &mut error as *mut c_int,
+ fd,
+ offset,
+ whence,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result as u64)
}
-pub unsafe fn open(path: *const c_char, flags: c_int) -> c_int {
+pub unsafe fn ftruncate(fd: c_int, length: off_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_open_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- flags);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_ftruncate_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ length,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn open64(path: *const c_char, oflag: c_int, mode: c_int) -> c_int {
+pub unsafe fn ftruncate64(fd: c_int, length: off64_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_open64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- oflag,
- mode);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_ftruncate64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ length,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn fstat(fd: c_int, buf: *mut stat) -> c_int {
+pub unsafe fn truncate(path: &CStr, length: off_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_fstat_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_truncate_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ length,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn fstat64(fd: c_int, buf: *mut stat64) -> c_int {
+pub unsafe fn truncate64(path: &CStr, length: off64_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_fstat64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_truncate64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ length,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn stat(path: *const c_char, buf: *mut stat) -> c_int {
+pub unsafe fn fsync(fd: c_int) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_stat_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_fsync_ocall(&mut result as *mut c_int, &mut error as *mut c_int, fd);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn stat64(path: *const c_char, buf: *mut stat64) -> c_int {
+pub unsafe fn fdatasync(fd: c_int) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_stat64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_fdatasync_ocall(&mut result as *mut c_int, &mut error as *mut c_int, fd);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
+pub unsafe fn fchmod(fd: c_int, mode: mode_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_lstat_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_fchmod_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ mode,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn lstat64(path: *const c_char, buf: *mut stat64) -> c_int {
+pub unsafe fn unlink(pathname: &CStr) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_lstat64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- buf);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_unlink_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ pathname.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
- let mut result: off_t = 0;
+pub unsafe fn link(oldpath: &CStr, newpath: &CStr) -> OCallResult<()> {
+ let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_lseek_ocall(&mut result as *mut off_t,
- &mut error as *mut c_int,
- fd,
- offset,
- whence);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_link_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ oldpath.as_ptr(),
+ newpath.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn lseek64(fd: c_int, offset: off64_t, whence: c_int) -> off64_t {
- let mut result: off64_t = 0;
+pub unsafe fn rename(oldpath: &CStr, newpath: &CStr) -> OCallResult<()> {
+ let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_lseek64_ocall(&mut result as *mut off64_t,
- &mut error as *mut c_int,
- fd,
- offset,
- whence);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_rename_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ oldpath.as_ptr(),
+ newpath.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn ftruncate(fd: c_int, length: off_t) -> c_int {
+pub unsafe fn chmod(path: &CStr, mode: mode_t) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_ftruncate_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- length);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn ftruncate64(fd: c_int, length: off64_t) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_ftruncate64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- length);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn truncate(path: *const c_char, length: off_t) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_truncate_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- length);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn truncate64(path: *const c_char, length: off64_t) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_truncate64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- length);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn fsync(fd: c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_fsync_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn fdatasync(fd: c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_fdatasync_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn fchmod(fd: c_int, mode: mode_t) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_fchmod_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- mode);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn unlink(pathname: *const c_char) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_unlink_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- pathname);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn link(oldpath: *const c_char, newpath: *const c_char) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_link_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- oldpath,
- newpath);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn rename(oldpath: *const c_char, newpath: *const c_char) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_rename_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- oldpath,
- newpath);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn chmod(path: *const c_char, mode: mode_t) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_chmod_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path,
- mode);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn readlink(path: *const c_char, buf: *mut c_char, bufsz: size_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
- let status = u_readlink_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- path,
- buf,
- bufsz);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn symlink(path1: *const c_char, path2: *const c_char) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_symlink_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- path1,
- path2);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn realpath(pathname: *const c_char) -> *mut c_char {
- let mut result: *mut c_char = ptr::null_mut();
- let mut error: c_int = 0;
- let status = u_realpath_ocall(&mut result as *mut *mut c_char,
- &mut error as *mut c_int,
- pathname);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result.is_null() {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = ptr::null_mut();
- }
- result
-}
-
-pub unsafe fn mkdir(pathname: *const c_char, mode: mode_t) -> c_int {
- let mut error: c_int = 0;
- let mut result: c_int = 0;
- let status = u_mkdir_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- pathname,
- mode);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn rmdir(pathname: *const c_char) -> c_int {
- let mut error: c_int = 0;
- let mut result: c_int = 0;
- let status = u_rmdir_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- pathname);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn opendir(pathname: *const c_char) -> *mut DIR {
- let mut result: *mut DIR = ptr::null_mut();
- let mut error: c_int = 0;
- let status = u_opendir_ocall(&mut result as *mut *mut DIR,
- &mut error as *mut c_int,
- pathname);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result.is_null() {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = ptr::null_mut();
- }
- result
-}
-
-pub unsafe fn readdir64_r(dirp: *mut DIR,
- entry: *mut dirent64,
- dirresult: *mut *mut dirent64) -> c_int {
- let mut result: c_int = 0;
- let status = u_readdir64_r_ocall(&mut result as *mut c_int,
- dirp,
- entry,
- dirresult);
- if status == sgx_status_t::SGX_SUCCESS && result == 0 {
- let dir_ret = *dirresult;
- if !dir_ret.is_null() {
- *dirresult = entry;
- }
- } else {
- *dirresult = ptr::null_mut();
- if status != sgx_status_t::SGX_SUCCESS {
- result = ESGX;
- }
- }
- result
-}
-
-pub unsafe fn closedir(dirp: *mut DIR) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_closedir_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- dirp);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn dirfd(dirp: *mut DIR) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_dirfd_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- dirp);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn fstatat64(dirfd: c_int,
- pathname: *const c_char,
- buf: *mut stat64,
- flags: c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_fstatat64_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- dirfd,
- pathname,
- buf,
- flags);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn read(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
-
- if buf.is_null() || sgx_is_within_enclave(buf, count) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if count >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
- }
-
- let tmp_buf = if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(count)
- } else {
- malloc(count)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- tmp_buf.write_bytes(0_u8, count);
-
- let status = u_read_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmp_buf,
- count);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if result != -1 {
- ptr::copy_nonoverlapping(tmp_buf as *const u8, buf as *mut u8, count);
- }
- if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
-}
-
-pub unsafe fn pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: off64_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
-
- if buf.is_null() || sgx_is_within_enclave(buf, count) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if count >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
- }
-
- let tmp_buf = if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(count)
- } else {
- malloc(count)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- tmp_buf.write_bytes(0_u8, count);
-
- let status = u_pread64_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmp_buf,
- count,
- offset);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if result != -1 {
- ptr::copy_nonoverlapping(tmp_buf as *const u8, buf as *mut u8, count);
- }
- if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
-}
-
-pub unsafe fn readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
- let mut iosize: usize = 0;
-
- if iov.is_null() || iovcnt <= 0 ||
- sgx_is_within_enclave(iov as *const c_void, iovcnt as usize * mem::size_of::<iovec>()) == 0 {
- set_errno(EINVAL);
- return -1;
- }
-
- let v = slice::from_raw_parts(iov, iovcnt as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- iosize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
- }
- }
-
- let iobase = malloc(iosize) as *mut u8;
- if iobase.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- iobase.write_bytes(0_u8, iosize);
-
- let mut tmpiovec: Vec<iovec> = Vec::with_capacity(iovcnt as usize);
- ptr = iobase;
- for io in v {
- let tmpiov = iovec{iov_base: ptr as *mut c_void,
- iov_len: io.iov_len};
- tmpiovec.push(tmpiov);
- ptr = ptr.add(io.iov_len as usize);
- }
-
- let status = u_readv_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmpiovec.as_slice().as_ptr(),
- iovcnt);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if result != -1 {
- for i in 0..v.len() {
- ptr::copy_nonoverlapping(tmpiovec[i].iov_base as *const u8, v[i].iov_base as *mut u8, v[i].iov_len as usize);
- }
- }
-
- free(iobase as *mut c_void);
- result
-}
-
-pub unsafe fn preadv64(fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off64_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
- let mut iosize: usize = 0;
-
- if iov.is_null() || iovcnt <= 0 ||
- sgx_is_within_enclave(iov as *const c_void, iovcnt as usize * mem::size_of::<iovec>()) == 0 {
- set_errno(EINVAL);
- return -1;
- }
-
- let v = slice::from_raw_parts(iov, iovcnt as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- iosize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
- }
- }
-
- let iobase = malloc(iosize) as *mut u8;
- if iobase.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- iobase.write_bytes(0_u8, iosize);
-
- let mut tmpiovec: Vec<iovec> = Vec::with_capacity(iovcnt as usize);
- ptr = iobase;
- for io in v {
- let tmpiov = iovec{iov_base: ptr as *mut c_void,
- iov_len: io.iov_len};
- tmpiovec.push(tmpiov);
- ptr = ptr.add(io.iov_len as usize);
- }
-
- let status = u_preadv64_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmpiovec.as_slice().as_ptr(),
- iovcnt,
- offset);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if result != -1 {
- for i in 0..v.len() {
- ptr::copy_nonoverlapping(tmpiovec[i].iov_base as *const u8, v[i].iov_base as *mut u8, v[i].iov_len as usize);
- }
- }
-
- free(iobase as *mut c_void);
- result
-}
-
-pub unsafe fn write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
-
- if buf.is_null() || sgx_is_within_enclave(buf, count) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if count >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
- }
-
- let tmp_buf = if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(count)
- } else {
- malloc(count)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- ptr::copy_nonoverlapping(buf as *const u8, tmp_buf as *mut u8, count);
-
- let status = u_write_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmp_buf,
- count);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
-}
-
-pub unsafe fn pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: off64_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
-
- if buf.is_null() || sgx_is_within_enclave(buf, count) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if count >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
- }
+ let status = u_chmod_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ mode,
+ );
- let tmp_buf = if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(count)
- } else {
- malloc(count)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- ptr::copy_nonoverlapping(buf as *const u8, tmp_buf as *mut u8, count);
-
- let status = u_pwrite64_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmp_buf,
- count,
- offset);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
- if count <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t {
+pub unsafe fn readlink(path: &CStr) -> OCallResult<Vec<u8>> {
let mut result: ssize_t = 0;
let mut error: c_int = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
- let mut iosize: usize = 0;
-
- if iov.is_null() || iovcnt <= 0 ||
- sgx_is_within_enclave(iov as *const c_void, iovcnt as usize * mem::size_of::<iovec>()) == 0 {
- set_errno(EINVAL);
- return -1;
- }
-
- let v = slice::from_raw_parts(iov, iovcnt as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- iosize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
- }
- }
-
- let iobase = malloc(iosize) as *mut u8;
- if iobase.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- iobase.write_bytes(0_u8, iosize);
-
- let mut tmpiovec: Vec<iovec> = Vec::with_capacity(iovcnt as usize);
- ptr = iobase;
- for io in v {
- let tmpiov = iovec{iov_base: ptr as *mut c_void,
- iov_len: io.iov_len};
- ptr::copy_nonoverlapping(io.iov_base as *const u8, tmpiov.iov_base as *mut u8, io.iov_len as usize);
- tmpiovec.push(tmpiov);
- ptr = ptr.add(io.iov_len as usize);
- }
-
- let status = u_writev_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmpiovec.as_slice().as_ptr(),
- iovcnt);
+ let mut buf: Vec<u8> = Vec::with_capacity(256);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ loop {
+ let bufsz = buf.capacity();
- free(iobase as *mut c_void);
- result
-}
+ let status = u_readlink_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ buf.as_mut_ptr() as *mut c_char,
+ bufsz,
+ );
-pub unsafe fn pwritev64(fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off64_t) -> ssize_t {
- let mut result: ssize_t = 0;
- let mut error: c_int = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
- let mut iosize: usize = 0;
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- if iov.is_null() || iovcnt <= 0 ||
- sgx_is_within_enclave(iov as *const c_void, iovcnt as usize * mem::size_of::<iovec>()) ==0 {
- set_errno(EINVAL);
- return -1;
- }
+ // On success, these calls return the number of bytes placed in buf.
+ // If the returned value equals bufsz, then truncation may have occurred.
+ let buf_read = result as usize;
+ ensure!(buf_read <= bufsz, ecust!("Malformed return value."));
+ buf.set_len(buf_read);
- let v = slice::from_raw_parts(iov, iovcnt as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- iosize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
+ if buf_read < buf.capacity() {
+ buf.shrink_to_fit();
+ return Ok(buf);
}
- }
- let iobase = malloc(iosize) as *mut u8;
- if iobase.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- iobase.write_bytes(0_u8, iosize);
-
- let mut tmpiovec: Vec<iovec> = Vec::with_capacity(iovcnt as usize);
- ptr = iobase;
- for io in v {
- let tmpiov = iovec{iov_base: ptr as *mut c_void,
- iov_len: io.iov_len};
- ptr::copy_nonoverlapping(io.iov_base as *const u8, tmpiov.iov_base as *mut u8, io.iov_len as usize);
- tmpiovec.push(tmpiov);
- ptr = ptr.add(io.iov_len as usize);
- }
-
- let status = u_pwritev64_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- fd,
- tmpiovec.as_slice().as_ptr(),
- iovcnt,
- offset);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
+ // Trigger the internal buffer resizing logic of `Vec` by requiring
+ // more space than the current capacity. The length is guaranteed to be
+ // the same as the capacity due to the if statement above.
+ buf.reserve(1);
}
-
- free(iobase as *mut c_void);
- result
}
-pub unsafe fn fcntl_arg0(fd: c_int, cmd: c_int) -> c_int {
+pub unsafe fn symlink(path1: &CStr, path2: &CStr) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_fcntl_arg0_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- cmd);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-pub unsafe fn fcntl_arg1(fd: c_int, cmd: c_int, arg: c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_fcntl_arg1_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- cmd,
- arg);
+ let status = u_symlink_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path1.as_ptr(),
+ path2.as_ptr(),
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn ioctl_arg0(fd: c_int, request: c_int) -> c_int {
+pub unsafe fn realpath(path: &CStr) -> OCallResult<Vec<u8>> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_ioctl_arg0_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- request);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
+ let bufsz = PATH_MAX as usize;
+ let mut resolved_buf = vec![0u8; bufsz];
-pub unsafe fn ioctl_arg1(fd: c_int, request: c_int, arg: *mut c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_ioctl_arg1_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd,
- request,
- arg);
+ let status = u_realpath_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ path.as_ptr(),
+ resolved_buf.as_mut_ptr() as *mut c_char,
+ bufsz,
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ shrink_to_fit_os_string(resolved_buf)
}
-pub unsafe fn close(fd: c_int) -> c_int {
- let mut result: c_int = 0;
+pub unsafe fn mkdir(pathname: &CStr, mode: mode_t) -> OCallResult<()> {
let mut error: c_int = 0;
- let status = u_close_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fd);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-
-pub unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_clock_gettime_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- clk_id,
- tp);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
-}
-pub unsafe fn socket(domain: c_int, ty: c_int, protocol: c_int) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_socket_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- domain,
- ty,
- protocol);
+ let status = u_mkdir_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ pathname.as_ptr(),
+ mode,
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn socketpair(domain: c_int, ty: c_int, protocol: c_int, sv: *mut c_int) -> c_int {
- let mut result: c_int = 0;
+pub unsafe fn rmdir(pathname: &CStr) -> OCallResult<()> {
let mut error: c_int = 0;
- let status = u_socketpair_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- domain,
- ty,
- protocol,
- sv);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let mut result: c_int = 0;
+
+ let status = u_rmdir_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ pathname.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn bind(sockfd: c_int, address: *const sockaddr, addrlen: socklen_t) -> c_int {
- let mut result: c_int = 0;
+// todo: change DIR to handle
+pub unsafe fn opendir(pathname: &CStr) -> OCallResult<*mut DIR> {
+ let mut result: *mut DIR = ptr::null_mut();
let mut error: c_int = 0;
- let status = u_bind_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- address,
- addrlen);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_opendir_ocall(
+ &mut result as *mut *mut DIR,
+ &mut error as *mut c_int,
+ pathname.as_ptr(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(!result.is_null(), eos!(error));
+ Ok(result)
}
-pub unsafe fn listen(sockfd: c_int, backlog: c_int) -> c_int {
+// todo: change the interface, dirresult
+// result: success or error
+// hint: end-of-dir or continue
+pub unsafe fn readdir64_r(
+ dirp: *mut DIR,
+ entry: &mut dirent64,
+ dirresult: *mut *mut dirent64,
+) -> OCallResult<()> {
let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_listen_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- backlog);
+ let mut eods: c_int = 0;
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
+ // if there is any error or or end-of-dir, the result is always null.
+ *dirresult = ptr::null_mut();
+
+ let status = u_readdir64_r_ocall(
+ &mut result as *mut c_int,
+ dirp,
+ entry,
+ &mut eods as *mut c_int,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(result));
+
+ // inspect contents of dirent64
+ // d_reclen is 8 bytes aligned on 64-bit platform
+ let dn_slice = as_u8_slice!(entry.d_name.as_ptr(), entry.d_name.len());
+ if let Some(slen) = memchr::memchr(0, dn_slice) {
+ ensure!(
+ (slen == 0 && entry.d_reclen == 0)
+ || align8!(slen + DIRENT64_NAME_OFFSET) == entry.d_reclen as usize,
+ ecust!("readdir64_r: inconsistant dirent content")
+ );
} else {
- set_errno(ESGX);
- result = -1;
+ return Err(ecust!("readdir64_r: d_name is not null terminated"));
}
- result
+
+ if eods == 0 {
+ *dirresult = entry;
+ }
+
+ Ok(())
}
-pub unsafe fn accept(sockfd: c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) -> c_int {
+pub unsafe fn closedir(dirp: *mut DIR) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
- let status = u_accept_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- addr,
- len_in, // This additional arg is just for EDL
- &mut len_out as *mut socklen_t);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let status = u_closedir_ocall(&mut result as *mut c_int, &mut error as *mut c_int, dirp);
- if !addrlen.is_null() {
- *addrlen = len_out;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn accept4(sockfd: c_int, addr: *mut sockaddr, addrlen: *mut socklen_t, flags: c_int) -> c_int {
+// todo: change the interface
+pub unsafe fn dirfd(dirp: *mut DIR) -> OCallResult<c_int> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
- let status = u_accept4_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- addr,
- len_in, // This additional arg is just for EDL
- &mut len_out as *mut socklen_t,
- flags);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let status = u_dirfd_ocall(&mut result as *mut c_int, &mut error as *mut c_int, dirp);
- if !addrlen.is_null() {
- *addrlen = len_out;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
}
-pub unsafe fn connect(sockfd: c_int, address: *const sockaddr, addrlen: socklen_t) -> c_int {
+pub unsafe fn fstatat64(
+ dirfd: c_int,
+ pathname: &CStr,
+ buf: &mut stat64,
+ flags: c_int,
+) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_connect_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- address,
- addrlen);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let status = u_fstatat64_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ dirfd,
+ pathname.as_ptr(),
+ buf,
+ flags,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn send(sockfd: c_int, buf: *const c_void, len: size_t, flags: c_int) -> ssize_t {
- let mut result: ssize_t = 0;
+fn check_trusted_enclave_buffer(buf: *const u8, count: size_t) -> OCallResult<()> {
+ ensure!(!buf.is_null(), ecust!("Invalid null buffer."));
+ ensure!(count > 0, ecust!("Invalid buffer checking length."));
+ ensure!(
+ unsafe { sgx_is_within_enclave(buf as *const c_void, count) } == 1,
+ ecust!("Buffer is not strictly inside enclave")
+ );
+ Ok(())
+}
+
+struct HostBuffer {
+ data: *mut u8,
+ len: usize,
+}
+
+unsafe fn host_malloc(size: usize) -> OCallResult<*mut c_void> {
+ let mut result: *mut c_void = ptr::null_mut();
let mut error: c_int = 0;
+ let status = u_malloc_ocall(
+ &mut result as *mut *mut c_void,
+ &mut error as *mut c_int,
+ size,
+ );
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(!result.is_null(), ecust!("Out of memory"));
+ ensure!(
+ sgx_is_outside_enclave(result, size) == 1,
+ ecust!("Malformed malloc address")
+ );
+
+ Ok(result as _)
+}
- if buf.is_null() || sgx_is_within_enclave(buf, len) == 0 {
- set_errno(EINVAL);
- return -1;
+impl HostBuffer {
+ fn zeroed(size: usize) -> OCallResult<Self> {
+ ensure!(
+ size != 0,
+ ecust!("Trying to allocate zero byte host memory.")
+ );
+ let host_ptr = unsafe { host_malloc(size)? };
+ unsafe { host_ptr.write_bytes(0_u8, size) };
+
+ Ok(HostBuffer {
+ data: host_ptr as _,
+ len: size,
+ })
}
- if len >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
+
+ fn from_enclave(buf: &[u8]) -> OCallResult<Self> {
+ let bufsz = buf.len();
+ ensure!(
+ bufsz != 0,
+ ecust!("Trying to allocate zero byte host memory.")
+ );
+ check_trusted_enclave_buffer(buf.as_ptr(), bufsz)?;
+ let host_ptr = unsafe { host_malloc(bufsz)? };
+ unsafe { ptr::copy_nonoverlapping(buf.as_ptr() as *const u8, host_ptr as *mut u8, bufsz) };
+
+ Ok(HostBuffer {
+ data: host_ptr as _,
+ len: bufsz,
+ })
}
- let tmp_buf = if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(len)
- } else {
- malloc(len)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
+ fn as_ptr(&self) -> *const c_void {
+ self.data as _
}
- ptr::copy_nonoverlapping(buf as *const u8, tmp_buf as *mut u8, len);
- let status = u_send_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- tmp_buf,
- len,
- flags);
+ fn as_mut_ptr(&mut self) -> *mut c_void {
+ self.data as _
+ }
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
+ fn len(&self) -> usize {
+ self.len
+ }
+
+ fn to_enclave_slice(&self, ecl_slice: &mut [u8]) -> OCallResult<usize> {
+ if ecl_slice.len() == 0 {
+ return Ok(0);
}
- } else {
- set_errno(ESGX);
- result = -1;
+ ensure!(ecl_slice.len() <= self.len);
+ check_trusted_enclave_buffer(ecl_slice.as_ptr(), ecl_slice.len())?;
+ unsafe {
+ ptr::copy_nonoverlapping(
+ self.data as *const u8,
+ ecl_slice.as_mut_ptr(),
+ ecl_slice.len(),
+ );
+ }
+ Ok(ecl_slice.len())
}
+}
- if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
+impl Drop for HostBuffer {
+ fn drop(&mut self) {
+ let _ = unsafe { u_free_ocall(self.data as _) };
}
- result
}
-pub unsafe fn sendto(sockfd: c_int,
- buf: *const c_void,
- len: size_t,
- flags: c_int,
- addr: *const sockaddr,
- addrlen: socklen_t) -> ssize_t {
+pub unsafe fn read(fd: c_int, buf: &mut [u8]) -> OCallResult<usize> {
let mut result: ssize_t = 0;
let mut error: c_int = 0;
+ let bufsz = buf.len();
+ check_trusted_enclave_buffer(buf.as_ptr(), bufsz)?;
- if buf.is_null() || sgx_is_within_enclave(buf, len) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if len >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
- }
+ let mut host_buf = HostBuffer::zeroed(bufsz)?;
- let tmp_buf = if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(len)
- } else {
- malloc(len)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- ptr::copy_nonoverlapping(buf as *const u8, tmp_buf as *mut u8, len);
+ let status = u_read_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_mut_ptr(),
+ host_buf.len(),
+ );
- let status = u_sendto_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- tmp_buf,
- len,
- flags,
- addr,
- addrlen);
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let nread = result as usize;
+ ensure!(nread <= bufsz, ecust!("Malformed return size"));
- if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
+ host_buf.to_enclave_slice(&mut buf[..nread])
}
-pub unsafe fn sendmsg(sockfd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
+pub unsafe fn pread64(fd: c_int, buf: &mut [u8], offset: off64_t) -> OCallResult<usize> {
let mut result: ssize_t = 0;
let mut error: c_int = 0;
- let mut hdrsize: usize = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
+ let bufsz = buf.len();
- if msg.is_null() || sgx_is_within_enclave(msg as *const c_void, mem::size_of::<msghdr>()) == 0 {
- set_errno(EINVAL);
- return -1;
- }
+ check_trusted_enclave_buffer(buf.as_ptr(), bufsz)?;
+ let mut host_buf = HostBuffer::zeroed(bufsz)?;
- let mhdr: &msghdr = &*msg;
- if !mhdr.msg_name.is_null() && mhdr.msg_namelen > 0 &&
- sgx_is_within_enclave(mhdr.msg_name, mhdr.msg_namelen as usize) != 0 {
- hdrsize += mhdr.msg_namelen as usize;
- }
+ let status = u_pread64_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_mut_ptr(),
+ host_buf.len(),
+ offset,
+ );
- if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 &&
- sgx_is_within_enclave(mhdr.msg_iov as *const c_void, mhdr.msg_iovlen as usize * mem::size_of::<iovec>()) != 0 {
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- hdrsize += mhdr.msg_iovlen as usize * mem::size_of::<iovec>();
- let v = slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- hdrsize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
- }
- }
- }
+ let nread = result as usize;
+ ensure!(nread <= bufsz, ecust!("Malformed return size"));
- if !mhdr.msg_control.is_null() && mhdr.msg_controllen > 0 &&
- sgx_is_within_enclave(mhdr.msg_control, mhdr.msg_controllen as usize) != 0 {
- hdrsize += mhdr.msg_controllen as usize;
- }
+ host_buf.to_enclave_slice(&mut buf[..nread])
+}
- let hdrbase = malloc(hdrsize) as *mut u8;
- if hdrbase.is_null() {
- set_errno(ENOMEM );
- return -1;
+// Caller is responsible to ensure the iov parameter and its content (slices) are inside enclave memory.
+pub unsafe fn readv(fd: c_int, mut iov: Vec<&mut [u8]>) -> OCallResult<size_t> {
+ let mut total_size: usize = 0;
+ for s in iov.iter() {
+ check_trusted_enclave_buffer(s.as_ptr(), s.len())?;
+ total_size = total_size
+ .checked_add(s.len())
+ .ok_or_else(|| OCallError::from_custom_error("Overflow"))?;
}
- hdrbase.write_bytes(0_u8, hdrsize);
-
- let mut tmpmsg: msghdr = mem::zeroed();
- ptr = hdrbase;
- if !mhdr.msg_name.is_null() && mhdr.msg_namelen > 0 {
- tmpmsg.msg_name = ptr as *mut c_void;
- tmpmsg.msg_namelen = mhdr.msg_namelen;
- ptr::copy_nonoverlapping(mhdr.msg_name as *const u8, tmpmsg.msg_name as *mut u8, mhdr.msg_namelen as usize);
- ptr = ptr.add(mhdr.msg_namelen as usize);
+
+ let bufsz = total_size;
+ if total_size == 0 {
+ return Ok(0);
}
- if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 {
- let tmpiov = slice::from_raw_parts_mut(ptr as *mut iovec, mhdr.msg_iovlen as usize);
- ptr = ptr.add(mhdr.msg_iovlen as usize * mem::size_of::<iovec>());
+ let mut host_buf = HostBuffer::zeroed(bufsz)?;
+ let mut result: ssize_t = 0;
+ let mut error: c_int = 0;
+ let status = u_read_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_mut_ptr(),
+ host_buf.len(),
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- let v = slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize);
- for i in 0..v.len() {
- tmpiov[i].iov_base = ptr as *mut c_void;
- tmpiov[i].iov_len = v[i].iov_len;
- ptr::copy_nonoverlapping(v[i].iov_base as *const u8, tmpiov[i].iov_base as *mut u8, v[i].iov_len as usize);
- ptr = ptr.add(v[i].iov_len as usize);
- }
- }
+ let u_read = result as usize;
+ ensure!(u_read <= bufsz, ecust!("Malformed result"));
- if !mhdr.msg_control.is_null() && mhdr.msg_controllen > 0 {
- tmpmsg.msg_control = ptr as *mut c_void;
- tmpmsg.msg_controllen = mhdr.msg_controllen;
- ptr::copy_nonoverlapping(mhdr.msg_control as *const u8, tmpmsg.msg_control as *mut u8, mhdr.msg_controllen as usize);
+ if u_read == 0 {
+ return Ok(0);
}
- let status = u_sendmsg_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- &tmpmsg as *const msghdr,
- flags);
+ // Buffers are processed in array order. This means that readv() com‐
+ // pletely fills iov[0] before proceeding to iov[1], and so on. (If
+ // there is insufficient data, then not all buffers pointed to by iov
+ // may be filled.) Similarly, writev() writes out the entire contents
+ // of iov[0] before proceeding to iov[1], and so on.
+ let mut bytes_left: usize = u_read;
+ let mut copied: usize = 0;
+ let mut i = 0;
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
+ let mut v = vec![0; u_read];
+ host_buf.to_enclave_slice(v.as_mut_slice())?;
+ while i < iov.len() && bytes_left > 0 {
+ let n = cmp::min(iov[i].len(), bytes_left);
+ iov[i][..n].copy_from_slice(&v[copied..copied + n]);
+ bytes_left -= n;
+ copied += n;
+ i += 1;
}
- free(hdrbase as *mut c_void);
- result
+ Ok(u_read)
}
-pub unsafe fn recv(sockfd: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> ssize_t {
+pub unsafe fn write(fd: c_int, buf: &[u8]) -> OCallResult<usize> {
let mut result: ssize_t = 0;
let mut error: c_int = 0;
-
- if buf.is_null() || sgx_is_within_enclave(buf, len) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if len >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
+ let bufsz = buf.len();
+ if bufsz == 0 {
+ return Ok(0);
}
- let tmp_buf = if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(len)
- } else {
- malloc(len)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- tmp_buf.write_bytes(0_u8, len);
+ let host_buf = HostBuffer::from_enclave(buf)?;
- let status = u_recv_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- tmp_buf,
- len,
- flags);
+ let status = u_write_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_ptr(),
+ host_buf.len(),
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- if result != -1 {
- ptr::copy_nonoverlapping(tmp_buf as *const u8, buf as *mut u8, len);
- }
- if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
- }
- result
+ let nwritten = result as usize;
+ ensure!(nwritten <= bufsz, ecust!("Malformed return size"));
+ Ok(nwritten)
}
-pub unsafe fn recvfrom(sockfd: c_int,
- buf: *mut c_void,
- len: size_t,
- flags: c_int,
- addr: *mut sockaddr,
- addrlen: *mut socklen_t) -> ssize_t {
+pub unsafe fn pwrite64(fd: c_int, buf: &[u8], offset: off64_t) -> OCallResult<usize> {
let mut result: ssize_t = 0;
let mut error: c_int = 0;
- let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
- let mut len_out: socklen_t = 0 as socklen_t;
-
- if buf.is_null() || sgx_is_within_enclave(buf, len) == 0 {
- set_errno(EINVAL);
- return -1;
- }
- if len >= usize::max_value() {
- set_errno(EINVAL);
- return -1;
+ let bufsz = buf.len();
+ if bufsz == 0 {
+ return Ok(0);
}
- let tmp_buf = if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocalloc(len)
- } else {
- malloc(len)
- };
- if tmp_buf.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- tmp_buf.write_bytes(0_u8, len);
-
- let status = u_recvfrom_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- tmp_buf,
- len,
- flags,
- addr,
- len_in, // This additional arg is just for EDL
- &mut len_out as *mut socklen_t);
+ let host_buf = HostBuffer::from_enclave(buf)?;
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let status = u_pwrite64_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_ptr(),
+ host_buf.len(),
+ offset,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- if result != -1 {
- ptr::copy_nonoverlapping(tmp_buf as *const u8, buf as *mut u8, len);
+ let nwritten = result as usize;
+ ensure!(nwritten <= bufsz, ecust!("Malformed return size"));
+
+ Ok(nwritten)
+}
+
+pub unsafe fn writev(fd: c_int, iov: Vec<&[u8]>) -> OCallResult<size_t> {
+ let mut total_size: usize = 0;
+ for s in iov.iter() {
+ check_trusted_enclave_buffer(s.as_ptr(), s.len())?;
+ total_size = total_size
+ .checked_add(s.len())
+ .ok_or_else(|| OCallError::from_custom_error("Overflow"))?;
}
- if len <= MAX_OCALL_ALLOC_SIZE {
- sgx_ocfree();
- } else {
- free(tmp_buf);
+
+ if total_size == 0 {
+ return Ok(0);
}
- if !addrlen.is_null() {
- *addrlen = len_out;
+ let bufsz = total_size;
+ let mut buffer = vec![0; total_size];
+
+ let mut copied = 0;
+ for io_slice in iov.iter() {
+ buffer[copied..copied + io_slice.len()].copy_from_slice(io_slice);
+ copied += io_slice.len();
}
- result
-}
-pub unsafe fn recvmsg(sockfd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
+ let host_buf = HostBuffer::from_enclave(&buffer)?;
let mut result: ssize_t = 0;
let mut error: c_int = 0;
- let mut hdrsize: usize = 0;
- let mut ptr: *mut u8 = ptr::null_mut();
- if msg.is_null() || sgx_is_within_enclave(msg as *const c_void, mem::size_of::<msghdr>()) == 0 {
- set_errno(EINVAL);
- return -1;
- }
+ let status = u_write_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ fd,
+ host_buf.as_ptr(),
+ host_buf.len(),
+ );
- let mhdr: &mut msghdr = &mut *msg;
- if !mhdr.msg_name.is_null() && mhdr.msg_namelen > 0 &&
- sgx_is_within_enclave(mhdr.msg_name, mhdr.msg_namelen as usize) != 0 {
- hdrsize += mhdr.msg_namelen as usize;
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 &&
- sgx_is_within_enclave(mhdr.msg_iov as *const c_void, mhdr.msg_iovlen as usize * mem::size_of::<iovec>()) != 0 {
+ let nwritten = result as size_t;
+ ensure!(nwritten <= bufsz, ecust!("Malformed result"));
- hdrsize += mhdr.msg_iovlen as usize * mem::size_of::<iovec>();
- let v = slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize);
- for io in v {
- if !io.iov_base.is_null() && io.iov_len > 0 &&
- sgx_is_within_enclave(io.iov_base, io.iov_len as usize) != 0 {
- hdrsize += io.iov_len as usize;
- } else {
- set_errno(EINVAL);
- return -1;
- }
- }
- }
+ Ok(nwritten)
+}
- if !mhdr.msg_control.is_null() && mhdr.msg_controllen > 0 &&
- sgx_is_within_enclave(mhdr.msg_control, mhdr.msg_controllen as usize) != 0 {
- hdrsize += mhdr.msg_controllen as usize;
- }
+pub unsafe fn fcntl_arg0(fd: c_int, cmd: c_int) -> OCallResult<c_int> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_fcntl_arg0_ocall(&mut result as *mut c_int, &mut error as *mut c_int, fd, cmd);
- let hdrbase = malloc(hdrsize) as *mut u8;
- if hdrbase.is_null() {
- set_errno(ENOMEM );
- return -1;
- }
- hdrbase.write_bytes(0_u8, hdrsize);
-
- let mut tmpmsg: msghdr = mem::zeroed();
- ptr = hdrbase;
- if !mhdr.msg_name.is_null() && mhdr.msg_namelen > 0 {
- tmpmsg.msg_name = ptr as *mut c_void;
- tmpmsg.msg_namelen = mhdr.msg_namelen;
- ptr::copy_nonoverlapping(mhdr.msg_name as *const u8, tmpmsg.msg_name as *mut u8, mhdr.msg_namelen as usize);
- ptr = ptr.add(mhdr.msg_namelen as usize);
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
+}
- if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 {
- let tmpiov = slice::from_raw_parts_mut(ptr as *mut iovec, mhdr.msg_iovlen as usize);
- ptr = ptr.add(mhdr.msg_iovlen as usize * mem::size_of::<iovec>());
+pub unsafe fn fcntl_arg1(fd: c_int, cmd: c_int, arg: c_int) -> OCallResult<c_int> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_fcntl_arg1_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ cmd,
+ arg,
+ );
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
+}
- let v = slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize);
- for i in 0..v.len() {
- tmpiov[i].iov_base = ptr as *mut c_void;
- tmpiov[i].iov_len = v[i].iov_len;
- ptr = ptr.add(v[i].iov_len as usize);
- }
- }
+pub unsafe fn ioctl_arg0(fd: c_int, request: c_int) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_ioctl_arg0_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ request,
+ );
- if !mhdr.msg_control.is_null() && mhdr.msg_controllen > 0 {
- tmpmsg.msg_control = ptr as *mut c_void;
- tmpmsg.msg_controllen = mhdr.msg_controllen;
- ptr::copy_nonoverlapping(mhdr.msg_control as *const u8, tmpmsg.msg_control as *mut u8, mhdr.msg_controllen as usize);
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
- let status = u_recvmsg_ocall(&mut result as *mut ssize_t,
- &mut error as *mut c_int,
- sockfd,
- &mut tmpmsg as *mut msghdr,
- flags);
+pub unsafe fn ioctl_arg1(fd: c_int, request: c_int, arg: &mut c_int) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_ioctl_arg1_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fd,
+ request,
+ arg,
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn close(fd: c_int) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_close_ocall(&mut result as *mut c_int, &mut error as *mut c_int, fd);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ Ok(())
+}
+
+pub unsafe fn clock_gettime(clk_id: clockid_t, tp: &mut timespec) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_clock_gettime_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ clk_id,
+ tp,
+ );
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ Ok(())
+}
+
+pub unsafe fn socket(domain: c_int, ty: c_int, protocol: c_int) -> OCallResult<c_int> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_socket_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ domain,
+ ty,
+ protocol,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+
+ Ok(result)
+}
+
+pub unsafe fn socketpair(
+ domain: c_int,
+ ty: c_int,
+ protocol: c_int,
+ sv: &mut [c_int; 2],
+) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let mut out_sv = [0 as c_int; 2];
+
+ let status = u_socketpair_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ domain,
+ ty,
+ protocol,
+ out_sv.as_mut_ptr() as *mut c_int,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ sv.copy_from_slice(&out_sv);
+ Ok(())
+}
+
+pub unsafe fn bind(sockfd: c_int, sock_addr: &SockAddr) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+
+ let address = sock_addr.as_bytes();
+
+ let status = u_bind_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ address.as_ptr() as *const sockaddr,
+ address.len() as socklen_t,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn listen(sockfd: c_int, backlog: c_int) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let status = u_listen_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ backlog,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn accept4(sockfd: c_int, flags: c_int) -> OCallResult<(c_int, SockAddr)> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let mut storage: sockaddr_storage = mem::zeroed();
+ let len_in = mem::size_of_val(&storage) as socklen_t;
+
+ let mut len_out: socklen_t = 0 as socklen_t;
+ let status = u_accept4_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ &mut storage as *mut _ as *mut _,
+ len_in, // This additional arg is just for EDL
+ &mut len_out as *mut socklen_t,
+ flags,
+ );
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ ensure!(
+ len_out <= len_in,
+ ecust!("Caller should alloc enough addr buffer.")
+ );
+
+ let addr = SockAddr::try_from_storage(storage, len_out)?;
+ Ok((result, addr))
+}
+
+pub unsafe fn connect(sockfd: c_int, address: &SockAddr) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+ let address = address.as_bytes();
+
+ let status = u_connect_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ address.as_ptr() as *const sockaddr,
+ address.len() as socklen_t,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn send(sockfd: c_int, buf: &[u8], flags: c_int) -> OCallResult<usize> {
+ let bufsz = buf.len();
+ // size zero
+
+ let mut result: ssize_t = 0;
+ let mut error: c_int = 0;
+ let host_buf = HostBuffer::from_enclave(buf)?;
+
+ let status = u_send_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ sockfd,
+ host_buf.as_ptr(),
+ host_buf.len(),
+ flags,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+
+ let nsent = result as usize;
+ ensure!(nsent <= bufsz, ecust!("Malformed return size"));
+
+ Ok(nsent)
+}
+
+pub unsafe fn sendto(
+ sockfd: c_int,
+ buf: &[u8],
+ flags: c_int,
+ sock_addr: &SockAddr,
+) -> OCallResult<usize> {
+ let mut result: ssize_t = 0;
+ let mut error: c_int = 0;
- ptr = hdrbase;
- if !mhdr.msg_name.is_null() && mhdr.msg_namelen > 0 {
- ptr = ptr.add(mhdr.msg_namelen as usize);
- }
+ let bufsz = buf.len();
+ let host_buf = HostBuffer::from_enclave(buf)?;
- if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 {
- let tmpiov = slice::from_raw_parts_mut(ptr as *mut iovec, mhdr.msg_iovlen as usize);
- ptr = ptr.add(mhdr.msg_iovlen as usize * mem::size_of::<iovec>());
+ let addr = sock_addr.as_bytes();
- let v = slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize);
- for i in 0..v.len() {
- ptr::copy_nonoverlapping(tmpiov[i].iov_base as *const u8, v[i].iov_base as *mut u8, v[i].iov_len as usize);
- ptr = ptr.add(v[i].iov_len as usize);
- }
- }
+ //todo: add check for addrlen
+ let status = u_sendto_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ sockfd,
+ host_buf.as_ptr(),
+ host_buf.len(),
+ flags,
+ addr.as_ptr() as *const sockaddr,
+ addr.len() as socklen_t,
+ );
- if !mhdr.msg_control.is_null() && mhdr.msg_controllen > 0 {
- ptr::copy_nonoverlapping(tmpmsg.msg_control as *const u8, mhdr.msg_control as *mut u8, mhdr.msg_controllen as usize);
- }
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
- free(hdrbase as *mut c_void);
- result
+ let nsent = result as usize;
+ ensure!(nsent <= bufsz, ecust!("Malformed return size"));
+
+ Ok(nsent)
}
-pub unsafe fn setsockopt(sockfd: c_int,
- level: c_int,
- optname: c_int,
- optval: *const c_void,
- optlen: socklen_t) -> c_int {
- let mut result: c_int = 0;
+pub unsafe fn recv(sockfd: c_int, buf: &mut [u8], flags: c_int) -> OCallResult<usize> {
+ let mut result: ssize_t = 0;
let mut error: c_int = 0;
- let status = u_setsockopt_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- level,
- optname,
- optval,
- optlen);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let buf_ptr = buf.as_ptr();
+ let bufsz = buf.len();
+ check_trusted_enclave_buffer(buf_ptr, bufsz)?;
+ let mut host_buf = HostBuffer::zeroed(bufsz)?;
+
+ let status = u_recv_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ sockfd,
+ host_buf.as_mut_ptr(),
+ host_buf.len(),
+ flags,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+
+ let nrecv = result as usize;
+ ensure!(nrecv <= bufsz, ecust!("Malformed return size"));
+ host_buf.to_enclave_slice(&mut buf[..nrecv])
}
-pub unsafe fn getsockopt(sockfd: c_int,
- level: c_int,
- optname: c_int,
- optval: *mut c_void,
- optlen: *mut socklen_t) -> c_int {
+pub unsafe fn recvfrom(
+ sockfd: c_int,
+ buf: &mut [u8],
+ flags: c_int,
+) -> OCallResult<(size_t, SockAddr)> {
+ let mut result: ssize_t = 0;
+ let mut error: c_int = 0;
+
+ let mut storage: sockaddr_storage = mem::zeroed();
+ let len_in = mem::size_of_val(&storage) as socklen_t;
+ let mut len_out: socklen_t = 0 as socklen_t;
+
+ let bufsz = buf.len();
+ let mut host_buf = HostBuffer::zeroed(bufsz)?;
+
+ // todo: add check for len_in
+ let status = u_recvfrom_ocall(
+ &mut result as *mut ssize_t,
+ &mut error as *mut c_int,
+ sockfd,
+ host_buf.as_mut_ptr(),
+ host_buf.len(),
+ flags,
+ &mut storage as *mut _ as *mut _,
+ len_in, // This additional arg is just for EDL
+ &mut len_out as *mut socklen_t,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ ensure!(
+ len_out <= len_in,
+ ecust!("Caller should alloc enough addr buffer.")
+ );
+
+ let nrecv = result as usize;
+ ensure!(nrecv <= bufsz, ecust!("Malformed return value"));
+
+ host_buf.to_enclave_slice(&mut buf[..nrecv])?;
+ let addr = SockAddr::try_from_storage(storage, len_out)?;
+ Ok((nrecv, addr))
+}
+
+pub unsafe fn setsockopt(
+ sockfd: c_int,
+ level: c_int,
+ optname: c_int,
+ optval: *const c_void,
+ optlen: socklen_t,
+) -> OCallResult<()> {
+ let mut result: c_int = 0;
+ let mut error: c_int = 0;
+
+ let status = u_setsockopt_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ level,
+ optname,
+ optval,
+ optlen,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn getsockopt(
+ sockfd: c_int,
+ level: c_int,
+ optname: c_int,
+ optval: *mut c_void,
+ optlen: *mut socklen_t,
+) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
let len_in: socklen_t = if !optlen.is_null() { *optlen } else { 0 };
let mut len_out: socklen_t = 0 as socklen_t;
- let status = u_getsockopt_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- level,
- optname,
- optval,
- len_in,
- &mut len_out as *mut socklen_t);
-
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
-
+ let status = u_getsockopt_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ level,
+ optname,
+ optval,
+ len_in,
+ &mut len_out as *mut socklen_t,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ ensure!(
+ len_out <= len_in,
+ ecust!("Caller should alloc enough opt buffer.")
+ );
if !optlen.is_null() {
*optlen = len_out;
}
- result
+ Ok(())
}
-pub unsafe fn getpeername(sockfd: c_int, address: *mut sockaddr, addrlen: *mut socklen_t) -> c_int {
+pub unsafe fn getpeername(sockfd: c_int) -> OCallResult<SockAddr> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
+ let mut storage: sockaddr_storage = mem::zeroed();
+ let len_in = mem::size_of_val(&storage) as socklen_t;
let mut len_out: socklen_t = 0 as socklen_t;
- let status = u_getpeername_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- address,
- len_in,
- &mut len_out as *mut socklen_t);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let status = u_getpeername_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ &mut storage as *mut _ as *mut _,
+ len_in,
+ &mut len_out as *mut socklen_t,
+ );
- if !addrlen.is_null() {
- *addrlen = len_out;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ ensure!(
+ len_out <= len_in,
+ ecust!("Caller should alloc enough addr buffer.")
+ );
+
+ let addr = SockAddr::try_from_storage(storage, len_out)?;
+ Ok(addr)
}
-pub unsafe fn getsockname(sockfd: c_int, address: *mut sockaddr, addrlen: *mut socklen_t) -> c_int {
+pub unsafe fn getsockname(sockfd: c_int) -> OCallResult<SockAddr> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let len_in: socklen_t = if !addrlen.is_null() { *addrlen } else { 0 };
+ let mut storage: sockaddr_storage = mem::zeroed();
+ let len_in = mem::size_of_val(&storage) as socklen_t;
let mut len_out: socklen_t = 0 as socklen_t;
- let status = u_getsockname_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- address,
- len_in,
- &mut len_out as *mut socklen_t);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
+ let status = u_getsockname_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ &mut storage as *mut _ as *mut _,
+ len_in,
+ &mut len_out as *mut socklen_t,
+ );
- if !addrlen.is_null() {
- *addrlen = len_out;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ ensure!(
+ len_out <= len_in,
+ ecust!("Caller should alloc enough addr buffer.")
+ );
+
+ let addr = SockAddr::try_from_storage(storage, len_out)?;
+ Ok(addr)
}
-pub unsafe fn shutdown(sockfd: c_int, how: c_int) -> c_int {
+pub unsafe fn shutdown(sockfd: c_int, how: c_int) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_shutdown_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- sockfd,
- how);
+ let status = u_shutdown_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ sockfd,
+ how,
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn getaddrinfo(node: *const c_char,
- service: *const c_char,
- hints: *const addrinfo,
- res: *mut *mut addrinfo) -> c_int {
+// exchange only struct sockaddr *ai_addr; information across the boundary
+// information filtering by hint is also not supported
+pub unsafe fn getaddrinfo(
+ node: Option<&CStr>,
+ service: Option<&CStr>,
+ hints: Option<AddrInfoHints>,
+) -> OCallResult<Vec<SockAddr>> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let mut ret_res: *mut addrinfo = ptr::null_mut();
- let hint: addrinfo = if !hints.is_null() {
- addrinfo {
- ai_flags: (*hints).ai_flags,
- ai_family: (*hints).ai_family,
- ai_socktype: (*hints).ai_socktype,
- ai_protocol: (*hints).ai_protocol,
- ai_addrlen: 0,
- ai_addr: ptr::null_mut(),
- ai_canonname: ptr::null_mut(),
- ai_next: ptr::null_mut(),
- }
- } else {
- addrinfo {
- ai_flags: AI_V4MAPPED | AI_ADDRCONFIG,
- ai_family: AF_UNSPEC,
- ai_socktype: 0,
- ai_protocol: 0,
- ai_addrlen: 0,
- ai_addr: ptr::null_mut(),
- ai_canonname: ptr::null_mut(),
- ai_next: ptr::null_mut(),
- }
- };
- let status = u_getaddrinfo_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- node,
- service,
- &hint as *const addrinfo,
- &mut ret_res as *mut *mut addrinfo);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == 0 {
- *res = ptr::null_mut();
- let mut cur_ptr: *mut addrinfo = ret_res;
- let mut addrinfo_vec: Vec<Box<addrinfo>> = Vec::new();
- while cur_ptr != ptr::null_mut() {
- let cur: &addrinfo = &*cur_ptr;
- let mut info = addrinfo {
- ai_flags: cur.ai_flags,
- ai_family: cur.ai_family,
- ai_socktype: cur.ai_socktype,
- ai_protocol: cur.ai_protocol,
- ai_addrlen: 0,
- ai_addr: ptr::null_mut(),
- ai_canonname: ptr::null_mut(),
- ai_next: ptr::null_mut(),
- };
-
- if !cur.ai_addr.is_null() && cur.ai_addrlen > 0 {
- let mut addr_vec = vec![0u8; cur.ai_addrlen as usize];
- let addr_slice: &[u8] = slice::from_raw_parts(cur.ai_addr as *const u8, cur.ai_addrlen as usize);
- addr_vec.copy_from_slice(addr_slice);
- addr_vec.shrink_to_fit();
- info.ai_addrlen = cur.ai_addrlen;
- info.ai_addr = addr_vec.as_mut_ptr() as *mut sockaddr;
- mem::forget(addr_vec);
- }
-
- if !cur.ai_canonname.is_null() {
- let len: usize = strlen(cur.ai_canonname) + 1;
- let mut name_vec = vec![0u8; len];
- let name_slice: &[u8] = slice::from_raw_parts(cur.ai_canonname as *const u8, len);
- name_vec.copy_from_slice(name_slice);
- name_vec.shrink_to_fit();
- info.ai_canonname = name_vec.as_mut_ptr() as *mut c_char;
- mem::forget(name_vec);
- }
-
- addrinfo_vec.push(Box::new(info));
- cur_ptr = cur.ai_next;
- }
+ let entry_size = cmp::max(
+ mem::size_of::<sockaddr_in6>(),
+ mem::size_of::<sockaddr_in>(),
+ );
- if addrinfo_vec.len() > 0 {
- for i in 0..addrinfo_vec.len() - 1 {
- addrinfo_vec[i].ai_next = addrinfo_vec[i + 1].as_mut() as *mut addrinfo;
- }
- let res_ptr = addrinfo_vec[0].as_mut() as *mut addrinfo;
+ let entry_count = 32;
+ let buf_sz = entry_size * entry_count;
- for info in addrinfo_vec {
- let _ = Box::into_raw(info);
- }
- *res = res_ptr;
- }
- let _ = u_freeaddrinfo_ocall(ret_res);
+ let mut buffer = vec![0u8; buf_sz];
+ let mut out_count = 0usize;
- } else if result == EAI_SYSTEM {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = EAI_SYSTEM;
- }
- result
-}
+ let node_ptr = match node {
+ Some(n) => n.as_ptr(),
+ None => ptr::null(),
+ };
-pub unsafe fn freeaddrinfo(res: *mut addrinfo ) {
- let mut cur_ptr: *mut addrinfo = res;
- let mut addrinfo_vec: Vec<Box<addrinfo>> = Vec::new();
- while cur_ptr != ptr::null_mut() {
- let cur: &addrinfo = &*cur_ptr;
- if !cur.ai_addr.is_null() && cur.ai_addrlen > 0 {
- let addr_vec = Vec::from_raw_parts(cur.ai_addr as *mut u8, cur.ai_addrlen as usize, cur.ai_addrlen as usize);
- drop(addr_vec);
- }
- if !cur.ai_canonname.is_null() {
- let len: usize = strlen(cur.ai_canonname) + 1;
- let name_vec = Vec::from_raw_parts(cur.ai_canonname as *mut u8, len, len);
- drop(name_vec);
+ let service_ptr = match service {
+ Some(s) => s.as_ptr(),
+ None => ptr::null(),
+ };
+
+ let hints = hints.map(|h| h.to_addrinfo());
+ let hints_ptr = match &hints {
+ Some(h) => h,
+ None => ptr::null(),
+ };
+
+ let status = u_getaddrinfo_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ node_ptr,
+ service_ptr,
+ hints_ptr,
+ entry_size,
+ buffer.as_mut_ptr() as *mut u8,
+ buf_sz,
+ &mut out_count as *mut size_t,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ match result {
+ 0 => {}
+ EAI_SYSTEM => return Err(eos!(error)),
+ 1 => return Err(ecust!("Untrusted side error")),
+ e => return Err(egai!(e)),
+ };
+
+ ensure!(result == 0, ecust!("Unkonwn error"));
+ ensure!(out_count <= entry_count, ecust!("Malformed out_count"));
+
+ let mut addr_vec = Vec::<SockAddr>::with_capacity(out_count);
+ let mut cur_ptr = buffer.as_ptr() as *const u8;
+ for _ in 0..out_count {
+ let family: *const sa_family_t = mem::transmute(cur_ptr);
+ match *family as i32 {
+ AF_INET => {
+ let sockaddr: *const sockaddr_in = mem::transmute(cur_ptr);
+ addr_vec.push(SockAddr::IN4(*sockaddr))
+ }
+ AF_INET6 => {
+ let sockaddr: *const sockaddr_in6 = mem::transmute(cur_ptr);
+ addr_vec.push(SockAddr::IN6(*sockaddr))
+ }
+ _ => bail!(ecust!("Unsupported family info")),
}
- addrinfo_vec.push(Box::from_raw(cur_ptr));
- cur_ptr = cur.ai_next;
+ cur_ptr = cur_ptr.add(entry_size);
}
- drop(addrinfo_vec);
+ Ok(addr_vec)
}
-pub unsafe fn gai_strerror(errcode: c_int) -> *const c_char {
- let mut result: *const c_char = ptr::null();
- let status = u_gai_strerror_ocall(&mut result as *mut *const c_char, errcode);
- if status != sgx_status_t::SGX_SUCCESS {
- set_errno(ESGX);
- }
- result
-}
+pub unsafe fn poll(fds: &mut [pollfd], timeout: c_int) -> OCallResult<PolledOk> {
+ let nfds = fds.len() as u64;
-pub unsafe fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_poll_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fds,
- nfds,
- timeout);
+ let status = u_poll_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fds.as_mut_ptr(),
+ nfds,
+ timeout,
+ );
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ match result {
+ 1..=i32::MAX => {
+ if result as u64 > nfds {
+ Err(ecust!("Malformed return value"))
+ } else {
+ Ok(PolledOk::ReadyDescsCount(result as usize))
+ }
}
- } else {
- set_errno(ESGX);
- result = -1;
+ 0 => Ok(PolledOk::TimeLimitExpired),
+ _ => Err(eos!(error)),
}
- result
}
-pub unsafe fn epoll_create1(flags: c_int) -> c_int {
+pub unsafe fn epoll_create1(flags: c_int) -> OCallResult<c_int> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_epoll_create1_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- flags);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_epoll_create1_ocall(&mut result as *mut c_int, &mut error as *mut c_int, flags);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+
+ Ok(result)
}
-pub unsafe fn epoll_ctl(epfd: c_int,
- op: c_int,
- fd: c_int,
- event: *mut epoll_event) -> c_int {
+pub unsafe fn epoll_ctl(
+ epfd: c_int,
+ op: c_int,
+ fd: c_int,
+ event: &mut epoll_event,
+) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_epoll_ctl_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- epfd,
- op,
- fd,
- event);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_epoll_ctl_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ epfd,
+ op,
+ fd,
+ event,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+
+ Ok(())
}
-pub unsafe fn epoll_wait(epfd: c_int,
- events: *mut epoll_event,
- maxevents: c_int,
- timeout: c_int) -> c_int {
+pub unsafe fn epoll_wait(
+ epfd: c_int,
+ events: &mut Vec<epoll_event>,
+ timeout: c_int,
+) -> OCallResult<usize> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_epoll_wait_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- epfd,
- events,
- maxevents,
- timeout);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+ let maxevents: c_int = events.capacity() as c_int;
+ ensure!(maxevents > 0, ecust!("Invalid events capacity"));
+
+ let status = u_epoll_wait_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ epfd,
+ events.as_mut_ptr(),
+ maxevents,
+ timeout,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ ensure!(result <= maxevents, ecust!("Malformed event count"));
+
+ events.set_len(result as usize);
+ Ok(result as usize)
}
-pub unsafe fn sysconf(name: c_int) -> c_long {
+pub unsafe fn sysconf(name: c_int) -> OCallResult<c_long> {
let mut result: c_long = 0;
let mut error: c_int = 0;
- let status = u_sysconf_ocall(&mut result as *mut c_long,
- &mut error as *mut c_int,
- name);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_sysconf_ocall(&mut result as *mut c_long, &mut error as *mut c_int, name);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
}
-pub unsafe fn prctl(option: c_int,
- arg2: c_ulong,
- arg3: c_ulong,
- arg4: c_ulong,
- arg5: c_ulong) -> c_int {
+pub unsafe fn prctl(
+ option: c_int,
+ arg2: c_ulong,
+ arg3: c_ulong,
+ arg4: c_ulong,
+ arg5: c_ulong,
+) -> OCallResult<c_int> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_prctl_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- option,
- arg2,
- arg3,
- arg4,
- arg5);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_prctl_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ option,
+ arg2,
+ arg3,
+ arg4,
+ arg5,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result >= 0, eos!(error));
+ Ok(result)
}
-pub unsafe fn sched_setaffinity(pid: pid_t, cpusetsize: size_t, mask: *const cpu_set_t) -> c_int {
+pub unsafe fn pipe2(fds: &mut [c_int; 2], flags: c_int) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_sched_setaffinity_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- pid,
- cpusetsize,
- mask);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_pipe2_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ fds.as_mut_ptr(),
+ flags,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
}
-pub unsafe fn sched_getaffinity(pid: pid_t, cpusetsize: size_t, mask: *mut cpu_set_t) -> c_int {
+pub unsafe fn sched_yield() -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_sched_getaffinity_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- pid,
- cpusetsize,
- mask);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
- }
- result
+
+ let status = u_sched_yield_ocall(&mut result as *mut c_int, &mut error as *mut c_int);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ ensure!(result == 0, eos!(error));
+ Ok(())
+}
+
+pub unsafe fn getpid() -> OCallResult<pid_t> {
+ let mut result = -1;
+
+ let status = u_getpid_ocall(&mut result as *mut pid_t);
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+ Ok(result)
}
-pub unsafe fn pipe(fds: *mut c_int) -> c_int {
+pub unsafe fn nanosleep(req: &mut timespec) -> OCallResult<()> {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_pipe_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fds);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
- result = -1;
+
+ let mut rem = req.clone();
+
+ let status = u_nanosleep_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ req,
+ &mut rem,
+ );
+
+ ensure!(status == sgx_status_t::SGX_SUCCESS, esgx!(status));
+
+ ensure!(rem.tv_sec <= req.tv_sec, ecust!("Malformed remaining time"));
+ if rem.tv_sec == req.tv_sec {
+ ensure!(
+ rem.tv_nsec < req.tv_nsec,
+ ecust!("Malformed remaining time")
+ );
}
- result
+
+ req.tv_sec = rem.tv_sec;
+ req.tv_nsec = rem.tv_nsec;
+
+ ensure!(result == 0, eos!(error));
+
+ req.tv_sec = 0;
+ req.tv_nsec = 0;
+ Ok(())
}
-pub unsafe fn pipe2(fds: *mut c_int, flags: c_int) -> c_int {
+pub unsafe fn sigaction(
+ signum: c_int,
+ act: *const sigaction,
+ oldact: *mut sigaction,
+ enclave_id: uint64_t,
+) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_pipe2_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- fds,
- flags);
+
+ let status = u_sigaction_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ signum,
+ act,
+ oldact,
+ enclave_id,
+ );
+
if status == sgx_status_t::SGX_SUCCESS {
if result == -1 {
set_errno(error);
@@ -2930,11 +2250,18 @@ pub unsafe fn pipe2(fds: *mut c_int, flags: c_int) -> c_int {
result
}
-pub unsafe fn sched_yield() -> c_int {
+pub unsafe fn sigprocmask(signum: c_int, set: *const sigset_t, oldset: *mut sigset_t) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_sched_yield_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int);
+
+ let status = u_sigprocmask_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ signum,
+ set,
+ oldset,
+ );
+
if status == sgx_status_t::SGX_SUCCESS {
if result == -1 {
set_errno(error);
@@ -2946,36 +2273,33 @@ pub unsafe fn sched_yield() -> c_int {
result
}
-pub unsafe fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
- let mut result: c_int = 0;
- let mut error: c_int = 0;
- let status = u_nanosleep_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- rqtp,
- rmtp);
- if status == sgx_status_t::SGX_SUCCESS {
- if result == -1 {
- set_errno(error);
- }
- } else {
- set_errno(ESGX);
+pub unsafe fn raise(signum: c_int) -> c_int {
+ let mut result: c_int = -1;
+
+ let status = u_raise_ocall(&mut result as *mut c_int, signum);
+
+ if status != sgx_status_t::SGX_SUCCESS {
result = -1;
}
result
}
-pub unsafe fn sigaction(signum: c_int,
- act: *const sigaction,
- oldact: *mut sigaction,
- enclave_id: uint64_t) -> c_int {
+pub unsafe fn pthread_sigmask(signum: c_int, set: &sigset_t, oldset: &mut sigset_t) -> c_int {
+ sigprocmask(signum, set, oldset)
+}
+
+pub unsafe fn sched_setaffinity(pid: pid_t, cpusetsize: size_t, mask: *const cpu_set_t) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_sigaction_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- signum,
- act,
- oldact,
- enclave_id);
+
+ let status = u_sched_setaffinity_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ pid,
+ cpusetsize,
+ mask,
+ );
+
if status == sgx_status_t::SGX_SUCCESS {
if result == -1 {
set_errno(error);
@@ -2987,16 +2311,18 @@ pub unsafe fn sigaction(signum: c_int,
result
}
-pub unsafe fn sigprocmask(signum: c_int,
- set: *const sigset_t,
- oldset: *mut sigset_t) -> c_int {
+pub unsafe fn sched_getaffinity(pid: pid_t, cpusetsize: size_t, mask: &mut cpu_set_t) -> c_int {
let mut result: c_int = 0;
let mut error: c_int = 0;
- let status = u_sigprocmask_ocall(&mut result as *mut c_int,
- &mut error as *mut c_int,
- signum,
- set,
- oldset);
+
+ let status = u_sched_getaffinity_ocall(
+ &mut result as *mut c_int,
+ &mut error as *mut c_int,
+ pid,
+ cpusetsize,
+ mask,
+ );
+
if status == sgx_status_t::SGX_SUCCESS {
if result == -1 {
set_errno(error);
@@ -3007,25 +2333,3 @@ pub unsafe fn sigprocmask(signum: c_int,
}
result
}
-
-pub unsafe fn raise(signum: c_int) -> c_int {
- let mut result: c_int = -1;
- let status = u_raise_ocall(&mut result as *mut c_int, signum);
- if status != sgx_status_t::SGX_SUCCESS {
- result = -1;
- }
- result
-}
-
-pub unsafe fn pthread_sigmask(signum: c_int, set: &sigset_t, oldset: &mut sigset_t) -> c_int {
- sigprocmask(signum, set, oldset)
-}
-
-pub unsafe fn getpid() -> pid_t {
- let mut result = -1;
- let status = u_getpid_ocall(&mut result as *mut pid_t);
- if status != sgx_status_t::SGX_SUCCESS {
- result = -1;
- }
- result
-}
diff --git a/sgx_libc/src/macros.rs b/sgx_libc/src/macros.rs
index e105de9..c40bb05 100644
--- a/sgx_libc/src/macros.rs
+++ b/sgx_libc/src/macros.rs
@@ -161,3 +161,46 @@ macro_rules! align_const {
};
)*)
}
+
+macro_rules! bail {
+ ($e:expr) => {
+ return Err($e);
+ };
+}
+
+macro_rules! ensure {
+ ($cond:expr) => {
+ if !($cond) {
+ bail!(OCallError::from_custom_error(stringify!($cond)));
+ }
+ };
+ ($cond:expr, $e:expr) => {
+ if !($cond) {
+ bail!($e);
+ }
+ };
+}
+
+macro_rules! esgx {
+ ($status:ident) => {
+ OCallError::from_sgx_error($status)
+ };
+}
+
+macro_rules! eos {
+ ($errno:ident) => {
+ OCallError::from_os_error($errno)
+ };
+}
+
+macro_rules! ecust {
+ ($lt:literal) => {
+ OCallError::from_custom_error($lt)
+ };
+}
+
+macro_rules! egai {
+ ($errno:ident) => {
+ OCallError::from_gai_error($errno)
+ };
+}
diff --git a/sgx_trts/src/memchr.rs b/sgx_libc/src/memchr.rs
similarity index 65%
rename from sgx_trts/src/memchr.rs
rename to sgx_libc/src/memchr.rs
index ea27c07..d6bec9d 100644
--- a/sgx_trts/src/memchr.rs
+++ b/sgx_libc/src/memchr.rs
@@ -15,6 +15,8 @@
// specific language governing permissions and limitations
// under the License..
+use core::ptr;
+
/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
@@ -36,7 +38,12 @@
// }
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
- let p = unsafe { sgx_libc::memchr(haystack.as_ptr(), needle, haystack.len()) };
+ let p = unsafe {
+ memchr_impl(
+ haystack.as_ptr(),
+ needle,
+ haystack.len())
+ };
if p.is_null() {
None
} else {
@@ -44,19 +51,50 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
}
}
+unsafe fn memchr_impl(s: *const u8, c: u8, n: usize) -> *const u8 {
+ let mut ret = ptr::null();
+ let mut p = s;
+ for _ in 0..n {
+ if *p == c {
+ ret = p;
+ break;
+ }
+ p = p.offset(1);
+ }
+ ret
+}
+
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
if haystack.is_empty() {
return None;
}
- let p = unsafe { sgx_libc::memrchr(haystack.as_ptr(), needle, haystack.len()) };
- if p.is_null() {
- None
- } else {
- Some(p as usize - (haystack.as_ptr() as usize))
- }
+ let p = unsafe {
+ memrchr_impl(
+ haystack.as_ptr(),
+ needle,
+ haystack.len(),
+ )
+ };
+ if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
}
memrchr_specific(needle, haystack)
}
+
+unsafe fn memrchr_impl(s: *const u8, c: u8, n: usize) -> *const u8 {
+ if n == 0 {
+ return ptr::null();
+ }
+ let mut ret = ptr::null();
+ let mut p: *const u8 = (s as usize + (n - 1)) as *const u8;
+ for _ in 0..n {
+ if *p == c {
+ ret = p;
+ break;
+ }
+ p = p.offset(-1);
+ }
+ ret
+}
diff --git a/sgx_trts/src/lib.rs b/sgx_trts/src/lib.rs
index e22093d..7e2f02a 100644
--- a/sgx_trts/src/lib.rs
+++ b/sgx_trts/src/lib.rs
@@ -67,7 +67,6 @@
#![feature(allocator_api)]
#![feature(asm)]
-#![feature(const_raw_ptr_deref)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
@@ -86,12 +85,9 @@ extern crate alloc;
#[macro_use]
mod macros;
-pub mod ascii;
-pub mod c_str;
pub mod cpu_feature;
pub mod cpuid;
pub mod enclave;
-pub mod memchr;
pub mod memeq;
pub mod oom;
pub mod trts;
@@ -105,6 +101,10 @@ pub mod libc {
pub use sgx_libc::*;
}
+pub use libc::c_str;
+pub use libc::ascii;
+pub use libc::memchr;
+
pub mod error {
pub use sgx_libc::{errno, error_string, set_errno};
}
diff --git a/sgx_tstd/src/io/error.rs b/sgx_tstd/src/io/error.rs
index 1f1ccaf..9b4f2ef 100644
--- a/sgx_tstd/src/io/error.rs
+++ b/sgx_tstd/src/io/error.rs
@@ -15,15 +15,14 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_types::sgx_status_t;
use crate::error;
use crate::sys;
+use alloc_crate::boxed::Box;
+use alloc_crate::str;
+use core::convert::From;
use core::fmt;
use core::result;
-use core::convert::From;
-use alloc_crate::str;
-use alloc_crate::boxed::Box;
-
+use sgx_types::sgx_status_t;
/// A specialized [`Result`](../result/enum.Result.html) type for I/O
/// operations.
@@ -188,14 +187,30 @@ impl From<ErrorKind> for Error {
///
#[inline]
fn from(kind: ErrorKind) -> Error {
- Error { repr: Repr::Simple(kind) }
+ Error {
+ repr: Repr::Simple(kind),
+ }
}
}
impl From<sgx_status_t> for Error {
#[inline]
fn from(status: sgx_status_t) -> Error {
- Error { repr: Repr::SgxStatus(status) }
+ Error {
+ repr: Repr::SgxStatus(status),
+ }
+ }
+}
+
+use sgx_libc::OCallError;
+impl From<OCallError> for Error {
+ fn from(e: OCallError) -> Error {
+ match e {
+ OCallError::SgxError(status) => Error::from_sgx_error(status),
+ OCallError::OsError(errno) => Error::from_raw_os_error(errno),
+ OCallError::GaiError(errno) => Error::new(ErrorKind::Other, sgx_libc::gai_error_str(errno)),
+ OCallError::CustomError(err) => Error::new(ErrorKind::Other, err),
+ }
}
}
@@ -215,7 +230,9 @@ impl Error {
}
fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
- Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
+ Error {
+ repr: Repr::Custom(Box::new(Custom { kind, error })),
+ }
}
/// Returns an error representing the last OS error which occurred.
@@ -231,7 +248,9 @@ impl Error {
/// Creates a new instance of an `Error` from a particular OS error code.
///
pub fn from_raw_os_error(code: i32) -> Error {
- Error { repr: Repr::Os(code) }
+ Error {
+ repr: Repr::Os(code),
+ }
}
/// Returns the OS error that this error represents (if any).
@@ -252,7 +271,9 @@ impl Error {
/// Creates a new instance of an `Error` from a particular SGX error status.
///
pub fn from_sgx_error(status: sgx_status_t) -> Error {
- Error { repr: Repr::SgxStatus(status) }
+ Error {
+ repr: Repr::SgxStatus(status),
+ }
}
/// Returns the SGX error that this error represents (if any).
@@ -275,7 +296,7 @@ impl Error {
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
///
- pub fn get_ref(&self) -> Option<&(dyn error::Error+Send+Sync+'static)> {
+ pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
@@ -392,7 +413,7 @@ impl error::Error for Error {
}
fn _assert_error_is_sync_send() {
- fn _is_sync_send<T: Sync+Send>() {}
+ fn _is_sync_send<T: Sync + Send>() {}
_is_sync_send::<Error>();
}
@@ -400,4 +421,4 @@ impl error::Error for sgx_status_t {
fn description(&self) -> &str {
self.__description()
}
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/net/addr.rs b/sgx_tstd/src/net/addr.rs
index a4dbc4f..b57030a 100644
--- a/sgx_tstd/src/net/addr.rs
+++ b/sgx_tstd/src/net/addr.rs
@@ -15,21 +15,22 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_trts::libc as c;
-use core::fmt;
-use core::hash;
-use core::mem;
-use core::option;
-use core::iter;
-#[cfg(feature = "net")]
-use core::convert::TryInto;
-use alloc_crate::vec;
-use alloc_crate::slice;
use crate::io;
use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr};
-use crate::sys_common::{AsInner, FromInner, IntoInner};
#[cfg(feature = "net")]
use crate::sys_common::net::LookupHost;
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+use alloc_crate::slice;
+use alloc_crate::vec;
+#[cfg(feature = "net")]
+use core::convert::TryInto;
+use core::convert::TryFrom;
+use core::fmt;
+use core::hash;
+use core::iter;
+use core::mem;
+use core::option;
+use sgx_trts::libc as c;
/// An internet socket address, either IPv4 or IPv6.
///
@@ -319,12 +320,47 @@ impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
impl<'a> IntoInner<(*const c::sockaddr, c::socklen_t)> for &'a SocketAddr {
fn into_inner(self) -> (*const c::sockaddr, c::socklen_t) {
match *self {
- SocketAddr::V4(ref a) => {
- (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
- }
- SocketAddr::V6(ref a) => {
- (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
- }
+ SocketAddr::V4(ref a) => (
+ a as *const _ as *const _,
+ mem::size_of_val(a) as c::socklen_t,
+ ),
+ SocketAddr::V6(ref a) => (
+ a as *const _ as *const _,
+ mem::size_of_val(a) as c::socklen_t,
+ ),
+ }
+ }
+}
+
+impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
+ fn into_inner(self) -> c::sockaddr_in {
+ self.inner
+ }
+}
+
+impl IntoInner<c::sockaddr_in6> for SocketAddrV6 {
+ fn into_inner(self) -> c::sockaddr_in6 {
+ self.inner
+ }
+}
+
+impl From<SocketAddr> for c::SockAddr {
+ fn from(addr: SocketAddr) -> c::SockAddr {
+ match addr {
+ SocketAddr::V4(sa) => c::SockAddr::IN4(sa.into_inner()),
+ SocketAddr::V6(sa) => c::SockAddr::IN6(sa.into_inner()),
+ }
+ }
+}
+
+impl TryFrom<c::SockAddr> for SocketAddr {
+ type Error = io::Error;
+
+ fn try_from(addr: c::SockAddr) -> io::Result<SocketAddr> {
+ match addr {
+ c::SockAddr::IN4(sa) => Ok(SocketAddr::V4(SocketAddrV4::from_inner(sa))),
+ c::SockAddr::IN6(sa) => Ok(SocketAddr::V6(SocketAddrV6::from_inner(sa))),
+ _ => Err(io::Error::new(io::ErrorKind::InvalidData, "Unsupported SocketAddr")),
}
}
}
@@ -548,7 +584,10 @@ impl ToSocketAddrs for (&str, u16) {
}
#[cfg(not(feature = "net"))]
- let r = Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address"));
+ let r = Err(io::Error::new(
+ io::ErrorKind::InvalidInput,
+ "invalid socket address",
+ ));
#[cfg(feature = "net")]
let r = resolve_socket_addr((host, port).try_into()?);
r
@@ -565,7 +604,10 @@ impl ToSocketAddrs for str {
}
#[cfg(not(feature = "net"))]
- let r = Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address"));
+ let r = Err(io::Error::new(
+ io::ErrorKind::InvalidInput,
+ "invalid socket address",
+ ));
#[cfg(feature = "net")]
let r = resolve_socket_addr(self.try_into()?);
r
@@ -592,4 +634,4 @@ impl ToSocketAddrs for String {
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
(&**self).to_socket_addrs()
}
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys/ext/net.rs b/sgx_tstd/src/sys/ext/net.rs
index 65c3249..620ff0e 100644
--- a/sgx_tstd/src/sys/ext/net.rs
+++ b/sgx_tstd/src/sys/ext/net.rs
@@ -15,8 +15,6 @@
// specific language governing permissions and limitations
// under the License..
-use core::mem;
-use core::fmt;
use crate::ascii;
use crate::ffi::OsStr;
use crate::io::{self, Initializer, IoSlice, IoSliceMut};
@@ -24,10 +22,13 @@ use crate::net::{self, Shutdown};
use crate::os::unix::ffi::OsStrExt;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::path::Path;
-use crate::time::Duration;
-use crate::sys::{self, cvt};
use crate::sys::net::Socket;
+use crate::sys::{self, cvt_ocall};
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
+use crate::time::Duration;
+use core::convert::{TryFrom, TryInto};
+use core::fmt;
+use core::mem;
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
// Work with an actual instance of the type since using a null pointer is UB
@@ -86,14 +87,10 @@ pub struct SocketAddr {
impl SocketAddr {
fn new<F>(f: F) -> io::Result<SocketAddr>
where
- F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int,
+ F: FnOnce() -> libc::OCallResult<libc::SockAddr>,
{
- unsafe {
- let mut addr: libc::sockaddr_un = mem::zeroed();
- let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
- cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
- SocketAddr::from_parts(addr, len)
- }
+ let addr = cvt_ocall(f())?;
+ addr.try_into()
}
fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
@@ -114,13 +111,21 @@ impl SocketAddr {
/// Returns `true` if the address is unnamed.
///
pub fn is_unnamed(&self) -> bool {
- if let AddressKind::Unnamed = self.address() { true } else { false }
+ if let AddressKind::Unnamed = self.address() {
+ true
+ } else {
+ false
+ }
}
/// Returns the contents of this address if it is a `pathname` address.
///
pub fn as_pathname(&self) -> Option<&Path> {
- if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
+ if let AddressKind::Pathname(path) = self.address() {
+ Some(path)
+ } else {
+ None
+ }
}
fn address(&self) -> AddressKind<'_> {
@@ -128,8 +133,7 @@ impl SocketAddr {
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
// macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
- if len == 0
- {
+ if len == 0 {
AddressKind::Unnamed
} else if self.addr.sun_path[0] == 0 {
AddressKind::Abstract(&path[1..len])
@@ -149,6 +153,20 @@ impl fmt::Debug for SocketAddr {
}
}
+impl TryFrom<libc::SockAddr> for SocketAddr {
+ type Error = io::Error;
+
+ fn try_from(addr: libc::SockAddr) -> io::Result<SocketAddr> {
+ match addr {
+ libc::SockAddr::UN((sa, len)) => SocketAddr::from_parts(sa, len),
+ _ => Err(io::Error::new(
+ io::ErrorKind::InvalidData,
+ "Unsupported SocketAddr",
+ )),
+ }
+ }
+}
+
struct AsciiEscaped<'a>(&'a [u8]);
impl<'a> fmt::Display for AsciiEscaped<'a> {
@@ -186,9 +204,9 @@ impl UnixStream {
fn inner(path: &Path) -> io::Result<UnixStream> {
unsafe {
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
- let (addr, len) = sockaddr_un(path)?;
+ let addr = libc::SockAddr::UN(sockaddr_un(path)?);
- cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
+ cvt_ocall(libc::connect(*inner.as_inner(), &addr))?;
Ok(UnixStream(inner))
}
}
@@ -218,13 +236,13 @@ impl UnixStream {
/// Returns the socket address of the local half of this connection.
///
pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+ SocketAddr::new(|| unsafe { libc::getsockname(*self.0.as_inner()) })
}
/// Returns the socket address of the remote half of this connection.
///
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
+ SocketAddr::new(|| unsafe { libc::getpeername(*self.0.as_inner()) })
}
/// Sets the read timeout for the socket.
@@ -450,9 +468,10 @@ impl UnixListener {
unsafe {
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
let (addr, len) = sockaddr_un(path)?;
+ let sock_addr = libc::SockAddr::UN((addr, len));
- cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
- cvt(libc::listen(*inner.as_inner(), 128))?;
+ cvt_ocall(libc::bind(*inner.as_inner(), &sock_addr))?;
+ cvt_ocall(libc::listen(*inner.as_inner(), 128))?;
Ok(UnixListener(inner))
}
@@ -467,11 +486,9 @@ impl UnixListener {
/// the remote peer's address will be returned.
///
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
- let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
- let mut len = mem::size_of_val(&storage) as libc::socklen_t;
- let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
- let addr = SocketAddr::from_parts(storage, len)?;
- Ok((UnixStream(sock), addr))
+ let (sock, addr) = self.0.accept()?;
+ let sa = addr.try_into()?;
+ Ok((UnixStream(sock), sa))
}
/// Creates a new independently owned handle to the underlying socket.
@@ -487,7 +504,7 @@ impl UnixListener {
/// Returns the local socket address of this listener.
///
pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+ SocketAddr::new(|| unsafe { libc::getsockname(*self.0.as_inner()) })
}
/// Moves the socket into or out of nonblocking mode.
@@ -592,8 +609,9 @@ impl UnixDatagram {
unsafe {
let socket = UnixDatagram::unbound()?;
let (addr, len) = sockaddr_un(path)?;
+ let sock_addr = libc::SockAddr::UN((addr, len));
- cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
+ cvt_ocall(libc::bind(*socket.0.as_inner(), &sock_addr))?;
Ok(socket)
}
@@ -629,10 +647,8 @@ impl UnixDatagram {
pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
unsafe {
- let (addr, len) = sockaddr_un(path)?;
-
- cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
-
+ let addr = libc::SockAddr::UN(sockaddr_un(path)?);
+ cvt_ocall(libc::connect(*d.0.as_inner(), &addr))?;
Ok(())
}
}
@@ -652,7 +668,7 @@ impl UnixDatagram {
/// Returns the address of this socket.
///
pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+ SocketAddr::new(|| unsafe { libc::getsockname(*self.0.as_inner()) })
}
/// Returns the address of this socket's peer.
@@ -662,7 +678,7 @@ impl UnixDatagram {
/// [`connect`]: #method.connect
///
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
+ SocketAddr::new(|| unsafe { libc::getpeername(*self.0.as_inner()) })
}
/// Receives data from the socket.
@@ -671,26 +687,11 @@ impl UnixDatagram {
/// whence the data came.
///
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- let mut count = 0;
- let addr = SocketAddr::new(|addr, len| unsafe {
- count = libc::recvfrom(
- *self.0.as_inner(),
- buf.as_mut_ptr() as *mut _,
- buf.len(),
- 0,
- addr,
- len,
- );
- if count > 0 {
- 1
- } else if count == 0 {
- 0
- } else {
- -1
- }
- })?;
-
- Ok((count as usize, addr))
+ unsafe {
+ let (count, addr) = cvt_ocall(libc::recvfrom(*self.0.as_inner(), buf, 0))?;
+ let addr = addr.try_into()?;
+ Ok((count as usize, addr))
+ }
}
/// Receives data from the socket.
@@ -708,15 +709,13 @@ impl UnixDatagram {
pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
unsafe {
- let (addr, len) = sockaddr_un(path)?;
+ let addr = libc::SockAddr::UN(sockaddr_un(path)?);
- let count = cvt(libc::sendto(
+ let count = cvt_ocall(libc::sendto(
*d.0.as_inner(),
- buf.as_ptr() as *const _,
- buf.len(),
+ buf,
libc::MSG_NOSIGNAL,
- &addr as *const _ as *const _,
- len,
+ &addr,
))?;
Ok(count as usize)
}
@@ -820,6 +819,8 @@ impl IntoRawFd for UnixDatagram {
}
mod libc {
+ pub use sgx_trts::libc::ocall::{
+ bind, connect, getpeername, getsockname, listen, recvfrom, sendto,
+ };
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{connect, listen, bind, sendto, recvfrom, getsockname, getpeername};
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys/fd.rs b/sgx_tstd/src/sys/fd.rs
index 430e86f..8b6f5f7 100644
--- a/sgx_tstd/src/sys/fd.rs
+++ b/sgx_tstd/src/sys/fd.rs
@@ -15,13 +15,13 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_trts::libc::{c_int, c_void, ssize_t};
-use core::cmp;
-use core::mem;
-use core::sync::atomic::{AtomicBool, Ordering};
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
-use crate::sys::cvt;
+use crate::sys::cvt_ocall;
use crate::sys_common::AsInner;
+use core::mem;
+use core::sync::atomic::{AtomicBool, Ordering};
+use sgx_trts::libc::{c_int, ssize_t};
+use core::ops::{Deref, DerefMut};
#[derive(Debug)]
pub struct FileDesc {
@@ -61,18 +61,16 @@ impl FileDesc {
}
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
- })?;
+ let ret = cvt_ocall(unsafe { libc::read(self.fd, buf) })?;
Ok(ret as usize)
}
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
- let ret = cvt(unsafe {
+ let vbufs: Vec<&mut [u8]> = bufs.iter_mut().map(|msl| msl.deref_mut()).collect();
+ let ret = cvt_ocall(unsafe {
libc::readv(
self.fd,
- bufs.as_ptr() as *const libc::iovec,
- cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
+ vbufs
)
})?;
Ok(ret as usize)
@@ -84,77 +82,41 @@ impl FileDesc {
}
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- unsafe fn cvt_pread64(
- fd: c_int,
- buf: *mut c_void,
- count: usize,
- offset: i64,
- ) -> io::Result<isize> {
- use libc::pread64;
- cvt(pread64(fd, buf, count, offset))
- }
-
- unsafe {
- cvt_pread64(
- self.fd,
- buf.as_mut_ptr() as *mut c_void,
- cmp::min(buf.len(), max_len()),
- offset as i64,
- )
- .map(|n| n as usize)
- }
+ cvt_ocall(unsafe { libc::pread64(self.fd, buf, offset as i64) })
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
- })?;
+ let ret = cvt_ocall(unsafe { libc::write(self.fd, buf) })?;
Ok(ret as usize)
}
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
- let ret = cvt(unsafe {
+ let vbufs: Vec<&[u8]> = bufs.iter().map(|msl| msl.deref()).collect();
+ let ret = cvt_ocall(unsafe {
libc::writev(
self.fd,
- bufs.as_ptr() as *const libc::iovec,
- cmp::min(bufs.len(), c_int::max_value() as usize) as c_int,
+ vbufs
)
})?;
Ok(ret as usize)
}
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- unsafe fn cvt_pwrite64(
- fd: c_int,
- buf: *const c_void,
- count: usize,
- offset: i64,
- ) -> io::Result<isize> {
- use libc::pwrite64;
- cvt(pwrite64(fd, buf, count, offset))
- }
-
- unsafe {
- cvt_pwrite64(
- self.fd,
- buf.as_ptr() as *const c_void,
- cmp::min(buf.len(), max_len()),
- offset as i64,
- )
- .map(|n| n as usize)
- }
+ cvt_ocall(unsafe { libc::pwrite64(self.fd, buf, offset as i64) })
}
pub fn get_cloexec(&self) -> io::Result<bool> {
- unsafe { Ok((cvt(libc::fcntl_arg0(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
+ unsafe {
+ Ok((cvt_ocall(libc::fcntl_arg0(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
+ }
}
pub fn set_cloexec(&self) -> io::Result<()> {
unsafe {
- let previous = cvt(libc::fcntl_arg0(self.fd, libc::F_GETFD))?;
+ let previous = cvt_ocall(libc::fcntl_arg0(self.fd, libc::F_GETFD))?;
let new = previous | libc::FD_CLOEXEC;
if new != previous {
- cvt(libc::fcntl_arg1(self.fd, libc::F_SETFD, new))?;
+ cvt_ocall(libc::fcntl_arg1(self.fd, libc::F_SETFD, new))?;
}
Ok(())
}
@@ -163,7 +125,11 @@ impl FileDesc {
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
unsafe {
let mut v = nonblocking as c_int;
- cvt(libc::ioctl_arg1(self.fd, libc::FIONBIO, &mut v as *mut c_int))?;
+ cvt_ocall(libc::ioctl_arg1(
+ self.fd,
+ libc::FIONBIO,
+ &mut v,
+ ))?;
Ok(())
}
}
@@ -194,7 +160,7 @@ impl FileDesc {
static TRY_CLOEXEC: AtomicBool = AtomicBool::new(!cfg!(target_os = "android"));
let fd = self.raw();
if TRY_CLOEXEC.load(Ordering::Relaxed) {
- match cvt(unsafe { libc::fcntl_arg1(fd, F_DUPFD_CLOEXEC, 0) }) {
+ match unsafe { libc::fcntl_arg1(fd, F_DUPFD_CLOEXEC, 0) } {
// We *still* call the `set_cloexec` method as apparently some
// linux kernel at some point stopped setting CLOEXEC even
// though it reported doing so on F_DUPFD_CLOEXEC.
@@ -205,13 +171,13 @@ impl FileDesc {
FileDesc::new(fd)
});
}
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
+ Err(ref e) if e.equal_to_os_error(libc::EINVAL) => {
TRY_CLOEXEC.store(false, Ordering::Relaxed);
}
- Err(e) => return Err(e),
+ Err(e) => return cvt_ocall(Err(e)),
}
}
- cvt(unsafe { libc::fcntl_arg1(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc)
+ cvt_ocall(unsafe { libc::fcntl_arg1(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc)
}
}
@@ -244,8 +210,9 @@ impl Drop for FileDesc {
}
mod libc {
+ pub use sgx_trts::libc::ocall::{
+ close, fcntl_arg0, fcntl_arg1, ioctl_arg0, ioctl_arg1, pread64, pwrite64, read, readv,
+ write, writev,
+ };
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{read, pread64, write, pwrite64, readv, writev,
- fcntl_arg0, fcntl_arg1, ioctl_arg0, ioctl_arg1,
- close};
}
diff --git a/sgx_tstd/src/sys/fs.rs b/sgx_tstd/src/sys/fs.rs
index d701810..7884f5a 100644
--- a/sgx_tstd/src/sys/fs.rs
+++ b/sgx_tstd/src/sys/fs.rs
@@ -15,17 +15,17 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_trts::libc::{c_int, mode_t, time_t, stat64, off64_t, DIR, dirent64};
-use crate::os::unix::prelude::*;
use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
+use crate::os::unix::prelude::*;
use crate::path::{Path, PathBuf};
use crate::sys::fd::FileDesc;
use crate::sys::time::SystemTime;
-use crate::sys::{cvt, cvt_r};
+use crate::sys::{cvt_ocall, cvt_ocall_r};
use crate::sys_common::{AsInner, FromInner};
-use core::{fmt, mem, ptr};
use alloc_crate::sync::Arc;
+use core::{fmt, mem, ptr};
+use sgx_trts::libc::{c_int, dirent64, mode_t, off64_t, stat64, time_t, DIR};
pub use crate::sys_common::fs::remove_dir_all;
@@ -37,9 +37,9 @@ pub struct FileAttr {
}
#[derive(Debug)]
-pub struct DirBuilder {
+pub struct DirBuilder {
mode: mode_t,
- }
+}
// all DirEntry's will have a reference to this struct
struct InnerReadDir {
@@ -98,11 +98,15 @@ impl FileAttr {
self.stat.st_size as u64
}
pub fn perm(&self) -> FilePermissions {
- FilePermissions { mode: (self.stat.st_mode as mode_t) }
+ FilePermissions {
+ mode: (self.stat.st_mode as mode_t),
+ }
}
pub fn file_type(&self) -> FileType {
- FileType { mode: self.stat.st_mode as mode_t }
+ FileType {
+ mode: self.stat.st_mode as mode_t,
+ }
}
}
@@ -174,7 +178,9 @@ impl FileType {
impl FromInner<u32> for FilePermissions {
fn from_inner(mode: u32) -> FilePermissions {
- FilePermissions { mode: mode as mode_t }
+ FilePermissions {
+ mode: mode as mode_t,
+ }
}
}
@@ -195,10 +201,14 @@ impl Iterator for ReadDir {
}
unsafe {
- let mut ret = DirEntry { entry: mem::zeroed(), dir: self.clone() };
+ let mut ret = DirEntry {
+ entry: mem::zeroed(),
+ dir: self.clone(),
+ };
let mut entry_ptr = ptr::null_mut();
loop {
- if libc::readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+ if let Err(e) = libc::readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr)
+ {
if entry_ptr.is_null() {
// We encountered an error (which will be returned in this iteration), but
// we also reached the end of the directory stream. The `end_of_stream`
@@ -206,8 +216,9 @@ impl Iterator for ReadDir {
// (instead of looping forever)
self.end_of_stream = true;
}
- return Some(Err(Error::last_os_error()));
- }
+ return Some(Err(e.into()));
+ };
+
if entry_ptr.is_null() {
return None;
}
@@ -222,13 +233,16 @@ impl Iterator for ReadDir {
impl Drop for Dir {
fn drop(&mut self) {
let r = unsafe { libc::closedir(self.0) };
- debug_assert_eq!(r, 0);
+ debug_assert!(r.is_ok());
}
}
impl DirEntry {
pub fn path(&self) -> PathBuf {
- self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
+ self.dir
+ .inner
+ .root
+ .join(OsStr::from_bytes(self.name_bytes()))
}
pub fn file_name(&self) -> OsString {
@@ -236,23 +250,47 @@ impl DirEntry {
}
pub fn metadata(&self) -> io::Result<FileAttr> {
- let fd = cvt(unsafe {libc::dirfd(self.dir.inner.dirp.0)})?;
+ let fd = cvt_ocall(unsafe { libc::dirfd(self.dir.inner.dirp.0) })?;
let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe {
- libc::fstatat64(fd, self.entry.d_name.as_ptr(), &mut stat, libc::AT_SYMLINK_NOFOLLOW)
+
+ let dname_bytes: Vec<u8> = self.entry.d_name.iter().map(|b| *b as u8).collect();
+ let v = unsafe { libc::shrink_to_fit_os_string(dname_bytes) }?;
+ let dname = CString::new(v)?;
+
+ cvt_ocall(unsafe {
+ libc::fstatat64(
+ fd,
+ &dname,
+ &mut stat,
+ libc::AT_SYMLINK_NOFOLLOW,
+ )
})?;
Ok(FileAttr { stat })
}
pub fn file_type(&self) -> io::Result<FileType> {
match self.entry.d_type {
- libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
- libc::DT_FIFO => Ok(FileType { mode: libc::S_IFIFO }),
- libc::DT_LNK => Ok(FileType { mode: libc::S_IFLNK }),
- libc::DT_REG => Ok(FileType { mode: libc::S_IFREG }),
- libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }),
- libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }),
- libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }),
+ libc::DT_CHR => Ok(FileType {
+ mode: libc::S_IFCHR,
+ }),
+ libc::DT_FIFO => Ok(FileType {
+ mode: libc::S_IFIFO,
+ }),
+ libc::DT_LNK => Ok(FileType {
+ mode: libc::S_IFLNK,
+ }),
+ libc::DT_REG => Ok(FileType {
+ mode: libc::S_IFREG,
+ }),
+ libc::DT_SOCK => Ok(FileType {
+ mode: libc::S_IFSOCK,
+ }),
+ libc::DT_DIR => Ok(FileType {
+ mode: libc::S_IFDIR,
+ }),
+ libc::DT_BLK => Ok(FileType {
+ mode: libc::S_IFBLK,
+ }),
_ => lstat(&self.path()).map(|m| m.file_type()),
}
}
@@ -310,11 +348,11 @@ impl OpenOptions {
fn get_access_mode(&self) -> io::Result<c_int> {
match (self.read, self.write, self.append) {
- (true, false, false) => Ok(libc::O_RDONLY),
- (false, true, false) => Ok(libc::O_WRONLY),
- (true, true, false) => Ok(libc::O_RDWR),
- (false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
- (true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
+ (true, false, false) => Ok(libc::O_RDONLY),
+ (false, true, false) => Ok(libc::O_WRONLY),
+ (true, true, false) => Ok(libc::O_RDWR),
+ (false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
+ (true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
(false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)),
}
}
@@ -335,12 +373,12 @@ impl OpenOptions {
}
Ok(match (self.create, self.truncate, self.create_new) {
- (false, false, false) => 0,
- (true, false, false) => libc::O_CREAT,
- (false, true, false) => libc::O_TRUNC,
- (true, true, false) => libc::O_CREAT | libc::O_TRUNC,
- (_, _, true) => libc::O_CREAT | libc::O_EXCL,
- })
+ (false, false, false) => 0,
+ (true, false, false) => libc::O_CREAT,
+ (false, true, false) => libc::O_TRUNC,
+ (true, true, false) => libc::O_CREAT | libc::O_TRUNC,
+ (_, _, true) => libc::O_CREAT | libc::O_EXCL,
+ })
}
}
@@ -355,7 +393,7 @@ impl File {
| opts.get_access_mode()?
| opts.get_creation_mode()?
| (opts.custom_flags as c_int & !libc::O_ACCMODE);
- let fd = cvt_r(|| unsafe { libc::open64(path.as_ptr(), flags, opts.mode as c_int) })?;
+ let fd = cvt_ocall_r(|| unsafe { libc::open64(path, flags, opts.mode as c_int) })?;
let fd = FileDesc::new(fd);
// Currently the standard library supports Linux 2.6.18 which did not
@@ -404,29 +442,26 @@ impl File {
pub fn file_attr(&self) -> io::Result<FileAttr> {
let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe { libc::fstat64(self.0.raw(), &mut stat) })?;
+ cvt_ocall(unsafe { libc::fstat64(self.0.raw(), &mut stat) })?;
Ok(FileAttr::from_stat64(stat))
}
pub fn fsync(&self) -> io::Result<()> {
- cvt_r(|| unsafe { libc::fsync(self.0.raw()) })?;
+ cvt_ocall_r(|| unsafe { libc::fsync(self.0.raw()) })?;
Ok(())
}
pub fn datasync(&self) -> io::Result<()> {
- cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
+ cvt_ocall_r(|| unsafe { libc::fdatasync(self.0.raw()) })?;
return Ok(());
-
- unsafe fn os_datasync(fd: c_int) -> c_int {
- libc::fdatasync(fd)
- }
}
pub fn truncate(&self, size: u64) -> io::Result<()> {
use crate::convert::TryInto;
- let size: off64_t =
- size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
- cvt_r(|| unsafe { libc::ftruncate64(self.0.raw(), size) }).map(drop)
+ let size: off64_t = size
+ .try_into()
+ .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
+ cvt_ocall_r(|| unsafe { libc::ftruncate64(self.0.raw(), size) }).map(drop)
}
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
@@ -466,7 +501,7 @@ impl File {
SeekFrom::Current(off) => (libc::SEEK_CUR, off),
};
- let n = cvt(unsafe { libc::lseek64(self.0.raw(), pos, whence) })?;
+ let n = cvt_ocall(unsafe { libc::lseek64(self.0.raw(), pos, whence) })?;
Ok(n as u64)
}
@@ -483,7 +518,7 @@ impl File {
}
pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
- cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
+ cvt_ocall_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
Ok(())
}
}
@@ -495,7 +530,7 @@ impl DirBuilder {
pub fn mkdir(&self, p: &Path) -> io::Result<()> {
let p = cstr(p)?;
- cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?;
+ cvt_ocall(unsafe { libc::mkdir(&p, self.mode) })?;
Ok(())
}
@@ -523,15 +558,14 @@ impl fmt::Debug for File {
}
fn get_mode(fd: c_int) -> Option<(bool, bool)> {
- let mode = unsafe { libc::fcntl_arg0(fd, libc::F_GETFL) };
- if mode == -1 {
- return None;
- }
- match mode & libc::O_ACCMODE {
- libc::O_RDONLY => Some((true, false)),
- libc::O_RDWR => Some((true, true)),
- libc::O_WRONLY => Some((false, true)),
- _ => None,
+ match unsafe { libc::fcntl_arg0(fd, libc::F_GETFL) } {
+ Err(_) => None,
+ Ok(mode) => match mode & libc::O_ACCMODE {
+ libc::O_RDONLY => Some((true, false)),
+ libc::O_RDWR => Some((true, true)),
+ libc::O_WRONLY => Some((false, true)),
+ _ => None,
+ },
}
}
@@ -552,108 +586,81 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
let root = p.to_path_buf();
let p = cstr(p)?;
unsafe {
- let ptr = libc::opendir(p.as_ptr());
- if ptr.is_null() {
- Err(Error::last_os_error())
- } else {
- let inner = InnerReadDir { dirp: Dir(ptr), root };
- Ok(ReadDir { inner: Arc::new(inner), end_of_stream: false })
- }
+ let ptr = cvt_ocall(libc::opendir(&p))?;
+ let inner = InnerReadDir {
+ dirp: Dir(ptr),
+ root,
+ };
+ Ok(ReadDir {
+ inner: Arc::new(inner),
+ end_of_stream: false,
+ })
}
}
pub fn unlink(p: &Path) -> io::Result<()> {
let p = cstr(p)?;
- cvt(unsafe { libc::unlink(p.as_ptr()) })?;
+ cvt_ocall(unsafe { libc::unlink(&p) })?;
Ok(())
}
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
let old = cstr(old)?;
let new = cstr(new)?;
- cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?;
+ cvt_ocall(unsafe { libc::rename(&old, &new) })?;
Ok(())
}
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
let p = cstr(p)?;
- cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?;
+ cvt_ocall_r(|| unsafe { libc::chmod(&p, perm.mode) })?;
Ok(())
}
pub fn rmdir(p: &Path) -> io::Result<()> {
let p = cstr(p)?;
- cvt(unsafe { libc::rmdir(p.as_ptr()) })?;
+ cvt_ocall(unsafe { libc::rmdir(&p) })?;
Ok(())
}
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
let c_path = cstr(p)?;
- let p = c_path.as_ptr();
-
- let mut buf = Vec::with_capacity(256);
-
- loop {
- let buf_read =
- cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize;
-
- unsafe {
- buf.set_len(buf_read);
- }
-
- if buf_read != buf.capacity() {
- buf.shrink_to_fit();
-
- return Ok(PathBuf::from(OsString::from_vec(buf)));
- }
-
- // Trigger the internal buffer resizing logic of `Vec` by requiring
- // more space than the current capacity. The length is guaranteed to be
- // the same as the capacity due to the if statement above.
- buf.reserve(1);
- }
+ let v = cvt_ocall(unsafe { libc::readlink(&c_path) })?;
+ return Ok(PathBuf::from(OsString::from_vec(v)));
}
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
let src = cstr(src)?;
let dst = cstr(dst)?;
- cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })?;
+ cvt_ocall(unsafe { libc::symlink(&src, &dst) })?;
Ok(())
}
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
let src = cstr(src)?;
let dst = cstr(dst)?;
- cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?;
+ cvt_ocall(unsafe { libc::link(&src, &dst) })?;
Ok(())
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
let p = cstr(p)?;
let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe { libc::stat64(p.as_ptr(), &mut stat as *mut _) })?;
+ cvt_ocall(unsafe { libc::stat64(&p, &mut stat) })?;
Ok(FileAttr::from_stat64(stat))
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
let p = cstr(p)?;
let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe { libc::lstat64(p.as_ptr(), &mut stat as *mut _) })?;
+ cvt_ocall(unsafe { libc::lstat64(&p, &mut stat) })?;
Ok(FileAttr::from_stat64(stat))
}
pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
let path = CString::new(p.as_os_str().as_bytes())?;
- let buf;
- unsafe {
- let r = libc::realpath(path.as_ptr());
- if r.is_null() {
- return Err(io::Error::last_os_error());
- }
- buf = CStr::from_ptr(r).to_bytes().to_vec();
- libc::free(r as *mut _);
- }
- Ok(PathBuf::from(OsString::from_vec(buf)))
+ let v = cvt_ocall(unsafe { libc::realpath(&path) })?;
+ Ok(PathBuf::from(OsString::from_vec(v)))
}
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
@@ -683,8 +690,10 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
}
mod libc {
+ pub use sgx_trts::libc::ocall::{
+ chmod, closedir, dirfd, fchmod, fcntl_arg0, fdatasync, fstat64, fstatat64, fsync,
+ ftruncate64, link, lseek64, lstat64, mkdir, open64, opendir, readdir64_r, readlink,
+ realpath, rename, rmdir, stat64, symlink, unlink, shrink_to_fit_os_string,
+ };
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{open64, fstat64, fsync, fdatasync, ftruncate64, lseek64, fchmod,
- unlink, link, rename, chmod, readlink, symlink, stat64, lstat64,
- fcntl_arg0, realpath, free, readdir64_r, closedir, dirfd, mkdir, rmdir, opendir, fstatat64};
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys/mod.rs b/sgx_tstd/src/sys/mod.rs
index 15c6441..54ffd19 100644
--- a/sgx_tstd/src/sys/mod.rs
+++ b/sgx_tstd/src/sys/mod.rs
@@ -15,41 +15,41 @@
// specific language governing permissions and limitations
// under the License..
+use crate::io::ErrorKind;
use sgx_trts::libc;
use sgx_trts::trts;
-use crate::io::ErrorKind;
pub use self::rand::hashmap_random_keys;
-pub mod mutex;
+#[cfg(feature = "backtrace")]
+pub mod backtrace;
+pub mod cmath;
pub mod condvar;
-pub mod rwlock;
+pub mod env;
+pub mod ext;
+#[cfg(feature = "thread")]
+pub mod fast_thread_local;
pub mod fd;
pub mod fs;
-pub mod sgxfs;
pub mod io;
-#[cfg(feature = "thread")]
-pub mod thread;
-#[cfg(feature = "thread")]
-pub mod fast_thread_local;
-#[cfg(feature = "thread")]
-pub mod thread_local;
+pub mod memchr;
+pub mod mutex;
#[cfg(feature = "net")]
pub mod net;
+pub mod os;
pub mod path;
-pub mod ext;
+#[cfg(feature = "pipe")]
+pub mod pipe;
pub mod rand;
-pub mod os;
+pub mod rwlock;
+pub mod sgxfs;
#[cfg(feature = "stdio")]
pub mod stdio;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
+#[cfg(feature = "thread")]
+pub mod thread;
+#[cfg(feature = "thread")]
+pub mod thread_local;
pub mod time;
-pub mod memchr;
-pub mod cmath;
-pub mod env;
-#[cfg(feature = "pipe")]
-pub mod pipe;
pub use crate::sys_common::os_str_bytes as os_str;
@@ -93,7 +93,11 @@ macro_rules! impl_is_minus_one {
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) }
+ 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>
@@ -112,3 +116,21 @@ where
pub unsafe fn abort_internal() -> ! {
trts::rsgx_abort()
}
+
+use sgx_trts::libc::OCallResult;
+
+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.kind() == ErrorKind::Interrupted => {}
+ other => return other,
+ }
+ }
+}
diff --git a/sgx_tstd/src/sys/net.rs b/sgx_tstd/src/sys/net.rs
index b6aa6c7..128363b 100644
--- a/sgx_tstd/src/sys/net.rs
+++ b/sgx_tstd/src/sys/net.rs
@@ -16,20 +16,18 @@
// under the License..
#![allow(dead_code)]
-use sgx_trts::libc::{c_int, size_t, c_void};
-use core::mem;
-use core::cmp;
-use core::str;
-use crate::ffi::CStr;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{Shutdown, SocketAddr};
use crate::sys::fd::FileDesc;
+pub use crate::sys::{cvt, cvt_ocall, cvt_ocall_r, cvt_r};
+use crate::sys_common::net::{getsockopt, setsockopt};
use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
use crate::time::{Duration, Instant};
#[cfg(not(feature = "untrusted_time"))]
use crate::untrusted::time::InstantEx;
-pub use crate::sys::{cvt, cvt_r};
+use core::cmp;
+use core::convert::TryInto;
+use sgx_trts::libc::{c_int, size_t, PolledOk};
pub type wrlen_t = size_t;
@@ -49,13 +47,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
return Err(io::Error::last_os_error());
}
- let detail = unsafe {
- let strerr = libc::gai_strerror(err);
- if strerr.is_null() {
- return Err(io::Error::from_raw_os_error(libc::ESGX));
- }
- str::from_utf8(CStr::from_ptr(strerr).to_bytes()).unwrap().to_owned()
- };
+ let detail = libc::gai_error_str(err);
Err(io::Error::new(
io::ErrorKind::Other,
&format!("failed to lookup address information: {}", detail)[..],
@@ -84,13 +76,13 @@ impl Socket {
// this option, however, was added in 2.6.27, and we still support
// 2.6.18 as a kernel, so if the returned error is EINVAL we
// fallthrough to the fallback.
- match cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0)) {
+ match libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0) {
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
- Err(e) => return Err(e),
+ Err(ref e) if e.equal_to_os_error(libc::EINVAL) => {}
+ Err(e) => return cvt_ocall(Err(e)),
}
- let fd = cvt(libc::socket(fam, ty, 0))?;
+ let fd = cvt_ocall(libc::socket(fam, ty, 0))?;
let fd = FileDesc::new(fd);
fd.set_cloexec()?;
let socket = Socket(fd);
@@ -104,15 +96,15 @@ impl Socket {
let mut fds = [0, 0];
// Like above, see if we can set cloexec atomically
- match cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr())) {
+ match libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, &mut fds) {
Ok(_) => {
return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
}
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
- Err(e) => return Err(e),
+ Err(ref e) if e.equal_to_os_error(libc::EINVAL) => {}
+ Err(e) => return cvt_ocall(Err(e)),
}
- cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
+ cvt_ocall(libc::socketpair(fam, ty, 0, &mut fds))?;
let a = FileDesc::new(fds[0]);
let b = FileDesc::new(fds[1]);
a.set_cloexec()?;
@@ -124,19 +116,23 @@ impl Socket {
pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
self.set_nonblocking(true)?;
let r = unsafe {
- let (addrp, len) = addr.into_inner();
- cvt(libc::connect(self.0.raw(), addrp, len))
+ let addr = addr.to_owned().into();
+ libc::connect(self.0.raw(), &addr)
};
self.set_nonblocking(false)?;
match r {
Ok(_) => return Ok(()),
// there's no ErrorKind for EINPROGRESS :(
- Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
- Err(e) => return Err(e),
+ Err(ref e) if e.equal_to_os_error(libc::EINPROGRESS) => {}
+ Err(e) => return cvt_ocall(Err(e)),
}
- let mut pollfd = libc::pollfd { fd: self.0.raw(), events: libc::POLLOUT, revents: 0 };
+ let mut pollfds = [libc::pollfd {
+ fd: self.0.raw(),
+ events: libc::POLLOUT,
+ revents: 0,
+ }];
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
return Err(io::Error::new(
@@ -150,7 +146,10 @@ impl Socket {
loop {
let elapsed = start.elapsed();
if elapsed >= timeout {
- return Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out"));
+ return Err(io::Error::new(
+ io::ErrorKind::TimedOut,
+ "connection timed out",
+ ));
}
let timeout = timeout - elapsed;
@@ -164,24 +163,17 @@ impl Socket {
let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int;
- match unsafe { libc::poll(&mut pollfd, 1, timeout) } {
- -1 => {
- let err = io::Error::last_os_error();
- if err.kind() != io::ErrorKind::Interrupted {
- return Err(err);
- }
- }
- 0 => {}
- _ => {
+ match unsafe { cvt_ocall(libc::poll(&mut pollfds, timeout))? } {
+ PolledOk::TimeLimitExpired => {}
+ PolledOk::ReadyDescsCount(_) => {
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
// for POLLHUP rather than read readiness
- if pollfd.revents & libc::POLLHUP != 0 {
+ if pollfds[0].revents & libc::POLLHUP != 0 {
let e = self.take_error()?.unwrap_or_else(|| {
io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
});
return Err(e);
}
-
return Ok(());
}
}
@@ -198,14 +190,10 @@ impl Socket {
// This function is guarded by feature `net` and should only
// be used on demand.
// We don't support linux kernel < 2.6.28. So we only use accept4.
- pub fn accept(&self, storage: *mut libc::sockaddr, len: *mut libc::socklen_t) -> io::Result<Socket> {
- let res = cvt_r(|| unsafe {
- libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC)
- });
- match res {
- Ok(fd) => Ok(Socket(FileDesc::new(fd))),
- Err(e) => Err(e),
- }
+ pub fn accept(&self) -> io::Result<(Socket, libc::SockAddr)> {
+ let (fd, addr) =
+ cvt_ocall_r(|| unsafe { libc::accept4(self.0.raw(), libc::SOCK_CLOEXEC) })?;
+ Ok((Socket(FileDesc::new(fd)), addr))
}
pub fn raw(&self) -> c_int {
@@ -221,9 +209,7 @@ impl Socket {
}
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::recv(self.0.raw(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
- })?;
+ let ret = cvt_ocall(unsafe { libc::recv(self.0.raw(), buf, flags) })?;
Ok(ret as usize)
}
@@ -244,20 +230,8 @@ impl Socket {
buf: &mut [u8],
flags: c_int,
) -> io::Result<(usize, SocketAddr)> {
- let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
- let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
-
- let n = cvt(unsafe {
- libc::recvfrom(
- self.0.raw(),
- buf.as_mut_ptr() as *mut c_void,
- buf.len(),
- flags,
- &mut storage as *mut _ as *mut _,
- &mut addrlen,
- )
- })?;
- Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
+ let (n, addr) = cvt_ocall(unsafe { libc::recvfrom(self.0.raw(), buf, flags) })?;
+ Ok((n, addr.try_into()?))
}
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
@@ -300,7 +274,10 @@ impl Socket {
}
timeout
}
- None => libc::timeval { tv_sec: 0, tv_usec: 0 },
+ None => libc::timeval {
+ tv_sec: 0,
+ tv_usec: 0,
+ },
};
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
}
@@ -322,7 +299,7 @@ impl Socket {
Shutdown::Read => libc::SHUT_RD,
Shutdown::Both => libc::SHUT_RDWR,
};
- cvt(unsafe { libc::shutdown(self.0.raw(), how) })?;
+ cvt_ocall(unsafe { libc::shutdown(self.0.raw(), how) })?;
Ok(())
}
@@ -337,12 +314,17 @@ impl Socket {
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
let mut nonblocking = nonblocking as c_int;
- cvt(unsafe { libc::ioctl_arg1(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(drop)
+ cvt_ocall(unsafe { libc::ioctl_arg1(*self.as_inner(), libc::FIONBIO, &mut nonblocking) })
+ .map(drop)
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
- if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
+ if raw == 0 {
+ Ok(None)
+ } else {
+ Ok(Some(io::Error::from_raw_os_error(raw as i32)))
+ }
}
}
@@ -365,7 +347,9 @@ impl IntoInner<c_int> for Socket {
}
mod libc {
+ pub use sgx_trts::libc::ocall::{
+ accept4, connect, ioctl_arg1, poll, recv, recvfrom, shutdown, socket,
+ socketpair,
+ };
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{socket, socketpair, connect, accept4, recv, recvfrom, shutdown,
- ioctl_arg1, poll, gai_strerror};
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys/os.rs b/sgx_tstd/src/sys/os.rs
index 9627cfe..49d9ef6 100644
--- a/sgx_tstd/src/sys/os.rs
+++ b/sgx_tstd/src/sys/os.rs
@@ -15,25 +15,23 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_trts::error as trts_error;
-use sgx_types::metadata;
-use crate::os::unix::prelude::*;
use crate::error::Error as StdError;
use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::io;
+use crate::memchr;
+use crate::os::unix::prelude::*;
use crate::path::{self, PathBuf};
use crate::sync::SgxThreadMutex;
-use crate::sys::cvt;
-use crate::memchr;
-use crate::io;
-use core::marker::PhantomData;
-use core::fmt;
-use core::iter;
-use core::ptr;
-use core::mem;
+use crate::sys::cvt_ocall;
use alloc_crate::slice;
-use alloc_crate::string::String;
use alloc_crate::str;
+use alloc_crate::string::String;
use alloc_crate::vec::{self, Vec};
+use core::fmt;
+use core::iter;
+use core::marker::PhantomData;
+use sgx_trts::error as trts_error;
+use sgx_types::metadata;
const TMPBUF_SZ: usize = 128;
static ENV_LOCK: SgxThreadMutex = SgxThreadMutex::new();
@@ -54,47 +52,59 @@ pub fn error_string(error: i32) -> String {
}
let p = buf.as_ptr() as *const _;
- str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
+ str::from_utf8(CStr::from_ptr(p).to_bytes())
+ .unwrap()
+ .to_owned()
}
}
pub struct SplitPaths<'a> {
- iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
- fn(&'a [u8]) -> PathBuf>,
+ iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> PathBuf>,
}
pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
fn bytes_to_path(b: &[u8]) -> PathBuf {
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
}
- fn is_colon(b: &u8) -> bool { *b == b':' }
+ fn is_colon(b: &u8) -> bool {
+ *b == b':'
+ }
let unparsed = unparsed.as_bytes();
SplitPaths {
- iter: unparsed.split(is_colon as fn(&u8) -> bool)
- .map(bytes_to_path as fn(&[u8]) -> PathBuf)
+ iter: unparsed
+ .split(is_colon as fn(&u8) -> bool)
+ .map(bytes_to_path as fn(&[u8]) -> PathBuf),
}
}
impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
- fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+ fn next(&mut self) -> Option<PathBuf> {
+ self.iter.next()
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
}
#[derive(Debug)]
pub struct JoinPathsError;
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: Iterator<Item=T>, T: AsRef<OsStr>
+where
+ I: Iterator<Item = T>,
+ T: AsRef<OsStr>,
{
let mut joined = Vec::new();
let sep = b':';
for (i, path) in paths.enumerate() {
let path = path.as_ref().as_bytes();
- if i > 0 { joined.push(sep) }
+ if i > 0 {
+ joined.push(sep)
+ }
if path.contains(&sep) {
- return Err(JoinPathsError)
+ return Err(JoinPathsError);
}
joined.extend_from_slice(path);
}
@@ -108,17 +118,17 @@ impl fmt::Display for JoinPathsError {
}
impl StdError for JoinPathsError {
- fn description(&self) -> &str { "failed to join paths" }
+ fn description(&self) -> &str {
+ "failed to join paths"
+ }
}
pub fn current_exe() -> io::Result<PathBuf> {
match crate::fs::read_link("/proc/self/exe") {
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
- Err(io::Error::new(
- io::ErrorKind::Other,
- "no /proc/self/exe available. Is /proc mounted?"
- ))
- },
+ Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::Error::new(
+ io::ErrorKind::Other,
+ "no /proc/self/exe available. Is /proc mounted?",
+ )),
other => other,
}
}
@@ -130,19 +140,26 @@ pub struct Env {
impl Iterator for Env {
type Item = (OsString, OsString);
- fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+ fn next(&mut self) -> Option<(OsString, OsString)> {
+ self.iter.next()
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
}
+/*
pub unsafe fn environ() -> *const *const libc::c_char {
libc::environ()
}
+*/
/// Returns a vector of (variable, value) byte-vector pairs for all the
/// environment variables of the current process.
pub fn env() -> Env {
unsafe {
ENV_LOCK.lock();
+ /*
let mut environ = environ();
let mut result = Vec::new();
if !environ.is_null() {
@@ -153,6 +170,8 @@ pub fn env() -> Env {
environ = environ.add(1);
}
}
+ */
+ let result = Vec::new();
let ret = Env {
iter: result.into_iter(),
_dont_send_or_sync_me: PhantomData,
@@ -183,40 +202,49 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
// environment variables with a nul byte can't be set, so their value is
// always None as well
let k = CString::new(k.as_bytes())?;
+
unsafe {
ENV_LOCK.lock();
- let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
- let ret = if s.is_null() {
- None
- } else {
- Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
- };
+ let result_opt = cvt_ocall(libc::getenv(&k));
+ let ret = result_opt.map(|opt| opt.map(|v| OsString::from_vec(v)));
ENV_LOCK.unlock();
- Ok(ret)
+ ret
}
}
-pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
+pub fn setenv(_k: &OsStr, _v: &OsStr) -> io::Result<()> {
+ Err(io::Error::new(
+ io::ErrorKind::Other,
+ "To be implemented completely within trusted part",
+ ))
+ /*
let k = CString::new(k.as_bytes())?;
let v = CString::new(v.as_bytes())?;
unsafe {
ENV_LOCK.lock();
- let ret = cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop);
+ let ret = cvt_ocall(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop);
ENV_LOCK.unlock();
ret
}
+ */
}
-pub fn unsetenv(n: &OsStr) -> io::Result<()> {
+pub fn unsetenv(_n: &OsStr) -> io::Result<()> {
+ Err(io::Error::new(
+ io::ErrorKind::Other,
+ "To be implemented completely within trusted part",
+ ))
+ /*
let nbuf = CString::new(n.as_bytes())?;
unsafe {
ENV_LOCK.lock();
- let ret = cvt(libc::unsetenv(nbuf.as_ptr())).map(drop);
+ let ret = cvt_ocall(libc::unsetenv(nbuf.as_ptr())).map(drop);
ENV_LOCK.unlock();
ret
}
+ */
}
pub fn page_size() -> usize {
@@ -224,78 +252,28 @@ pub fn page_size() -> usize {
}
pub fn temp_dir() -> PathBuf {
- crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
- PathBuf::from("/tmp")
- })
+ crate::env::var_os("TMPDIR")
+ .map(PathBuf::from)
+ .unwrap_or_else(|| PathBuf::from("/tmp"))
}
pub fn getcwd() -> io::Result<PathBuf> {
- let mut buf = Vec::with_capacity(512);
- loop {
- unsafe {
- let ptr = buf.as_mut_ptr() as *mut libc::c_char;
- if !libc::getcwd(ptr, buf.capacity()).is_null() {
- let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
- buf.set_len(len);
- buf.shrink_to_fit();
- return Ok(PathBuf::from(OsString::from_vec(buf)));
- } else {
- let error = io::Error::last_os_error();
- if error.raw_os_error() != Some(libc::ERANGE) {
- return Err(error);
- }
- }
-
- // Trigger the internal buffer resizing logic of `Vec` by requiring
- // more space than the current capacity.
- let cap = buf.capacity();
- buf.set_len(cap);
- buf.reserve(1);
- }
- }
+ let v = cvt_ocall(unsafe { libc::getcwd() })?;
+ return Ok(PathBuf::from(OsString::from_vec(v)));
}
pub fn chdir(p: &path::Path) -> io::Result<()> {
let p: &OsStr = p.as_ref();
let p = CString::new(p.as_bytes())?;
- unsafe {
- match libc::chdir(p.as_ptr()) == (0 as libc::c_int) {
- true => Ok(()),
- false => Err(io::Error::last_os_error()),
- }
- }
+ unsafe { cvt_ocall(libc::chdir(&p)) }
}
+// No fallback logic here for security reasons.
pub fn home_dir() -> Option<PathBuf> {
- return crate::env::var_os("HOME").or_else(|| unsafe {
- fallback()
- }).map(PathBuf::from);
- unsafe fn fallback() -> Option<OsString> {
- let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
- n if n < 0 => 512 as usize,
- n => n as usize,
- };
- let mut buf = Vec::with_capacity(amt);
- let mut passwd: libc::passwd = mem::zeroed();
- let mut result = ptr::null_mut();
- match libc::getpwuid_r(
- libc::getuid(),
- &mut passwd,
- buf.as_mut_ptr(),
- buf.capacity(),
- &mut result
- ) {
- 0 if !result.is_null() => {
- let ptr = passwd.pw_dir as *const _;
- let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
- Some(OsStringExt::from_vec(bytes))
- }
- _ => None,
- }
- }
+ return crate::env::var_os("HOME").map(PathBuf::from);
}
mod libc {
+ pub use sgx_trts::libc::ocall::{chdir, getcwd, getenv, getuid, sysconf};
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{environ, getenv, setenv, unsetenv, getcwd, chdir, sysconf, getuid, getpwuid_r};
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys/pipe.rs b/sgx_tstd/src/sys/pipe.rs
index 3a5e249..637a4fc 100644
--- a/sgx_tstd/src/sys/pipe.rs
+++ b/sgx_tstd/src/sys/pipe.rs
@@ -17,10 +17,9 @@
use crate::io::{self, IoSlice, IoSliceMut};
use crate::sys::fd::FileDesc;
-use crate::sys::{cvt, cvt_r};
-use core::mem;
+use crate::sys::{cvt_ocall, cvt_ocall_r};
use alloc_crate::vec::Vec;
-
+use core::mem;
////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
@@ -30,7 +29,7 @@ pub struct AnonPipe(FileDesc);
pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
let mut fds = [0; 2];
- cvt(unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) })?;
+ cvt_ocall(unsafe { libc::pipe2(&mut fds, libc::O_CLOEXEC) })?;
let fd0 = FileDesc::new(fds[0]);
let fd1 = FileDesc::new(fds[1]);
@@ -77,7 +76,7 @@ pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) ->
fds[1].events = libc::POLLIN;
loop {
// wait for either pipe to become readable using `poll`
- cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
+ cvt_ocall_r(|| unsafe { libc::poll(&mut fds, -1) })?;
if fds[0].revents != 0 && read(&p1, v1)? {
p2.set_nonblocking(false)?;
@@ -111,6 +110,6 @@ pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) ->
}
mod libc {
- pub use sgx_trts::libc::*;
pub use sgx_trts::libc::ocall::{pipe2, poll};
-}
\ No newline at end of file
+ pub use sgx_trts::libc::*;
+}
diff --git a/sgx_tstd/src/sys/thread.rs b/sgx_tstd/src/sys/thread.rs
index 91d20ec..d09d55a 100644
--- a/sgx_tstd/src/sys/thread.rs
+++ b/sgx_tstd/src/sys/thread.rs
@@ -21,7 +21,6 @@ use core::mem;
use core::ptr;
use crate::ffi::CStr;
use crate::io;
-use crate::sys::os;
use crate::time::Duration;
pub struct Thread {
@@ -73,7 +72,7 @@ impl Thread {
pub fn yield_now() {
let ret = unsafe { libc::sched_yield() };
- debug_assert_eq!(ret, 0);
+ debug_assert!(ret.is_ok());
}
pub fn sleep(dur: Duration) {
@@ -89,8 +88,8 @@ impl Thread {
tv_nsec: nsecs,
};
secs -= ts.tv_sec as u64;
- if libc::nanosleep(&ts, &mut ts) == -1 {
- assert_eq!(os::errno(), libc::EINTR);
+ if let Err(e) = libc::nanosleep(&mut ts) {
+ assert_eq!(e.equal_to_os_error(libc::EINTR), true);
secs += ts.tv_sec as u64;
nsecs = ts.tv_nsec;
} else {
diff --git a/sgx_tstd/src/sys/time.rs b/sgx_tstd/src/sys/time.rs
index 89940c4..55c001a 100644
--- a/sgx_tstd/src/sys/time.rs
+++ b/sgx_tstd/src/sys/time.rs
@@ -15,12 +15,12 @@
// specific language governing permissions and limitations
// under the License..
-use sgx_trts::libc;
+pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
+use crate::time::Duration;
use core::cmp::Ordering;
-use core::hash::{Hash, Hasher};
use core::convert::TryInto;
-use crate::time::Duration;
-pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
+use core::hash::{Hash, Hasher};
+use sgx_trts::libc;
const NSEC_PER_SEC: u64 = 1_000_000_000;
@@ -31,7 +31,12 @@ struct Timespec {
impl Timespec {
const fn zero() -> Timespec {
- Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
+ Timespec {
+ t: libc::timespec {
+ tv_sec: 0,
+ tv_nsec: 0,
+ },
+ }
}
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
@@ -69,7 +74,12 @@ impl Timespec {
nsec -= NSEC_PER_SEC as u32;
secs = secs.checked_add(1)?;
}
- Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
+ Some(Timespec {
+ t: libc::timespec {
+ tv_sec: secs,
+ tv_nsec: nsec as _,
+ },
+ })
}
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
@@ -85,7 +95,12 @@ impl Timespec {
nsec += NSEC_PER_SEC as i32;
secs = secs.checked_sub(1)?;
}
- Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
+ Some(Timespec {
+ t: libc::timespec {
+ tv_sec: secs,
+ tv_nsec: nsec as _,
+ },
+ })
}
}
@@ -119,9 +134,9 @@ impl Hash for Timespec {
}
mod inner {
- use core::fmt;
- use crate::sys::cvt;
+ use crate::sys::cvt_ocall;
use crate::time::Duration;
+ use core::fmt;
use super::Timespec;
@@ -141,7 +156,9 @@ mod inner {
impl Instant {
pub fn now() -> Instant {
- Instant { t: now(libc::CLOCK_MONOTONIC) }
+ Instant {
+ t: now(libc::CLOCK_MONOTONIC),
+ }
}
pub const fn zero() -> Instant {
@@ -151,9 +168,9 @@ mod inner {
}
pub fn actually_monotonic() -> bool {
- (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64")) ||
- (cfg!(target_os = "linux") && cfg!(target_arch = "x86")) ||
- false // last clause, used so `||` is always trailing above
+ (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
+ || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
+ || false // last clause, used so `||` is always trailing above
}
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
@@ -161,11 +178,15 @@ mod inner {
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
- Some(Instant { t: self.t.checked_add_duration(other)? })
+ Some(Instant {
+ t: self.t.checked_add_duration(other)?,
+ })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
- Some(Instant { t: self.t.checked_sub_duration(other)? })
+ Some(Instant {
+ t: self.t.checked_sub_duration(other)?,
+ })
}
pub fn get_tup(&self) -> (i64, i64) {
@@ -184,7 +205,9 @@ mod inner {
impl SystemTime {
pub fn now() -> SystemTime {
- SystemTime { t: now(libc::CLOCK_REALTIME) }
+ SystemTime {
+ t: now(libc::CLOCK_REALTIME),
+ }
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
@@ -192,11 +215,15 @@ mod inner {
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
- Some(SystemTime { t: self.t.checked_add_duration(other)? })
+ Some(SystemTime {
+ t: self.t.checked_add_duration(other)?,
+ })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
- Some(SystemTime { t: self.t.checked_sub_duration(other)? })
+ Some(SystemTime {
+ t: self.t.checked_sub_duration(other)?,
+ })
}
pub fn get_tup(&self) -> (i64, i64) {
@@ -220,13 +247,18 @@ mod inner {
}
fn now(clock: libc::clockid_t) -> Timespec {
- let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
- cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
+ let mut t = Timespec {
+ t: libc::timespec {
+ tv_sec: 0,
+ tv_nsec: 0,
+ },
+ };
+ cvt_ocall(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
t
}
mod libc {
- pub use sgx_trts::libc::*;
pub use sgx_trts::libc::ocall::clock_gettime;
+ pub use sgx_trts::libc::*;
}
-}
\ No newline at end of file
+}
diff --git a/sgx_tstd/src/sys_common/net.rs b/sgx_tstd/src/sys_common/net.rs
index 6e7f400..d086471 100644
--- a/sgx_tstd/src/sys_common/net.rs
+++ b/sgx_tstd/src/sys_common/net.rs
@@ -17,18 +17,18 @@
#![allow(dead_code)]
-use sgx_trts::libc::{c_int, c_uint, c_void};
-use core::cmp;
-use core::fmt;
-use core::mem;
-use core::ptr;
-use core::convert::{TryFrom, TryInto};
use crate::ffi::CString;
use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
-use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
-use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys::net::{init, Socket};
+use crate::sys::{cvt_ocall, cvt_ocall_r};
+use crate::sys_common::{AsInner, FromInner};
use crate::time::Duration;
+use alloc_crate::vec;
+use core::convert::{TryFrom, TryInto};
+use core::fmt;
+use core::mem;
+use sgx_trts::libc::{c_int, c_uint, c_void, SockAddr};
////////////////////////////////////////////////////////////////////////////////
// sockaddr and misc bindings
@@ -37,7 +37,7 @@ use crate::time::Duration;
pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int, payload: T) -> io::Result<()> {
unsafe {
let payload = &payload as *const T as *const c_void;
- cvt(libc::setsockopt(
+ cvt_ocall(libc::setsockopt(
*sock.as_inner(),
opt,
val,
@@ -52,7 +52,7 @@ pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int, val: c_int) -> io::Result<
unsafe {
let mut slot: T = mem::zeroed();
let mut len = mem::size_of::<T>() as libc::socklen_t;
- cvt(libc::getsockopt(
+ cvt_ocall(libc::getsockopt(
*sock.as_inner(),
opt,
val,
@@ -66,16 +66,24 @@ pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int, val: c_int) -> io::Result<
fn sockname<F>(f: F) -> io::Result<SocketAddr>
where
- F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> c_int,
+ F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::OCallResult<()>,
{
unsafe {
let mut storage: libc::sockaddr_storage = mem::zeroed();
let mut len = mem::size_of_val(&storage) as libc::socklen_t;
- cvt(f(&mut storage as *mut _ as *mut _, &mut len))?;
+ cvt_ocall(f(&mut storage as *mut _ as *mut _, &mut len))?;
sockaddr_to_addr(&storage, len as usize)
}
}
+fn sockname2<F>(f: F) -> io::Result<SocketAddr>
+where
+ F: FnOnce() -> libc::OCallResult<libc::SockAddr>,
+{
+ let sa = cvt_ocall(f())?;
+ sa.try_into()
+}
+
pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage, len: usize) -> io::Result<SocketAddr> {
match storage.ss_family as c_int {
libc::AF_INET => {
@@ -103,8 +111,7 @@ fn to_ipv6mr_interface(value: u32) -> c_uint {
////////////////////////////////////////////////////////////////////////////////
pub struct LookupHost {
- original: *mut libc::addrinfo,
- cur: *mut libc::addrinfo,
+ iter: vec::IntoIter<SockAddr>,
port: u16,
}
@@ -117,28 +124,17 @@ impl LookupHost {
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> {
- loop {
- unsafe {
- let cur = self.cur.as_ref()?;
- self.cur = cur.ai_next;
- match sockaddr_to_addr(mem::transmute(cur.ai_addr), cur.ai_addrlen as usize) {
- Ok(addr) => return Some(addr),
- Err(_) => continue,
- }
- }
- }
+ self.iter.next().map(|sai| match sai {
+ SockAddr::IN4(addr) => SocketAddr::V4(FromInner::from_inner(addr)),
+ SockAddr::IN6(addr) => SocketAddr::V6(FromInner::from_inner(addr)),
+ _ => unreachable!(),
+ })
}
}
unsafe impl Sync for LookupHost {}
unsafe impl Send for LookupHost {}
-impl Drop for LookupHost {
- fn drop(&mut self) {
- unsafe { libc::freeaddrinfo(self.original) }
- }
-}
-
impl TryFrom<&str> for LookupHost {
type Error = io::Error;
@@ -169,13 +165,15 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
init();
let c_host = CString::new(host)?;
- let mut hints: libc::addrinfo = unsafe { mem::zeroed() };
- hints.ai_socktype = libc::SOCK_STREAM;
- let mut res = ptr::null_mut();
- unsafe {
- cvt_gai(libc::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
- .map(|_| LookupHost { original: res, cur: res, port })
- }
+ let mut hints = libc::AddrInfoHints::default();
+ hints.socktype = libc::SOCK_STREAM;
+
+ let addr_vec = unsafe { cvt_ocall(libc::getaddrinfo(Some(&c_host), None, Some(hints)))? };
+
+ Ok(LookupHost {
+ iter: addr_vec.into_iter(),
+ port,
+ })
}
}
@@ -217,8 +215,8 @@ impl TcpStream {
init();
let sock = Socket::new_socket_addr_type(addr, libc::SOCK_STREAM)?;
- let (addrp, len) = addr.into_inner();
- cvt_r(|| unsafe { libc::connect(*sock.as_inner(), addrp, len) })?;
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall_r(|| unsafe { libc::connect(*sock.as_inner(), &sock_addr) })?;
Ok(TcpStream { inner: sock })
}
@@ -227,8 +225,8 @@ impl TcpStream {
init();
- let (addrp, len) = addr.into_inner();
- cvt_r(|| unsafe { libc::connect(*self.inner.as_inner(), addrp, len) }).map(drop)
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall_r(|| unsafe { libc::connect(*self.inner.as_inner(), &sock_addr) }).map(drop)
}
pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
@@ -280,15 +278,8 @@ impl TcpStream {
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
- let ret = cvt(unsafe {
- libc::send(
- *self.inner.as_inner(),
- buf.as_ptr() as *const c_void,
- len,
- libc::MSG_NOSIGNAL,
- )
- })?;
+ let ret =
+ cvt_ocall(unsafe { libc::send(*self.inner.as_inner(), buf, libc::MSG_NOSIGNAL) })?;
Ok(ret as usize)
}
@@ -297,15 +288,11 @@ impl TcpStream {
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- sockname(|buf, len| unsafe {
- libc::getpeername(*self.inner.as_inner(), buf, len)
- })
+ sockname2(|| unsafe { libc::getpeername(*self.inner.as_inner()) })
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- sockname(|buf, len| unsafe {
- libc::getsockname(*self.inner.as_inner(), buf, len)
- })
+ sockname2(|| unsafe { libc::getsockname(*self.inner.as_inner()) })
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -334,7 +321,12 @@ impl TcpStream {
}
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
- setsockopt(&self.inner, libc::IPPROTO_IPV6, libc::IPV6_V6ONLY, only_v6 as c_int)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_V6ONLY,
+ only_v6 as c_int,
+ )
}
pub fn only_v6(&self) -> io::Result<bool> {
@@ -419,11 +411,11 @@ impl TcpListener {
setsockopt(&sock, libc::SOL_SOCKET, libc::SO_REUSEADDR, 1 as c_int)?;
// Bind our new socket
- let (addrp, len) = addr.into_inner();
- cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len as _) })?;
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall(unsafe { libc::bind(*sock.as_inner(), &sock_addr) })?;
// Start listening
- cvt(unsafe { libc::listen(*sock.as_inner(), 128) })?;
+ cvt_ocall(unsafe { libc::listen(*sock.as_inner(), 128) })?;
Ok(TcpListener { inner: sock })
}
@@ -432,10 +424,15 @@ impl TcpListener {
init();
- setsockopt(&self.inner, libc::SOL_SOCKET, libc::SO_REUSEADDR, 1 as c_int)?;
- let (addrp, len) = addr.into_inner();
- cvt(unsafe { libc::bind(*self.inner.as_inner(), addrp, len as _) })?;
- cvt(unsafe { libc::listen(*self.inner.as_inner(), 128) }).map(drop)
+ setsockopt(
+ &self.inner,
+ libc::SOL_SOCKET,
+ libc::SO_REUSEADDR,
+ 1 as c_int,
+ )?;
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall(unsafe { libc::bind(*self.inner.as_inner(), &sock_addr) })?;
+ cvt_ocall(unsafe { libc::listen(*self.inner.as_inner(), 128) })
}
pub fn socket(&self) -> &Socket {
@@ -447,16 +444,12 @@ impl TcpListener {
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- sockname(|buf, len| unsafe {
- libc::getsockname(*self.inner.as_inner(), buf, len)
- })
+ sockname2(|| unsafe { libc::getsockname(*self.inner.as_inner()) })
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
- let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
- let mut len = mem::size_of_val(&storage) as libc::socklen_t;
- let sock = self.inner.accept(&mut storage as *mut _ as *mut _, &mut len)?;
- let addr = sockaddr_to_addr(&storage, len as usize)?;
+ let (sock, addr) = self.inner.accept()?;
+ let addr = addr.try_into()?;
Ok((TcpStream { inner: sock }, addr))
}
@@ -474,7 +467,12 @@ impl TcpListener {
}
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
- setsockopt(&self.inner, libc::IPPROTO_IPV6, libc::IPV6_V6ONLY, only_v6 as c_int)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_V6ONLY,
+ only_v6 as c_int,
+ )
}
pub fn only_v6(&self) -> io::Result<bool> {
@@ -519,7 +517,6 @@ pub struct UdpSocket {
}
impl UdpSocket {
-
pub fn new(sockfd: c_int) -> io::Result<UdpSocket> {
let sock = Socket::new(sockfd)?;
Ok(UdpSocket { inner: sock })
@@ -549,8 +546,8 @@ impl UdpSocket {
init();
let sock = Socket::new_socket_addr_type(addr, libc::SOCK_DGRAM)?;
- let (addrp, len) = addr.into_inner();
- cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len as _) })?;
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall(unsafe { libc::bind(*sock.as_inner(), &sock_addr) })?;
Ok(UdpSocket { inner: sock })
}
@@ -559,8 +556,8 @@ impl UdpSocket {
init();
- let (addrp, len) = addr.into_inner();
- cvt(unsafe { libc::bind(*self.inner.as_inner(), addrp, len as _) }).map(drop)
+ let sock_addr = addr.to_owned().into();
+ cvt_ocall(unsafe { libc::bind(*self.inner.as_inner(), &sock_addr) }).map(drop)
}
pub fn socket(&self) -> &Socket {
@@ -572,15 +569,11 @@ impl UdpSocket {
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- sockname(|buf, len| unsafe {
- libc::getpeername(*self.inner.as_inner(), buf, len)
- })
+ sockname2(|| unsafe { libc::getpeername(*self.inner.as_inner()) })
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- sockname(|buf, len| unsafe {
- libc::getsockname(*self.inner.as_inner(), buf, len)
- })
+ sockname2(|| unsafe { libc::getsockname(*self.inner.as_inner()) })
}
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
@@ -592,17 +585,9 @@ impl UdpSocket {
}
pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
- let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
- let (dstp, dstlen) = dst.into_inner();
- let ret = cvt(unsafe {
- libc::sendto(
- *self.inner.as_inner(),
- buf.as_ptr() as *const c_void,
- len,
- libc::MSG_NOSIGNAL,
- dstp,
- dstlen,
- )
+ let dst = dst.to_owned().into();
+ let ret = cvt_ocall(unsafe {
+ libc::sendto(*self.inner.as_inner(), &buf, libc::MSG_NOSIGNAL, &dst)
})?;
Ok(ret as usize)
}
@@ -628,7 +613,12 @@ impl UdpSocket {
}
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
- setsockopt(&self.inner, libc::SOL_SOCKET, libc::SO_BROADCAST, broadcast as c_int)
+ setsockopt(
+ &self.inner,
+ libc::SOL_SOCKET,
+ libc::SO_BROADCAST,
+ broadcast as c_int,
+ )
}
pub fn broadcast(&self) -> io::Result<bool> {
@@ -637,7 +627,12 @@ impl UdpSocket {
}
pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
- setsockopt(&self.inner, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IP,
+ libc::IP_MULTICAST_LOOP,
+ multicast_loop_v4 as c_int,
+ )
}
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
@@ -646,7 +641,12 @@ impl UdpSocket {
}
pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
- setsockopt(&self.inner, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IP,
+ libc::IP_MULTICAST_TTL,
+ multicast_ttl_v4 as c_int,
+ )
}
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
@@ -655,7 +655,12 @@ impl UdpSocket {
}
pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
- setsockopt(&self.inner, libc::IPPROTO_IPV6, libc::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_MULTICAST_LOOP,
+ multicast_loop_v6 as c_int,
+ )
}
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
@@ -676,7 +681,12 @@ impl UdpSocket {
ipv6mr_multiaddr: *multiaddr.as_inner(),
ipv6mr_interface: to_ipv6mr_interface(interface),
};
- setsockopt(&self.inner, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, mreq)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_ADD_MEMBERSHIP,
+ mreq,
+ )
}
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
@@ -684,7 +694,12 @@ impl UdpSocket {
imr_multiaddr: *multiaddr.as_inner(),
imr_interface: *interface.as_inner(),
};
- setsockopt(&self.inner, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, mreq)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IP,
+ libc::IP_DROP_MEMBERSHIP,
+ mreq,
+ )
}
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
@@ -692,7 +707,12 @@ impl UdpSocket {
ipv6mr_multiaddr: *multiaddr.as_inner(),
ipv6mr_interface: to_ipv6mr_interface(interface),
};
- setsockopt(&self.inner, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, mreq)
+ setsockopt(
+ &self.inner,
+ libc::IPPROTO_IPV6,
+ libc::IPV6_DROP_MEMBERSHIP,
+ mreq,
+ )
}
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
@@ -721,21 +741,14 @@ impl UdpSocket {
}
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
- let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
- let ret = cvt(unsafe {
- libc::send(
- *self.inner.as_inner(),
- buf.as_ptr() as *const c_void,
- len,
- libc::MSG_NOSIGNAL,
- )
- })?;
+ let ret =
+ cvt_ocall(unsafe { libc::send(*self.inner.as_inner(), buf, libc::MSG_NOSIGNAL) })?;
Ok(ret as usize)
}
pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
- let (addrp, len) = addr?.into_inner();
- cvt_r(|| unsafe { libc::connect(*self.inner.as_inner(), addrp, len) }).map(drop)
+ let sock_addr = addr?.to_owned().into();
+ cvt_ocall_r(|| unsafe { libc::connect(*self.inner.as_inner(), &sock_addr) }).map(drop)
}
}
@@ -759,7 +772,9 @@ impl fmt::Debug for UdpSocket {
}
mod libc {
+ pub use sgx_trts::libc::ocall::{
+ bind, connect, getaddrinfo, getpeername, getsockname, getsockopt, listen, send, sendto,
+ setsockopt,
+ };
pub use sgx_trts::libc::*;
- pub use sgx_trts::libc::ocall::{bind, listen, connect, setsockopt, getsockopt, send, sendto,
- getpeername, getsockname, getaddrinfo, freeaddrinfo};
-}
\ No newline at end of file
+}
diff --git a/sgx_urts/src/env.rs b/sgx_urts/src/env.rs
index 3816d3f..973c862 100644
--- a/sgx_urts/src/env.rs
+++ b/sgx_urts/src/env.rs
@@ -17,6 +17,7 @@
use libc::{self, c_char, c_int, passwd, size_t, uid_t};
use std::io::Error;
+use std::ptr;
#[no_mangle]
pub extern "C" fn u_getuid_ocall() -> uid_t {
@@ -32,8 +33,39 @@ pub extern "C" fn u_environ_ocall() -> *const *const c_char {
}
#[no_mangle]
-pub extern "C" fn u_getenv_ocall(name: *const c_char) -> *const c_char {
- unsafe { libc::getenv(name) }
+pub extern "C" fn u_getenv_ocall(
+ error: *mut c_int,
+ name: *const c_char,
+ buf: *mut c_char,
+ bufsz: size_t,
+ isset: *mut c_int
+) -> c_int {
+ unsafe {
+ if bufsz == 0 || buf.is_null() || isset.is_null() {
+ if !error.is_null() {
+ *error = libc::EINVAL;
+ }
+ return -1;
+ }
+
+ let rptr = libc::getenv(name);
+
+ if rptr.is_null() {
+ *isset = 0;
+ *buf = 0;
+ } else {
+ *isset = 1;
+ let sn = libc::strlen(rptr) + 1;
+ if sn > bufsz {
+ if !error.is_null() {
+ *error = libc::ERANGE;
+ }
+ return -1;
+ }
+ ptr::copy_nonoverlapping(rptr, buf, sn);
+ };
+ 0
+ }
}
#[no_mangle]
@@ -72,18 +104,18 @@ pub extern "C" fn u_unsetenv_ocall(error: *mut c_int, name: *const c_char) -> c_
}
#[no_mangle]
-pub extern "C" fn u_getcwd_ocall(error: *mut c_int, buf: *mut c_char, size: size_t) -> *mut c_char {
- let mut errno = 0;
+pub extern "C" fn u_getcwd_ocall(error: *mut c_int, buf: *mut c_char, size: size_t) -> c_int {
let ret = unsafe { libc::getcwd(buf, size) };
if ret.is_null() {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
+ let errno = Error::last_os_error().raw_os_error().unwrap_or(0);
+ if !error.is_null() {
+ unsafe {
+ *error = errno;
+ }
}
+ return -1;
}
- ret
+ 0
}
#[no_mangle]
diff --git a/sgx_urts/src/fd.rs b/sgx_urts/src/fd.rs
index cfbf5a3..a416867 100644
--- a/sgx_urts/src/fd.rs
+++ b/sgx_urts/src/fd.rs
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License..
-use libc::{self, c_int, c_ulong, c_void, iovec, off64_t, size_t, ssize_t};
+use libc::{self, c_int, c_ulong, c_void, off64_t, size_t, ssize_t};
use std::io::Error;
#[no_mangle]
@@ -60,47 +60,6 @@ pub extern "C" fn u_pread64_ocall(
}
#[no_mangle]
-pub extern "C" fn u_readv_ocall(
- error: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
-) -> ssize_t {
- let mut errno = 0;
- let ret = unsafe { libc::readv(fd, iov, iovcnt) };
- if ret < 0 {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
- }
- }
- ret
-}
-
-#[no_mangle]
-pub extern "C" fn u_preadv64_ocall(
- error: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
- offset: off64_t,
-) -> ssize_t {
- let mut errno = 0;
- let ret = unsafe { libc::preadv64(fd, iov, iovcnt, offset) };
- if ret < 0 {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
- }
- }
- ret
-}
-
-#[no_mangle]
pub extern "C" fn u_write_ocall(
error: *mut c_int,
fd: c_int,
@@ -142,47 +101,6 @@ pub extern "C" fn u_pwrite64_ocall(
}
#[no_mangle]
-pub extern "C" fn u_writev_ocall(
- error: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
-) -> ssize_t {
- let mut errno = 0;
- let ret = unsafe { libc::writev(fd, iov, iovcnt) };
- if ret < 0 {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
- }
- }
- ret
-}
-
-#[no_mangle]
-pub extern "C" fn u_pwritev64_ocall(
- error: *mut c_int,
- fd: c_int,
- iov: *const iovec,
- iovcnt: c_int,
- offset: off64_t,
-) -> ssize_t {
- let mut errno = 0;
- let ret = unsafe { libc::pwritev64(fd, iov, iovcnt, offset) };
- if ret < 0 {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
- }
- }
- ret
-}
-
-#[no_mangle]
pub extern "C" fn u_fcntl_arg0_ocall(error: *mut c_int, fd: c_int, cmd: c_int) -> c_int {
let mut errno = 0;
let ret = unsafe { libc::fcntl(fd, cmd) };
diff --git a/sgx_urts/src/file.rs b/sgx_urts/src/file.rs
index 85edd82..7b13e69 100644
--- a/sgx_urts/src/file.rs
+++ b/sgx_urts/src/file.rs
@@ -411,18 +411,25 @@ pub extern "C" fn u_symlink_ocall(
}
#[no_mangle]
-pub extern "C" fn u_realpath_ocall(error: *mut c_int, pathname: *const c_char) -> *mut c_char {
+pub extern "C" fn u_realpath_ocall(
+ error: *mut c_int,
+ pathname: *const c_char,
+ resolved_buf: *mut c_char,
+ _bufsz: size_t,
+) -> c_int {
let mut errno = 0;
- let ret = unsafe { libc::realpath(pathname, ptr::null_mut()) };
+ let mut result = 0;
+ let ret = unsafe { libc::realpath(pathname, resolved_buf) };
if ret.is_null() {
errno = Error::last_os_error().raw_os_error().unwrap_or(0);
+ result = -1;
}
if !error.is_null() {
unsafe {
*error = errno;
}
}
- ret
+ result
}
#[no_mangle]
@@ -474,9 +481,17 @@ pub extern "C" fn u_opendir_ocall(error: *mut c_int, pathname: *const c_char) ->
pub extern "C" fn u_readdir64_r_ocall(
dirp: *mut DIR,
entry: *mut dirent64,
- result: *mut *mut dirent64,
+ eods: *mut c_int, // end of directory stream
) -> c_int {
- unsafe { libc::readdir64_r(dirp, entry, result) }
+ let mut result_ptr = ptr::null_mut();
+ let result = unsafe { libc::readdir64_r(dirp, entry, &mut result_ptr) };
+ assert!(!eods.is_null());
+ if result_ptr.is_null() {
+ unsafe {
+ *eods= 1;
+ }
+ }
+ return result;
}
#[no_mangle]
diff --git a/sgx_urts/src/net.rs b/sgx_urts/src/net.rs
index 765da79..e641725 100644
--- a/sgx_urts/src/net.rs
+++ b/sgx_urts/src/net.rs
@@ -15,36 +15,57 @@
// specific language governing permissions and limitations
// under the License..
-use libc::{self, addrinfo, c_char, c_int};
+use libc::{self, addrinfo, c_char, c_int, size_t};
use std::io::Error;
+use core::ptr;
+
#[no_mangle]
pub extern "C" fn u_getaddrinfo_ocall(
error: *mut c_int,
node: *const c_char,
service: *const c_char,
- hints: *const addrinfo,
- res: *mut *mut addrinfo,
+ hints: *mut addrinfo,
+ entry_size: size_t,
+ buf: *mut u8,
+ bufsz: size_t,
+ out_cnt: *mut size_t,
) -> c_int {
let mut errno = 0;
- let ret = unsafe { libc::getaddrinfo(node, service, hints, res) };
+ let mut res: *mut addrinfo = ptr::null_mut();
+
+ let ret = unsafe { libc::getaddrinfo(node, service, hints, &mut res) };
+
if ret == libc::EAI_SYSTEM {
errno = Error::last_os_error().raw_os_error().unwrap_or(0);
}
+
if !error.is_null() {
unsafe {
*error = errno;
}
}
- ret
-}
-#[no_mangle]
-pub extern "C" fn u_freeaddrinfo_ocall(res: *mut addrinfo) {
- unsafe { libc::freeaddrinfo(res) }
-}
+ if ret != 0 {
+ return ret;
+ }
-#[no_mangle]
-pub extern "C" fn u_gai_strerror_ocall(errcode: c_int) -> *const c_char {
- unsafe { libc::gai_strerror(errcode) }
+ unsafe {
+ let mut i = 0;
+ let mut cur_ptr = res;
+ while cur_ptr != ptr::null_mut() && (i + entry_size) < bufsz {
+ let cur: &addrinfo = &*cur_ptr;
+ let len = cur.ai_addrlen as usize;
+ if len > entry_size {
+ return 1;
+ }
+ std::ptr::copy_nonoverlapping(cur.ai_addr as *const u8, buf.add(i), len);
+ i += entry_size;
+ cur_ptr = cur.ai_next;
+ }
+ *out_cnt = i / entry_size;
+ }
+
+ unsafe { libc::freeaddrinfo(res) };
+ return 0;
}
diff --git a/sgx_urts/src/socket.rs b/sgx_urts/src/socket.rs
index d606a1c..c139f9d 100644
--- a/sgx_urts/src/socket.rs
+++ b/sgx_urts/src/socket.rs
@@ -95,28 +95,6 @@ pub extern "C" fn u_listen_ocall(error: *mut c_int, sockfd: c_int, backlog: c_in
}
#[no_mangle]
-pub extern "C" fn u_accept_ocall(
- error: *mut c_int,
- sockfd: c_int,
- addr: *mut sockaddr,
- addrlen_in: socklen_t,
- addrlen_out: *mut socklen_t,
-) -> c_int {
- let mut errno = 0;
- unsafe { *addrlen_out = addrlen_in };
- let ret = unsafe { libc::accept(sockfd, addr, addrlen_out) };
- if ret < 0 {
- errno = Error::last_os_error().raw_os_error().unwrap_or(0);
- }
- if !error.is_null() {
- unsafe {
- *error = errno;
- }
- }
- ret
-}
-
-#[no_mangle]
pub extern "C" fn u_accept4_ocall(
error: *mut c_int,
sockfd: c_int,
diff --git a/sgx_ustdc/net.c b/sgx_ustdc/net.c
index 1228eaa..1c0ccb6 100644
--- a/sgx_ustdc/net.c
+++ b/sgx_ustdc/net.c
@@ -37,8 +37,3 @@ void u_freeaddrinfo_ocall(struct addrinfo *res)
{
return freeaddrinfo(res);
}
-
-const char *u_gai_strerror_ocall(int errcode)
-{
- return gai_strerror(errcode);
-}
\ No newline at end of file
diff --git a/sgx_ustdc/socket.c b/sgx_ustdc/socket.c
index 9b8141a..83dccfe 100644
--- a/sgx_ustdc/socket.c
+++ b/sgx_ustdc/socket.c
@@ -59,19 +59,6 @@ int u_listen_ocall(int *error, int sockfd, int backlog)
return ret;
}
-int u_accept_ocall(int *error,
- int sockfd,
- struct sockaddr *addr,
- socklen_t addrlen_in,
- socklen_t *addrlen_out)
-{
- *addrlen_out = addrlen_in;
- int ret = accept(sockfd, addr, addrlen_out);
- if (error) {
- *error = ret == -1 ? errno : 0;
- }
- return ret;
-}
int u_accept4_ocall(int *error,
int sockfd,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org