diff --git a/expected/wasm32-wasi/defined-symbols.txt b/expected/wasm32-wasi/defined-symbols.txt index 2b6a0af..d50f745 100644 --- a/expected/wasm32-wasi/defined-symbols.txt +++ b/expected/wasm32-wasi/defined-symbols.txt @@ -251,6 +251,8 @@ __uselocale __utc __wasilibc_fd_renumber __wasilibc_find_relpath +__wasilibc_open_nomode +__wasilibc_openat_nomode __wasilibc_populate_environ __wasilibc_register_preopened_fd __wasilibc_rmdirat diff --git a/libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c b/libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c index ecda800..c940d5f 100644 --- a/libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c +++ b/libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: BSD-2-Clause +#include #include #include #include @@ -9,7 +10,11 @@ DIR *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 if (fd == -1) return NULL; diff --git a/libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c b/libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c index 324c590..345234f 100644 --- a/libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c +++ b/libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c @@ -3,6 +3,7 @@ // SPDX-License-Identifier: BSD-2-Clause #include +#include #include #include #include @@ -24,7 +25,11 @@ int scandirat(int dirfd, const char *dir, struct dirent ***namelist, 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 if (fd == -1) return -1; diff --git a/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c b/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c index 790434d..0b62500 100644 --- a/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c +++ b/libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,13 @@ static_assert(O_EXCL >> 12 == __WASI_O_EXCL, "Value mismatch"); static_assert(O_TRUNC >> 12 == __WASI_O_TRUNC, "Value mismatch"); 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 // Compute rights corresponding with the access modes provided. // Attempt to obtain all rights, except the ones that contradict the // access mode provided to openat(). diff --git a/libc-bottom-half/headers/public/wasi/libc.h b/libc-bottom-half/headers/public/wasi/libc.h index 643cc68..4bbc1dc 100644 --- a/libc-bottom-half/headers/public/wasi/libc.h +++ b/libc-bottom-half/headers/public/wasi/libc.h @@ -11,6 +11,8 @@ 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); +int __wasilibc_open_nomode(const char *path, int oflag); +int __wasilibc_openat_nomode(int fd, const char *path, int oflag); off_t __wasilibc_tell(int fd); #ifdef __cplusplus diff --git a/libc-bottom-half/libpreopen/libpreopen.c b/libc-bottom-half/libpreopen/libpreopen.c index 2579110..8a17a42 100644 --- a/libc-bottom-half/libpreopen/libpreopen.c +++ b/libc-bottom-half/libpreopen/libpreopen.c @@ -65,6 +65,14 @@ int open(const char *path, int flags, ...) +{ + // WASI libc's openat ignores the mode argument, so call a special + // entrypoint which avoids the varargs calling convention. + return __wasilibc_open_nomode(path, flags); +} + +int +__wasilibc_open_nomode(const char *path, int flags) { const char *relative_path; int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_OPEN, 0, @@ -77,9 +85,7 @@ open(const char *path, int flags, ...) return -1; } - // WASI libc's openat ignores the mode argument, so don't bother passing - // the actual mode value through. - return openat(dirfd, relative_path, flags); + return __wasilibc_openat_nomode(dirfd, relative_path, flags); } int diff --git a/libc-bottom-half/sources/truncate.c b/libc-bottom-half/sources/truncate.c index b56123d..24ae28f 100644 --- a/libc-bottom-half/sources/truncate.c +++ b/libc-bottom-half/sources/truncate.c @@ -1,23 +1,21 @@ #include #include #include +#include int truncate(const char *path, off_t length) { - int fd = open(path, O_WRONLY | O_CLOEXEC | O_NOCTTY); + int fd = __wasilibc_open_nomode(path, O_WRONLY | O_CLOEXEC | O_NOCTTY); if (fd < 0) return -1; int result = ftruncate(fd, length); - if (result < 0) { + if (result != 0) { int save_errno = errno; (void)close(fd); errno = save_errno; return -1; } - if (close(fd) < 0) - return -1; - - return 0; + return close(fd); } diff --git a/libc-top-half/musl/src/stdio/fopen.c b/libc-top-half/musl/src/stdio/fopen.c index 07f035d..670f438 100644 --- a/libc-top-half/musl/src/stdio/fopen.c +++ b/libc-top-half/musl/src/stdio/fopen.c @@ -1,6 +1,7 @@ #ifdef __wasilibc_unmodified_upstream // WASI has no syscall #else #include +#include #endif #include "stdio_impl.h" #include @@ -25,7 +26,8 @@ FILE *fopen(const char *restrict filename, const char *restrict mode) #ifdef __wasilibc_unmodified_upstream // WASI has no sys_open fd = sys_open(filename, flags, 0666); #else - fd = open(filename, flags, 0666); + // WASI libc ignores the mode parameter anyway, so skip the varargs. + fd = __wasilibc_open_nomode(filename, flags); #endif if (fd < 0) return 0; #ifdef __wasilibc_unmodified_upstream // WASI has no syscall