diff --git a/wasmtime-wasi/build.rs b/wasmtime-wasi/build.rs index 46d7058caf..fa9d79f17f 100644 --- a/wasmtime-wasi/build.rs +++ b/wasmtime-wasi/build.rs @@ -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_.*") diff --git a/wasmtime-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h b/wasmtime-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h index 7410161ee1..660c4b2538 100644 --- a/wasmtime-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h +++ b/wasmtime-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h @@ -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, diff --git a/wasmtime-wasi/sandboxed-system-primitives/src/locking.h b/wasmtime-wasi/sandboxed-system-primitives/src/locking.h index 0efb788ed5..3c606235eb 100644 --- a/wasmtime-wasi/sandboxed-system-primitives/src/locking.h +++ b/wasmtime-wasi/sandboxed-system-primitives/src/locking.h @@ -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); } diff --git a/wasmtime-wasi/sandboxed-system-primitives/src/posix.c b/wasmtime-wasi/sandboxed-system-primitives/src/posix.c index 6f7ba8ab3d..31d379a1b3 100644 --- a/wasmtime-wasi/sandboxed-system-primitives/src/posix.c +++ b/wasmtime-wasi/sandboxed-system-primitives/src/posix.c @@ -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 ) { @@ -653,32 +649,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, diff --git a/wasmtime-wasi/sandboxed-system-primitives/src/posix.h b/wasmtime-wasi/sandboxed-system-primitives/src/posix.h index 6711c9b2e3..b3519da78a 100644 --- a/wasmtime-wasi/sandboxed-system-primitives/src/posix.h +++ b/wasmtime-wasi/sandboxed-system-primitives/src/posix.h @@ -18,9 +18,12 @@ #include "locking.h" struct fd_entry; -struct fd_prestat; struct syscalls; +struct fd_prestat { + const char *dir; +}; + struct fd_table { struct rwlock lock; struct fd_entry *entries; diff --git a/wasmtime-wasi/src/host_impls.rs b/wasmtime-wasi/src/host_impls.rs index a509ba2582..d614d6d0b1 100644 --- a/wasmtime-wasi/src/host_impls.rs +++ b/wasmtime-wasi/src/host_impls.rs @@ -88,10 +88,66 @@ 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 == ::std::ptr::null() { + return None; + } + + Some(prestat) +} + +macro_rules! rwlock_rdlock { + ($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 as host::__wasi_preopentype_t; + unsafe { + let dir_name = ::std::ffi::CStr::from_ptr((*prestat).dir).to_str().unwrap(); + (*buf).u.dir.pr_name_len = 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 { diff --git a/wasmtime-wasi/src/syscalls.rs b/wasmtime-wasi/src/syscalls.rs index 04241500ad..0151095976 100644 --- a/wasmtime-wasi/src/syscalls.rs +++ b/wasmtime-wasi/src/syscalls.rs @@ -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);