Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion wasmtime-wasi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ fn main() {
.whitelist_function("fd_prestats_init")
.whitelist_function("fd_prestats_insert")
.whitelist_function("argv_environ_init")
.whitelist_function("rwlock_.*")
.whitelist_type("__wasi_.*")
.whitelist_type("fd_table")
.whitelist_type("fd_prestat")
.whitelist_type("fd_prestats")
.whitelist_type("argv_environ_values")
.whitelist_var("__WASI_.*")
Expand Down Expand Up @@ -101,7 +103,8 @@ fn main() {
.blacklist_item("__WASI_ETIMEDOUT")
.blacklist_item("__WASI_ETXTBSY")
.blacklist_item("__WASI_EXDEV")
.blacklist_item("__WASI_ENOTCAPABLE");
.blacklist_item("__WASI_ENOTCAPABLE")
.blacklist_item("__WASI_PREOPENTYPE_DIR");

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,14 +497,6 @@ __wasi_errno_t wasmtime_ssp_environ_sizes_get(
size_t *environ_buf_size
) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__));

__wasi_errno_t wasmtime_ssp_fd_prestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
__wasi_prestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__));

__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
Expand Down
8 changes: 4 additions & 4 deletions wasmtime-wasi/sandboxed-system-primitives/src/locking.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,21 @@ struct LOCKABLE rwlock {
pthread_rwlock_t object;
};

static inline void rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock) {
void rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock) {
pthread_rwlock_init(&lock->object, NULL);
}

static inline void rwlock_rdlock(struct rwlock *lock)
void rwlock_rdlock(struct rwlock *lock)
LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_rdlock(&lock->object);
}

static inline void rwlock_wrlock(struct rwlock *lock)
void rwlock_wrlock(struct rwlock *lock)
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_wrlock(&lock->object);
}

static inline void rwlock_unlock(struct rwlock *lock)
void rwlock_unlock(struct rwlock *lock)
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_unlock(&lock->object);
}
Expand Down
45 changes: 9 additions & 36 deletions wasmtime-wasi/sandboxed-system-primitives/src/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,6 @@ __wasi_errno_t wasmtime_ssp_clock_time_get(
return 0;
}

struct fd_prestat {
const char *dir;
};

void fd_prestats_init(
struct fd_prestats *pt
) {
Expand Down Expand Up @@ -278,8 +274,10 @@ static bool fd_prestats_grow(
return false;

// Mark all new file descriptors as unused.
for (size_t i = pt->size; i < size; ++i)
prestats[i].dir = NULL;
for (size_t i = pt->size; i < size; ++i) {
prestats[i].dir_name = NULL;
prestats[i].dir_name_len = 0;
}
pt->prestats = prestats;
pt->size = size;
}
Expand All @@ -299,7 +297,8 @@ bool fd_prestats_insert(
return false;
}

pt->prestats[fd].dir = strdup(dir);
pt->prestats[fd].dir_name = strdup(dir);
pt->prestats[fd].dir_name_len = strlen(dir);
rwlock_unlock(&pt->lock);
return true;
}
Expand All @@ -314,7 +313,7 @@ static __wasi_errno_t fd_prestats_get_entry(
if (fd >= pt->size)
return __WASI_EBADF;
struct fd_prestat *prestat = &pt->prestats[fd];
if (prestat->dir == NULL)
if (prestat->dir_name == NULL)
return __WASI_EBADF;

*ret = prestat;
Expand Down Expand Up @@ -653,32 +652,6 @@ static __wasi_errno_t fd_table_insert_fd(
return fd_table_insert(ft, fo, rights_base, rights_inheriting, out);
}

__wasi_errno_t wasmtime_ssp_fd_prestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
__wasi_prestat_t *buf
) {
rwlock_rdlock(&prestats->lock);
struct fd_prestat *prestat;
__wasi_errno_t error = fd_prestats_get_entry(prestats, fd, &prestat);
if (error != 0) {
rwlock_unlock(&prestats->lock);
return error;
}

*buf = (__wasi_prestat_t) {
.pr_type = __WASI_PREOPENTYPE_DIR,
};

buf->u.dir.pr_name_len = strlen(prestat->dir);

rwlock_unlock(&prestats->lock);

return 0;
}

