Abstract POSIX filesystem functions (#2585)

To allow non-POSIX platforms such as Windows to support WASI libc
filesystem functionality, create a set of wrapper functions which provide a
platform-agnostic interface to interact with the host filesystem. For now,
the Windows implementation is stubbed but this will be implemented
properly in a future PR. There are no functional changes in this change,
just a reorganization of code to move any direct POSIX references out of
posix.c in the libc implementation into posix_file.c under the shared
POSIX sources.

See https://github.com/bytecodealliance/wasm-micro-runtime/issues/2495 for a
more detailed overview of the plan to port the WASI libc filesystem to Windows.
This commit is contained in:
zoraaver
2023-10-19 12:19:39 +01:00
committed by GitHub
parent 5fd530610a
commit fa5e9d72b0
40 changed files with 3805 additions and 2566 deletions

View File

@ -7,6 +7,7 @@
#include "bh_platform.h"
#include "wasm_export.h"
#include "wasm_runtime_common.h"
#include "wasmtime_ssp.h"
#if WASM_ENABLE_THREAD_MGR != 0
#include "../../../thread-mgr/thread_manager.h"

View File

@ -6,7 +6,6 @@
#ifndef _LIBC_WASI_WRAPPER_H
#define _LIBC_WASI_WRAPPER_H
#include "wasmtime_ssp.h"
#include "posix.h"
#ifdef __cplusplus

View File

@ -8,119 +8,68 @@
#include "ssp_config.h"
#include "blocking_op.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd)
__wasi_errno_t
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
bool is_stdio)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
int ret = close(fd);
__wasi_errno_t error = os_close(handle, is_stdio);
wasm_runtime_end_blocking_op(exec_env);
return error;
}
__wasi_errno_t
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
return __WASI_EINTR;
}
__wasi_errno_t error = os_readv(handle, iov, iovcnt, nread);
wasm_runtime_end_blocking_op(exec_env);
return error;
}
__wasi_errno_t
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_iovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nread)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
return __WASI_EINTR;
}
__wasi_errno_t ret = os_preadv(handle, iov, iovcnt, offset, nread);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
__wasi_errno_t
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
size_t *nwritten)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
ssize_t ret = readv(fd, iov, iovcnt);
__wasi_errno_t error = os_writev(handle, iov, iovcnt, nwritten);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
return error;
}
#if CONFIG_HAS_PREADV
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
__wasi_errno_t
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nwritten)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
ssize_t ret = preadv(fd, iov, iovcnt, offset);
__wasi_errno_t error = os_pwritev(handle, iov, iovcnt, offset, nwritten);
wasm_runtime_end_blocking_op(exec_env);
return ret;
return error;
}
#else /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pread(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#endif /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = writev(fd, iov, iovcnt);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#if CONFIG_HAS_PWRITEV
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwritev(fd, iov, iovcnt, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#else /* CONFIG_HAS_PWRITEV */
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwrite(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#endif /* CONFIG_HAS_PWRITEV */
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
@ -207,20 +156,17 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
return ret;
}
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode)
__wasi_errno_t
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
const char *path, __wasi_oflags_t oflags,
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
wasi_libc_file_access_mode access_mode, os_file_handle *out)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
int ret = openat(fd, path, oflags, mode);
__wasi_errno_t error = os_openat(handle, path, oflags, fd_flags,
lookup_flags, access_mode, out);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
return error;
}

View File

@ -6,26 +6,24 @@
#include "bh_platform.h"
#include "wasm_export.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd);
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset);
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset);
__wasi_errno_t
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
bool is_stdio);
__wasi_errno_t
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread);
__wasi_errno_t
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_iovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nread);
__wasi_errno_t
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
size_t *nwritten);
__wasi_errno_t
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nwritten);
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
bh_socket_t *sockp, void *addr,
@ -48,10 +46,8 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size);
#ifdef BH_PLATFORM_WINDOWS
/* TODO to be (re)moved as part of WASI on windows work */
typedef unsigned mode_t;
#endif
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode);
__wasi_errno_t
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
const char *path, __wasi_oflags_t oflags,
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
wasi_libc_file_access_mode access_mode, os_file_handle *out);

View File

@ -60,7 +60,8 @@ struct addr_pool {
bool
fd_table_init(struct fd_table *);
bool
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, os_file_handle,
bool is_stdio);
bool
fd_prestats_init(struct fd_prestats *);
bool

View File

@ -47,38 +47,6 @@
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(ESP_PLATFORM) \
&& !defined(_WIN32)
#define CONFIG_HAS_FDATASYNC 1
#else
#define CONFIG_HAS_FDATASYNC 0
#endif
/*
* For NuttX, CONFIG_HAS_ISATTY is provided by its platform header.
* (platform_internal.h)
*/
#ifndef __NuttX__
#ifndef __CloudABI__
#define CONFIG_HAS_ISATTY 1
#else
#define CONFIG_HAS_ISATTY 0
#endif
#endif
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(_WIN32) \
&& !defined(__COSMOPOLITAN__)
#define CONFIG_HAS_POSIX_FALLOCATE 1
#else
#define CONFIG_HAS_POSIX_FALLOCATE 0
#endif
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(_WIN32)
#define CONFIG_HAS_PREADV 1
#else
#define CONFIG_HAS_PREADV 0
#endif
#if defined(__APPLE__) || defined(__CloudABI__)
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
#else
@ -92,32 +60,6 @@
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
#endif
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(_WIN32)
#define CONFIG_HAS_PWRITEV 1
#else
#define CONFIG_HAS_PWRITEV 0
#endif
#ifdef __APPLE__
#define st_atim st_atimespec
#define st_ctim st_ctimespec
#define st_mtim st_mtimespec
#endif
#if defined(O_DSYNC)
#define CONFIG_HAS_O_DSYNC
#endif
// POSIX requires O_RSYNC to be defined, but Linux explicitly doesn't support
// it.
#if defined(O_RSYNC) && !defined(__linux__)
#define CONFIG_HAS_O_RSYNC
#endif
#if defined(O_SYNC)
#define CONFIG_HAS_O_SYNC
#endif
#if !defined(BH_PLATFORM_LINUX_SGX)
/* Clang's __GNUC_PREREQ macro has a different meaning than GCC one,
so we have to handle this case specially */
@ -145,10 +87,4 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */
#define CONFIG_HAS_STD_ATOMIC 0
#endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */
#if !defined(__NuttX__)
#define CONFIG_HAS_D_INO 1
#else
#define CONFIG_HAS_D_INO 0
#endif
#endif