summaryrefslogtreecommitdiffstats
path: root/libc-bottom-half/sources
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:11:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:11:56 +0000
commite9699e2b995d3ded2efd5580ae6dadf555181d62 (patch)
treedd029bd1e3b8b9ffb627115e7ecc577f250fa742 /libc-bottom-half/sources
parentAdding upstream version 0.0~git20230113.4362b18. (diff)
downloadwasi-libc-e9699e2b995d3ded2efd5580ae6dadf555181d62.tar.xz
wasi-libc-e9699e2b995d3ded2efd5580ae6dadf555181d62.zip
Adding upstream version 0.0~git20230621.7018e24.upstream/0.0_git20230621.7018e24
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-bottom-half/sources')
-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
3 files changed, 64 insertions, 18 deletions
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);