summaryrefslogtreecommitdiffstats
path: root/libc-bottom-half
diff options
context:
space:
mode:
Diffstat (limited to 'libc-bottom-half')
-rw-r--r--libc-bottom-half/cloudlibc/src/libc/unistd/close.c16
-rw-r--r--libc-bottom-half/crt/crt1-reactor.c20
-rw-r--r--libc-bottom-half/headers/public/__header_sys_socket.h2
-rw-r--r--libc-bottom-half/headers/public/wasi/libc.h6
-rw-r--r--libc-bottom-half/sources/__wasilibc_fd_renumber.c22
-rw-r--r--libc-bottom-half/sources/__wasilibc_real.c2
-rw-r--r--libc-bottom-half/sources/preopens.c58
7 files changed, 91 insertions, 35 deletions
diff --git a/libc-bottom-half/cloudlibc/src/libc/unistd/close.c b/libc-bottom-half/cloudlibc/src/libc/unistd/close.c
deleted file mode 100644
index 2f5814b..0000000
--- a/libc-bottom-half/cloudlibc/src/libc/unistd/close.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
-//
-// SPDX-License-Identifier: BSD-2-Clause
-
-#include <wasi/api.h>
-#include <errno.h>
-#include <unistd.h>
-
-int close(int fildes) {
- __wasi_errno_t error = __wasi_fd_close(fildes);
- if (error != 0) {
- errno = error;
- return -1;
- }
- return 0;
-}
diff --git a/libc-bottom-half/crt/crt1-reactor.c b/libc-bottom-half/crt/crt1-reactor.c
index f507c9e..ea4a84f 100644
--- a/libc-bottom-half/crt/crt1-reactor.c
+++ b/libc-bottom-half/crt/crt1-reactor.c
@@ -1,7 +1,27 @@
+#if defined(_REENTRANT)
+#include <stdatomic.h>
+extern void __wasi_init_tp(void);
+#endif
extern void __wasm_call_ctors(void);
__attribute__((export_name("_initialize")))
void _initialize(void) {
+#if defined(_REENTRANT)
+ static volatile atomic_int initialized = 0;
+ int expected = 0;
+ if (!atomic_compare_exchange_strong(&initialized, &expected, 1)) {
+ __builtin_trap();
+ }
+
+ __wasi_init_tp();
+#else
+ static volatile int initialized = 0;
+ if (initialized != 0) {
+ __builtin_trap();
+ }
+ initialized = 1;
+#endif
+
// The linker synthesizes this to call constructors.
__wasm_call_ctors();
}
diff --git a/libc-bottom-half/headers/public/__header_sys_socket.h b/libc-bottom-half/headers/public/__header_sys_socket.h
index 9fa8684..77aaa1b 100644
--- a/libc-bottom-half/headers/public/__header_sys_socket.h
+++ b/libc-bottom-half/headers/public/__header_sys_socket.h
@@ -13,7 +13,7 @@
#define MSG_PEEK __WASI_RIFLAGS_RECV_PEEK
#define MSG_WAITALL __WASI_RIFLAGS_RECV_WAITALL
-#define MSG_TRUNC __WASI_RIFLAGS_RECV_DATA_TRUNCATED
+#define MSG_TRUNC __WASI_ROFLAGS_RECV_DATA_TRUNCATED
#define SOCK_DGRAM __WASI_FILETYPE_SOCKET_DGRAM
#define SOCK_STREAM __WASI_FILETYPE_SOCKET_STREAM
diff --git a/libc-bottom-half/headers/public/wasi/libc.h b/libc-bottom-half/headers/public/wasi/libc.h
index b50518b..18d8e9e 100644
--- a/libc-bottom-half/headers/public/wasi/libc.h
+++ b/libc-bottom-half/headers/public/wasi/libc.h
@@ -11,6 +11,12 @@ extern "C" {
struct stat;
struct timespec;
+/// Populate libc's preopen tables. This is normally done automatically
+/// just before it's needed, however if you call `__wasi_fd_renumber` or
+/// `__wasi_fd_close` directly, and you need the preopens to be accurate
+/// afterward, you should call this before doing so.
+void __wasilibc_populate_preopens(void);
+
/// Register the given pre-opened file descriptor under the given path.
///
/// This function does not take ownership of `prefix` (it makes its own copy).
diff --git a/libc-bottom-half/sources/__wasilibc_fd_renumber.c b/libc-bottom-half/sources/__wasilibc_fd_renumber.c
index aa9d8dc..47992e9 100644
--- a/libc-bottom-half/sources/__wasilibc_fd_renumber.c
+++ b/libc-bottom-half/sources/__wasilibc_fd_renumber.c
@@ -4,6 +4,9 @@
#include <unistd.h>
int __wasilibc_fd_renumber(int fd, int newfd) {
+ // Scan the preopen fds before making any changes.
+ __wasilibc_populate_preopens();
+
__wasi_errno_t error = __wasi_fd_renumber(fd, newfd);
if (error != 0) {
errno = error;
@@ -11,3 +14,22 @@ int __wasilibc_fd_renumber(int fd, int newfd) {
}
return 0;
}
+
+int close(int fd) {
+ // Scan the preopen fds before making any changes.
+ __wasilibc_populate_preopens();
+
+ __wasi_errno_t error = __wasi_fd_close(fd);
+ if (error != 0) {
+ errno = error;
+ return -1;
+ }
+
+ return 0;
+}
+
+weak void __wasilibc_populate_preopens(void) {
+ // This version does nothing. It may be overridden by a version which does
+ // something if `__wasilibc_find_abspath` or `__wasilibc_find_relpath` are
+ // used.
+}
diff --git a/libc-bottom-half/sources/__wasilibc_real.c b/libc-bottom-half/sources/__wasilibc_real.c
index d2e6b71..186de01 100644
--- a/libc-bottom-half/sources/__wasilibc_real.c
+++ b/libc-bottom-half/sources/__wasilibc_real.c
@@ -662,7 +662,7 @@ __wasi_errno_t __wasi_sock_shutdown(
#ifdef _REENTRANT
int32_t __imported_wasi_thread_spawn(int32_t arg0) __attribute__((
__import_module__("wasi"),
- __import_name__("thread_spawn")
+ __import_name__("thread-spawn")
));
int32_t __wasi_thread_spawn(void* start_arg) {
diff --git a/libc-bottom-half/sources/preopens.c b/libc-bottom-half/sources/preopens.c
index 7293c8c..b495433 100644
--- a/libc-bottom-half/sources/preopens.c
+++ b/libc-bottom-half/sources/preopens.c
@@ -25,6 +25,7 @@ typedef struct preopen {
} preopen;
/// A simple growable array of `preopen`.
+static _Atomic _Bool preopens_populated = false;
static preopen *preopens;
static size_t num_preopens;
static size_t preopen_capacity;
@@ -100,12 +101,9 @@ static const char *strip_prefixes(const char *path) {
return path;
}
-/// Register the given preopened file descriptor under the given path.
-///
-/// This function takes ownership of `prefix`.
-static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) {
- LOCK(lock);
-
+/// Similar to `internal_register_preopened_fd_unlocked` but does not
+/// take a lock.
+static int internal_register_preopened_fd_unlocked(__wasi_fd_t fd, const char *relprefix) {
// Check preconditions.
assert_invariants();
assert(fd != AT_FDCWD);
@@ -113,22 +111,32 @@ static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix)
assert(relprefix != NULL);
if (num_preopens == preopen_capacity && resize() != 0) {
- UNLOCK(lock);
return -1;
}
char *prefix = strdup(strip_prefixes(relprefix));
if (prefix == NULL) {
- UNLOCK(lock);
return -1;
}
preopens[num_preopens++] = (preopen) { prefix, fd, };
assert_invariants();
- UNLOCK(lock);
return 0;
}
+/// Register the given preopened file descriptor under the given path.
+///
+/// This function takes ownership of `prefix`.
+static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) {
+ LOCK(lock);
+
+ int r = internal_register_preopened_fd_unlocked(fd, relprefix);
+
+ UNLOCK(lock);
+
+ return r;
+}
+
/// Are the `prefix_len` bytes pointed to by `prefix` a prefix of `path`?
static bool prefix_matches(const char *prefix, size_t prefix_len, const char *path) {
// Allow an empty string as a prefix of any relative path.
@@ -152,6 +160,8 @@ static bool prefix_matches(const char *prefix, size_t prefix_len, const char *pa
// See the documentation in libc.h
int __wasilibc_register_preopened_fd(int fd, const char *prefix) {
+ __wasilibc_populate_preopens();
+
return internal_register_preopened_fd((__wasi_fd_t)fd, prefix);
}
@@ -172,6 +182,8 @@ int __wasilibc_find_relpath(const char *path,
int __wasilibc_find_abspath(const char *path,
const char **abs_prefix,
const char **relative_path) {
+ __wasilibc_populate_preopens();
+
// Strip leading `/` characters, the prefixes we're mataching won't have
// them.
while (*path == '/')
@@ -219,13 +231,20 @@ int __wasilibc_find_abspath(const char *path,
return fd;
}
-/// This is referenced by weak reference from crt1.c and lives in the same
-/// source file as `__wasilibc_find_relpath` so that it's linked in when it's
-/// needed.
-// Concerning the 51 -- see the comment by the constructor priority in
-// libc-bottom-half/sources/environ.c.
-__attribute__((constructor(51)))
-static void __wasilibc_populate_preopens(void) {
+void __wasilibc_populate_preopens(void) {
+ // Fast path: If the preopens are already initialized, do nothing.
+ if (preopens_populated) {
+ return;
+ }
+
+ LOCK(lock);
+
+ // Check whether another thread initialized the preopens already.
+ if (preopens_populated) {
+ UNLOCK(lock);
+ return;
+ }
+
// Skip stdin, stdout, and stderr, and count up until we reach an invalid
// file descriptor.
for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
@@ -249,7 +268,7 @@ static void __wasilibc_populate_preopens(void) {
goto oserr;
prefix[prestat.u.dir.pr_name_len] = '\0';
- if (internal_register_preopened_fd(fd, prefix) != 0)
+ if (internal_register_preopened_fd_unlocked(fd, prefix) != 0)
goto software;
free(prefix);
@@ -260,6 +279,11 @@ static void __wasilibc_populate_preopens(void) {
}
}
+ // Preopens are now initialized.
+ preopens_populated = true;
+
+ UNLOCK(lock);
+
return;
oserr:
_Exit(EX_OSERR);