Skip to content

Commit

Permalink
AT_FDCWD support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Feb 4, 2021
1 parent 5ccfab7 commit c88708f
Show file tree
Hide file tree
Showing 24 changed files with 448 additions and 251 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ CFLAGS = $(WASM_CFLAGS) --target=$(TARGET_TRIPLE)
# WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it.
CFLAGS += -fno-trapping-math
# We should have proper declarations for everything.
CFLAGS += \
-Werror=missing-declarations \
-Werror=implicit-function-declaration \

# Configure support for threads.
ifeq ($(THREAD_MODEL), single)
Expand Down
22 changes: 21 additions & 1 deletion expected/wasm32-wasi/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ __uflow
__unlist_locked_file
__uselocale
__utc
__wasilibc_access
__wasilibc_cwd
__wasilibc_ensure_environ
__wasilibc_environ
Expand All @@ -258,12 +259,31 @@ __wasilibc_find_abspath
__wasilibc_find_relpath
__wasilibc_find_relpath_alloc
__wasilibc_initialize_environ
__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_nomode
__wasilibc_nocwd_opendirat
__wasilibc_nocwd_readlinkat
__wasilibc_nocwd_renameat
__wasilibc_nocwd_scandirat
__wasilibc_nocwd_symlinkat
__wasilibc_nocwd_utimensat
__wasilibc_open_nomode
__wasilibc_openat_nomode
__wasilibc_register_preopened_fd
__wasilibc_rename_newat
__wasilibc_rename_oldat
__wasilibc_rmdirat
__wasilibc_stat
__wasilibc_tell
__wasilibc_unlinkat
__wasilibc_utimens
__wasm_call_dtors
__wcscoll_l
__wcsftime_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 @@ -166,6 +166,7 @@
#include <wasi/api.h>
#include <wasi/libc-environ.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 @@ -3021,6 +3022,7 @@
#define __wasi_libc_environ_h
#define __wasi_libc_find_relpath_h
#define __wasi_libc_h
#define __wasi_libc_nocwd_h
#define __wasilibc___errno_h
#define __wasilibc___errno_values_h
#define __wasilibc___fd_set_h
Expand Down
9 changes: 3 additions & 6 deletions libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
// SPDX-License-Identifier: BSD-2-Clause

#include <wasi/libc.h>
#include <wasi/libc-nocwd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stddef.h>
#include <unistd.h>

