From 8987432f369d8cd70bc632be55ed2eb2a1cb5aed Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:02:25 +0100 Subject: [PATCH] libc-wasi: Conditionally support SYNC flags (#2581) To make it clearer to users when synchronization behaviour is not supported, return ENOTSUP when O_RSYNC, O_DSYNC or O_SYNC are respectively not defined. Linux also doesn't support O_RSYNC despite the O_RSYNC flag being defined. --- .../sandboxed-system-primitives/src/posix.c | 34 ++++++++++++------- .../src/ssp_config.h | 16 ++++++++- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index eda65b8da4..5c85a81d63 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -1282,18 +1282,20 @@ wasmtime_ssp_fd_fdstat_get(wasm_exec_env_t exec_env, struct fd_table *curfds, if ((ret & O_APPEND) != 0) buf->fs_flags |= __WASI_FDFLAG_APPEND; -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC if ((ret & O_DSYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_DSYNC; #endif if ((ret & O_NONBLOCK) != 0) buf->fs_flags |= __WASI_FDFLAG_NONBLOCK; -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC if ((ret & O_RSYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_RSYNC; #endif +#ifdef CONFIG_HAS_O_SYNC if ((ret & O_SYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_SYNC; +#endif return 0; } @@ -1306,21 +1308,25 @@ wasmtime_ssp_fd_fdstat_set_flags(wasm_exec_env_t exec_env, if ((fs_flags & __WASI_FDFLAG_APPEND) != 0) noflags |= O_APPEND; if ((fs_flags & __WASI_FDFLAG_DSYNC) != 0) -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC noflags |= O_DSYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif if ((fs_flags & __WASI_FDFLAG_NONBLOCK) != 0) noflags |= O_NONBLOCK; if ((fs_flags & __WASI_FDFLAG_RSYNC) != 0) -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC noflags |= O_RSYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif if ((fs_flags & __WASI_FDFLAG_SYNC) != 0) +#ifdef CONFIG_HAS_O_SYNC noflags |= O_SYNC; +#else + return __WASI_ENOTSUP; +#endif struct fd_object *fo; __wasi_errno_t error = @@ -1971,26 +1977,30 @@ wasmtime_ssp_path_open(wasm_exec_env_t exec_env, struct fd_table *curfds, if ((fs_flags & __WASI_FDFLAG_APPEND) != 0) noflags |= O_APPEND; if ((fs_flags & __WASI_FDFLAG_DSYNC) != 0) { -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC noflags |= O_DSYNC; + needed_inheriting |= __WASI_RIGHT_FD_DATASYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif - needed_inheriting |= __WASI_RIGHT_FD_DATASYNC; } if ((fs_flags & __WASI_FDFLAG_NONBLOCK) != 0) noflags |= O_NONBLOCK; if ((fs_flags & __WASI_FDFLAG_RSYNC) != 0) { -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC noflags |= O_RSYNC; + needed_inheriting |= __WASI_RIGHT_FD_SYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif - needed_inheriting |= __WASI_RIGHT_FD_SYNC; } if ((fs_flags & __WASI_FDFLAG_SYNC) != 0) { +#ifdef CONFIG_HAS_O_SYNC noflags |= O_SYNC; needed_inheriting |= __WASI_RIGHT_FD_SYNC; +#else + return __WASI_ENOTSUP; +#endif } if (write && (noflags & (O_APPEND | O_TRUNC)) == 0) needed_inheriting |= __WASI_RIGHT_FD_SEEK; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index f5e130a9ee..f75da5d8a0 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -14,8 +14,8 @@ #ifndef SSP_CONFIG_H #define SSP_CONFIG_H +#include "bh_platform.h" #include "gnuc.h" -#include #if defined(__FreeBSD__) || defined(__APPLE__) \ || (defined(ANDROID) && __ANDROID_API__ < 28) @@ -101,6 +101,20 @@ #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 */