Skip to content

Commit

Permalink
Avoid varargs conventions when calling open (#126)
Browse files Browse the repository at this point in the history
* Add an entrypoint for calling open that bypasses the varargs.

* Add an entrypoint for calling openat that bypasses the varargs.
  • Loading branch information
sunfishcode authored Nov 5, 2019
1 parent 7fcc4f2 commit a94d2d0
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 10 deletions.
2 changes: 2 additions & 0 deletions expected/wasm32-wasi/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/dirent/opendirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
//
// SPDX-License-Identifier: BSD-2-Clause

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

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;

Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: BSD-2-Clause

#include <wasi/core.h>
#include <wasi/libc.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
Expand All @@ -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;

Expand Down
8 changes: 8 additions & 0 deletions libc-bottom-half/cloudlibc/src/libc/fcntl/openat.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <assert.h>
#include <wasi/core.h>
#include <wasi/libc.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
Expand All @@ -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().
Expand Down
2 changes: 2 additions & 0 deletions libc-bottom-half/headers/public/wasi/libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions libc-bottom-half/libpreopen/libpreopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
10 changes: 4 additions & 6 deletions libc-bottom-half/sources/truncate.c
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <wasi/libc.h>

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);
}
4 changes: 3 additions & 1 deletion libc-top-half/musl/src/stdio/fopen.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
#else
#include <unistd.h>
#include <wasi/libc.h>
#endif
#include "stdio_impl.h"
#include <fcntl.h>
Expand All @@ -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
Expand Down

0 comments on commit a94d2d0

Please sign in to comment.