__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
Expand All @@ -694,12 +667,12 @@ __wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
rwlock_unlock(&prestats->lock);
return error;
}
if (path_len != strlen(prestat->dir)) {
if (path_len != prestat->dir_name_len) {
rwlock_unlock(&prestats->lock);
return EINVAL;
}

memcpy(path, prestat->dir, path_len);
memcpy(path, prestat->dir_name, path_len);

rwlock_unlock(&prestats->lock);

Expand Down
6 changes: 5 additions & 1 deletion wasmtime-wasi/sandboxed-system-primitives/src/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
#include "locking.h"

struct fd_entry;
struct fd_prestat;
struct syscalls;

struct fd_prestat {
const char *dir_name;
size_t dir_name_len;
};

struct fd_table {
struct rwlock lock;
struct fd_entry *entries;
Expand Down
3 changes: 3 additions & 0 deletions wasmtime-wasi/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,6 @@ pub const __WASI_ETIMEDOUT: __wasi_errno_t = 73;
pub const __WASI_ETXTBSY: __wasi_errno_t = 74;
pub const __WASI_EXDEV: __wasi_errno_t = 75;
pub const __WASI_ENOTCAPABLE: __wasi_errno_t = 76;

// pub type __wasi_preopentype_t = u8;
pub const __WASI_PREOPENTYPE_DIR: __wasi_preopentype_t = 0;
55 changes: 55 additions & 0 deletions wasmtime-wasi/src/host_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,65 @@ fn convert_errno(error: Errno) -> host::__wasi_errno_t {
}
}

fn fd_prestats_get_entry(
pt: &host::fd_prestats,
fd: host::__wasi_fd_t,
) -> Option<&host::fd_prestat> {
// Test for file descriptor existence
if fd as usize >= pt.size {
return None;
}

let prestat = unsafe { &*pt.prestats.add(fd as usize) };
if prestat.dir_name == ::std::ptr::null() {
return None;
}

Some(prestat)
}

macro_rules! rwlock_rdlock {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the fact that we'll be using host::rwlock_rdlock (and host::rwlock_unlock) in a couple more places before we port every single bit of code from C that is using it, I've decided to add these simple macros, just for convenience.

($prestats:expr) => {
unsafe {
host::rwlock_rdlock(&mut (*$prestats).lock as *mut host::rwlock);
}
};
}

macro_rules! rwlock_unlock {
($prestats:expr) => {
unsafe {
host::rwlock_unlock(&mut (*$prestats).lock as *mut host::rwlock);
}
};
}

pub fn wasmtime_ssp_proc_exit(rval: wasm32::__wasi_exitcode_t) {
::std::process::exit(rval as i32)
}

pub fn wasmtime_ssp_fd_prestat_get(
prestats: &mut host::fd_prestats,
fd: host::__wasi_fd_t,
buf: &mut host::__wasi_prestat_t,
) -> host::__wasi_errno_t {
rwlock_rdlock!(prestats);

let ret_code = if let Some(prestat) = fd_prestats_get_entry(prestats, fd) {
buf.pr_type = host::__WASI_PREOPENTYPE_DIR;
unsafe {
buf.u.dir.pr_name_len = prestat.dir_name_len;
}
host::__WASI_ESUCCESS
} else {
host::__WASI_EBADF
};

rwlock_unlock!(prestats);

ret_code
}

pub fn wasmtime_ssp_sched_yield() -> host::__wasi_errno_t {
unsafe {
if libc::sched_yield() < 0 {
Expand Down
2 changes: 1 addition & 1 deletion wasmtime-wasi/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ syscalls! {
return return_encoded_errno(e);
}

let e = host::wasmtime_ssp_fd_prestat_get(prestats, fd, &mut host_buf);
let e = host_impls::wasmtime_ssp_fd_prestat_get(&mut *prestats, fd, &mut host_buf);

encode_prestat_byref(vmctx, buf, host_buf);

Expand Down