DIR *opendirat(int dir, const char *dirname) {
DIR *__wasilibc_nocwd_opendirat(int dir, const char *dirname) {
// Open directory.
#ifdef __wasilibc_unmodified_upstream // avoid making a varargs call
int fd = openat(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_openat_nomode(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#endif
int fd = __wasilibc_nocwd_openat_nomode(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
if (fd == -1)
return NULL;

Expand Down
17 changes: 5 additions & 12 deletions libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <wasi/api.h>
#include <wasi/libc.h>
#include <wasi/libc-nocwd.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
Expand All @@ -17,19 +18,15 @@ static int sel_true(const struct dirent *de) {
return 1;
}

int scandirat(int dirfd, const char *dir, struct dirent ***namelist,
int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) {
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 **)) {
// Match all files if no select function is provided.
if (sel == NULL)
sel = sel_true;

// Open the directory.
#ifdef __wasilibc_unmodified_upstream // avoid making a varargs call
int fd = openat(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_openat_nomode(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#endif
int fd = __wasilibc_nocwd_openat_nomode(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
if (fd == -1)
return -1;

Expand Down Expand Up @@ -119,12 +116,8 @@ int scandirat(int dirfd, const char *dir, struct dirent ***namelist,

read_entries:;
// Load more directory entries and continue.
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_readdir(fd, buffer, buffer_size,
#else
// TODO: Remove the cast on `buffer` once the witx is updated with char8 support.
__wasi_errno_t error = __wasi_fd_readdir(fd, (uint8_t *)buffer, buffer_size,
#endif
cookie, &buffer_used);
if (error != 0) {
errno = error;
Expand Down
104 changes: 2 additions & 102 deletions libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,156 +11,61 @@
#include <fcntl.h>
#include <string.h>

#ifdef __wasilibc_unmodified_upstream // fstat
static_assert(O_APPEND == __WASI_FDFLAG_APPEND, "Value mismatch");
static_assert(O_DSYNC == __WASI_FDFLAG_DSYNC, "Value mismatch");
static_assert(O_NONBLOCK == __WASI_FDFLAG_NONBLOCK, "Value mismatch");
static_assert(O_RSYNC == __WASI_FDFLAG_RSYNC, "Value mismatch");
static_assert(O_SYNC == __WASI_FDFLAG_SYNC, "Value mismatch");
#else
static_assert(O_APPEND == __WASI_FDFLAGS_APPEND, "Value mismatch");
static_assert(O_DSYNC == __WASI_FDFLAGS_DSYNC, "Value mismatch");
static_assert(O_NONBLOCK == __WASI_FDFLAGS_NONBLOCK, "Value mismatch");
static_assert(O_RSYNC == __WASI_FDFLAGS_RSYNC, "Value mismatch");
static_assert(O_SYNC == __WASI_FDFLAGS_SYNC, "Value mismatch");
#endif

#ifdef __wasilibc_unmodified_upstream // fstat
static_assert(O_CREAT >> 12 == __WASI_O_CREAT, "Value mismatch");
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");
#else
static_assert(O_CREAT >> 12 == __WASI_OFLAGS_CREAT, "Value mismatch");
static_assert(O_DIRECTORY >> 12 == __WASI_OFLAGS_DIRECTORY, "Value mismatch");
static_assert(O_EXCL >> 12 == __WASI_OFLAGS_EXCL, "Value mismatch");
static_assert(O_TRUNC >> 12 == __WASI_OFLAGS_TRUNC, "Value mismatch");
#endif

int openat(int fd, const char *path, int oflag, ...) {
#ifdef __wasilibc_unmodified_upstream // fstat
#else
return __wasilibc_openat_nomode(fd, path, oflag);
}

int __wasilibc_openat_nomode(int fd, const char *path, int oflag) {
#endif
int __wasilibc_nocwd_openat_nomode(int fd, const char *path, int oflag) {
// Compute rights corresponding with the access modes provided.
// Attempt to obtain all rights, except the ones that contradict the
// access mode provided to openat().
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
__wasi_rights_t min = 0;
#endif
__wasi_rights_t max =
#ifdef __wasilibc_unmodified_upstream // fstat
~(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ |
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FILE_ALLOCATE |
__WASI_RIGHT_FILE_READDIR | __WASI_RIGHT_FILE_STAT_FPUT_SIZE |
#else
~(__WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ |
__WASI_RIGHTS_FD_WRITE | __WASI_RIGHTS_FD_ALLOCATE |
__WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE |
#endif
#ifdef __wasilibc_unmodified_upstream // RIGHT_MEM_MAP_EXEC
__WASI_RIGHT_MEM_MAP_EXEC);
#else
0);
#endif
__WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE);
switch (oflag & O_ACCMODE) {
case O_RDONLY:
case O_RDWR:
case O_WRONLY:
if ((oflag & O_RDONLY) != 0) {
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
min |= (oflag & O_DIRECTORY) == 0 ? __WASI_RIGHT_FD_READ
: __WASI_RIGHT_FILE_READDIR;
#endif
#ifdef __wasilibc_unmodified_upstream // RIGHT_MEM_MAP_EXEC
max |= __WASI_RIGHT_FD_READ | __WASI_RIGHT_FILE_READDIR |
__WASI_RIGHT_MEM_MAP_EXEC;
#else
max |= __WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR;
#endif
}
if ((oflag & O_WRONLY) != 0) {
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
min |= __WASI_RIGHT_FD_WRITE;
if ((oflag & O_APPEND) == 0)
min |= __WASI_RIGHT_FD_SEEK;
#endif
#ifdef __wasilibc_unmodified_upstream // fstat
max |= __WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_WRITE |
__WASI_RIGHT_FILE_ALLOCATE |
__WASI_RIGHT_FILE_STAT_FPUT_SIZE;
#else
max |= __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_WRITE |
__WASI_RIGHTS_FD_ALLOCATE |
__WASI_RIGHTS_FD_FILESTAT_SET_SIZE;
#endif
}
break;
case O_EXEC:
#ifdef __wasilibc_unmodified_upstream // RIGHT_PROC_EXEC
min |= __WASI_RIGHT_PROC_EXEC;
#endif
break;
case O_SEARCH:
break;
default:
errno = EINVAL;
return -1;
}
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
assert((min & max) == min &&
"Minimal rights should be a subset of the maximum");
#endif

// Ensure that we can actually obtain the minimal rights needed.
__wasi_fdstat_t fsb_cur;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_fd_stat_get(fd, &fsb_cur);
#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fd, &fsb_cur);
#endif
if (error != 0) {
errno = error;
return -1;
}
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
if (fsb_cur.fs_filetype != __WASI_FILETYPE_DIRECTORY) {
errno = ENOTDIR;
return -1;
}
if ((min & fsb_cur.fs_rights_inheriting) != min) {
errno = ENOTCAPABLE;
return -1;
}
#endif

// Path lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
#else
__wasi_lookupflags_t lookup_flags = 0;
#endif
if ((oflag & O_NOFOLLOW) == 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif

// Open file with appropriate rights.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t and __wasi_fdstat_t
__wasi_fdstat_t fsb_new = {
.fs_flags = oflag & 0xfff,
.fs_rights_base = max & fsb_cur.fs_rights_inheriting,
.fs_rights_inheriting = fsb_cur.fs_rights_inheriting,
};
__wasi_fd_t newfd;
error = __wasi_file_open(lookup, path, strlen(path),
(oflag >> 12) & 0xfff, &fsb_new, &newfd);
#else
__wasi_fdflags_t fs_flags = oflag & 0xfff;
__wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting;
__wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting;
Expand All @@ -169,13 +74,8 @@ int __wasilibc_openat_nomode(int fd, const char *path, int oflag) {
(oflag >> 12) & 0xfff,
fs_rights_base, fs_rights_inheriting, fs_flags,
&newfd);
#endif
if (error != 0) {
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
errno = errno_fixup_directory(lookup.fd, error);
#else
errno = errno_fixup_directory(fd, error);
#endif
return -1;
}
return newfd;
Expand Down
8 changes: 2 additions & 6 deletions libc-bottom-half/cloudlibc/src/libc/stdio/renameat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
#include <stdio.h>
#include <string.h>

int renameat(int oldfd, const char *old, int newfd, const char *new) {
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_rename(oldfd, old, strlen(old),
#else
int __wasilibc_nocwd_renameat(int oldfd, const char *old, int newfd, const char *new) {
__wasi_errno_t error = __wasi_path_rename(oldfd, old, strlen(old),
#endif
newfd, new, strlen(new));
newfd, new, strlen(new));
if (error != 0) {
errno = errno_fixup_directory(oldfd, errno_fixup_directory(newfd, error));
return -1;
Expand Down
16 changes: 2 additions & 14 deletions libc-bottom-half/cloudlibc/src/libc/sys/stat/fstatat.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,17 @@

#include "stat_impl.h"

int fstatat(int fd, const char *restrict path, struct stat *restrict buf,
int flag) {
int __wasilibc_nocwd_fstatat(int fd, const char *restrict path, struct stat *restrict buf,
int flag) {
// Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
#else
__wasi_lookupflags_t lookup_flags = 0;
#endif
if ((flag & AT_SYMLINK_NOFOLLOW) == 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif

// Perform system call.
__wasi_filestat_t internal_stat;
__wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_file_stat_get(lookup, path, strlen(path), &internal_stat);
#else
__wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &internal_stat);
#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
Expand Down
11 changes: 1 addition & 10 deletions libc-bottom-half/cloudlibc/src/libc/sys/stat/mkdirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,9 @@
#include <errno.h>
#include <string.h>

#ifdef __wasilibc_unmodified_upstream
int mkdirat(int fd, const char *path, ...) {
#else
int 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(
fd, path, strlen(path), __WASI_FILETYPE_DIRECTORY);
#else
int __wasilibc_nocwd_mkdirat(int fd, const char *path, mode_t mode) {
__wasi_errno_t error = __wasi_path_create_directory(
fd, path, strlen(path));
#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
Expand Down
Loading

0 comments on commit c88708f

Please sign in to comment.