Skip to content
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ override WASM_CFLAGS += --target=$(TARGET_TRIPLE)
# WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it.
override WASM_CFLAGS += -fno-trapping-math
# We should have proper declarations for everything.
override WASM_CFLAGS += \
-Werror=missing-declarations \
-Werror=implicit-function-declaration \

# Configure support for threads.
ifeq ($(THREAD_MODEL), single)
Expand Down
21 changes: 21 additions & 0 deletions expected/wasm32-wasi/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,34 @@ __uflow
__unlist_locked_file
__uselocale
__utc
__wasilibc_access
__wasilibc_fd_renumber
__wasilibc_find_relpath
__wasilibc_init_preopen
__wasilibc_link
__wasilibc_link_newat
__wasilibc_link_oldat
__wasilibc_nocwd___wasilibc_rmdirat
__wasilibc_nocwd___wasilibc_unlinkat
__wasilibc_nocwd_faccessat
__wasilibc_nocwd_fstatat
__wasilibc_nocwd_linkat
__wasilibc_nocwd_mkdirat
__wasilibc_nocwd_openat
__wasilibc_nocwd_opendirat
__wasilibc_nocwd_readlinkat
__wasilibc_nocwd_renameat
__wasilibc_nocwd_scandirat
__wasilibc_nocwd_symlinkat
__wasilibc_nocwd_utimensat
__wasilibc_register_preopened_fd
__wasilibc_rename_newat
__wasilibc_rename_oldat
__wasilibc_rmdirat
__wasilibc_stat
__wasilibc_tell
__wasilibc_unlinkat
__wasilibc_utimens
__wcscoll_l
__wcsftime_l
__wcsxfrm_l
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasi/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
#include <values.h>
#include <wasi/core.h>
#include <wasi/libc-find-relpath.h>
#include <wasi/libc-nocwd.h>
#include <wasi/libc.h>
#include <wchar.h>
#include <wctype.h>
2 changes: 2 additions & 0 deletions expected/wasm32-wasi/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#define ARG_MAX 131072
#define ARMAG "!<arch>\n"
#define AT_EACCESS (0x0)
#define AT_FDCWD (-2)
#define AT_REMOVEDIR (0x4)
#define AT_SYMLINK_FOLLOW (0x2)
#define AT_SYMLINK_NOFOLLOW (0x1)
Expand Down Expand Up @@ -3098,6 +3099,7 @@
#define __wasi_core_h
#define __wasi_libc_find_relpath_h
#define __wasi_libc_h
#define __wasi_libc_nocwd_h
#define __wasilibc___errno_values_h
#define __wasilibc___fd_set_h
#define __wasilibc___function___isatty_h
Expand Down
12 changes: 12 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@
#include <fcntl.h>
#include <stddef.h>
#include <unistd.h>
#ifdef __wasilibc_unmodified_upstream // Use WASI libc's nocwd functions.
#else
#include <wasi/libc-nocwd.h>
#endif

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
DIR *opendirat(int dir, const char *dirname) {
#else
DIR *__wasilibc_nocwd_opendirat(int dir, const char *dirname) {
#endif
// Open directory.
#ifdef __wasilibc_unmodified_upstream // Call the nocwd function directly.
int fd = openat(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_nocwd_openat(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY, 0);
#endif
if (fd == -1)
return NULL;

Expand Down
14 changes: 14 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,36 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef __wasilibc_unmodified_upstream // Use WASI libc's nocwd functions.
#else
#include <wasi/libc-nocwd.h>
#endif

#include "dirent_impl.h"

static int sel_true(const struct dirent *de) {
return 1;
}

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int scandirat(int dirfd, const char *dir, struct dirent ***namelist,
int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) {
#else
int __wasilibc_nocwd_scandirat(int dirfd, const char *dir, struct dirent ***namelist,
int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) {
#endif
// Match all files if no select function is provided.
if (sel == NULL)
sel = sel_true;

// Open the directory.
#ifdef __wasilibc_unmodified_upstream // Call the nocwd function directly.
int fd = openat(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_nocwd_openat(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY, 0);
#endif
if (fd == -1)
return -1;

Expand Down
4 changes: 4 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ static_assert(O_DIRECTORY >> 12 == __WASI_O_DIRECTORY, "Value mismatch");
static_assert(O_EXCL >> 12 == __WASI_O_EXCL, "Value mismatch");
static_assert(O_TRUNC >> 12 == __WASI_O_TRUNC, "Value mismatch");

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int openat(int fd, const char *path, int oflag, ...) {
#else
int __wasilibc_nocwd_openat(int fd, const char *path, int oflag, mode_t mode) {
#endif
// Compute rights corresponding with the access modes provided.
// Attempt to obtain all rights, except the ones that contradict the
// access mode provided to openat().
Expand Down
4 changes: 4 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/stdio/renameat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
#include <stdio.h>
#include <string.h>

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int renameat(int oldfd, const char *old, int newfd, const char *new) {
#else
int __wasilibc_nocwd_renameat(int oldfd, const char *old, int newfd, const char *new) {
#endif
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_rename(oldfd, old, strlen(old),
#else
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/sys/stat/fstatat.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@

#include "stat_impl.h"

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int fstatat(int fd, const char *restrict path, struct stat *restrict buf,
int flag) {
#else
int __wasilibc_nocwd_fstatat(int fd, const char *restrict path, struct stat *restrict buf,
int flag) {
#endif
// Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
Expand Down
4 changes: 2 additions & 2 deletions libc-bottom-half/cloudlibc/src/libc/sys/stat/mkdirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#include <errno.h>
#include <string.h>

#ifdef __wasilibc_unmodified_upstream
#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support, and don't use varargs
int mkdirat(int fd, const char *path, ...) {
#else
int mkdirat(int fd, const char *path, mode_t mode) {
int __wasilibc_nocwd_mkdirat(int fd, const char *path, mode_t mode) {
#endif
#ifdef __wasilibc_unmodified_upstream // __wasi_path_create_directory
__wasi_errno_t error = __wasi_file_create(
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/sys/stat/utimensat.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@

#include "stat_impl.h"

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int utimensat(int fd, const char *path, const struct timespec times[2],
int flag) {
#else
int __wasilibc_nocwd_utimensat(int fd, const char *path, const struct timespec times[2],
int flag) {
#endif
// Convert timestamps and extract NOW/OMIT flags.
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_filestat_t fs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <errno.h>
#include <string.h>

int __wasilibc_rmdirat(int fd, const char *path) {
int __wasilibc_nocwd___wasilibc_rmdirat(int fd, const char *path) {
size_t path_len = strlen(path);
__wasi_errno_t error = __wasi_path_remove_directory(fd, path, path_len);
if (error != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <errno.h>
#include <string.h>

int __wasilibc_unlinkat(int fd, const char *path) {
int __wasilibc_nocwd___wasilibc_unlinkat(int fd, const char *path) {
size_t path_len = strlen(path);
__wasi_errno_t error = __wasi_path_unlink_file(fd, path, path_len);
if (error != 0) {
Expand Down
4 changes: 4 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include <string.h>
#include <unistd.h>

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int faccessat(int fd, const char *path, int amode, int flag) {
#else
int __wasilibc_nocwd_faccessat(int fd, const char *path, int amode, int flag) {
#endif
// Validate function parameters.
if ((amode & ~(F_OK | R_OK | W_OK | X_OK)) != 0 ||
(flag & ~AT_EACCESS) != 0) {
Expand Down
4 changes: 4 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/unistd/linkat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include <string.h>
#include <unistd.h>

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) {
#else
int __wasilibc_nocwd_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) {
#endif
// Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup1 = {.fd = fd1, .flags = 0};
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/unistd/readlinkat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
#include <string.h>
#include <unistd.h>

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf,
size_t bufsize) {
#else
ssize_t __wasilibc_nocwd_readlinkat(int fd, const char *restrict path, char *restrict buf,
size_t bufsize) {
#endif
size_t bufused;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_readlink(fd, path, strlen(path),
Expand Down
4 changes: 4 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/unistd/symlinkat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
#include <string.h>
#include <unistd.h>

#ifdef __wasilibc_unmodified_upstream // Rename for AT_FDCWD support
int symlinkat(const char *path1, int fd, const char *path2) {
#else
int __wasilibc_nocwd_symlinkat(const char *path1, int fd, const char *path2) {
#endif
__wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream
__wasi_file_symlink(path1, strlen(path1), fd, path2, strlen(path2));
Expand Down
1 change: 1 addition & 0 deletions libc-bottom-half/headers/private/stdio.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#include <_/cdefs.h>
int snprintf(char *str, size_t size, const char *format, ...);
int rename(const char *oldpath, const char *newpath);
6 changes: 6 additions & 0 deletions libc-bottom-half/headers/public/__header_fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@

#define FD_CLOEXEC (1)

#define AT_FDCWD (-2)
/*
* WASI doesn't make a distinction between the "real UID" and the
* "effective UID", so AT_EACCESS is 0 because it doesn't change
* anything.
*/
#define AT_EACCESS (0x0)
#define AT_SYMLINK_NOFOLLOW (0x1)
#define AT_SYMLINK_FOLLOW (0x2)
Expand Down
60 changes: 60 additions & 0 deletions libc-bottom-half/headers/public/wasi/libc-nocwd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef __wasi_libc_nocwd_h
#define __wasi_libc_nocwd_h

/*
* In order to support AT_FDCWD, we need to wrap the *at functions to handle
* it by calling back into the non-at versions which perform libpreopen
* queries. These __wasilibc_nocwd_* forms are the underlying calls which
* assume AT_FDCWD has already been resolved.
*/

#define __need_size_t
#include <stddef.h>
#include <__typedef_ssize_t.h>
#include <__typedef_mode_t.h>
#include <__typedef_DIR.h>

#ifdef __cplusplus
extern "C" {
#endif

struct timespec;
struct stat;
struct dirent;

int __wasilibc_nocwd___wasilibc_unlinkat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd___wasilibc_rmdirat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_linkat(int, const char *, int, const char *, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_symlinkat(const char *, int, const char *)
__attribute__((__warn_unused_result__));
ssize_t __wasilibc_nocwd_readlinkat(int, const char *__restrict, char *__restrict, size_t)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_unlinkat(int, const char *, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_faccessat(int, const char *, int, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_renameat(int, const char *, int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_openat(int, const char *, int, mode_t)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_fstatat(int, const char *__restrict, struct stat *__restrict, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_mkdirat(int, const char *, mode_t)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_utimensat(int, const char *, const struct timespec [2], int)
__attribute__((__warn_unused_result__));
DIR *__wasilibc_nocwd_opendirat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_scandirat(int, const char *, struct dirent ***,
int (*)(const struct dirent *),
int (*)(const struct dirent **, const struct dirent **))
__attribute__((__warn_unused_result__));

#ifdef __cplusplus
}
#endif

#endif
37 changes: 32 additions & 5 deletions libc-bottom-half/headers/public/wasi/libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,44 @@
#define __wasi_libc_h

#include <__typedef_off_t.h>
#include <__struct_timespec.h>

#ifdef __cplusplus
extern "C" {
#endif

struct stat;
struct timespec;

void __wasilibc_init_preopen(void);
int __wasilibc_register_preopened_fd(int fd, const char *path);
int __wasilibc_fd_renumber(int fd, int newfd);
int __wasilibc_unlinkat(int fd, const char *path);
int __wasilibc_rmdirat(int fd, const char *path);
off_t __wasilibc_tell(int fd);
int __wasilibc_register_preopened_fd(int fd, const char *path)
__attribute__((__warn_unused_result__));
int __wasilibc_fd_renumber(int fd, int newfd)
__attribute__((__warn_unused_result__));
int __wasilibc_unlinkat(int fd, const char *path)
__attribute__((__warn_unused_result__));
int __wasilibc_rmdirat(int fd, const char *path)
__attribute__((__warn_unused_result__));
off_t __wasilibc_tell(int fd)
__attribute__((__warn_unused_result__));

/* Non-`at` forms of various `*at` functions. */
int __wasilibc_access(const char *pathname, int mode, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_stat(const char *__restrict pathname, struct stat *__restrict statbuf, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_utimens(const char *pathname, const struct timespec times[2], int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link(const char *oldpath, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link_oldat(int olddirfd, const char *oldpath, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link_newat(const char *oldpath, int newdirfd, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_rename_oldat(int olddirfd, const char *oldpath, const char *newpath)
__attribute__((__warn_unused_result__));
int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpath)
__attribute__((__warn_unused_result__));

#ifdef __cplusplus
}
Expand Down
Loading