Avoid varargs conventions when calling open (#126)

* Add an entrypoint for calling open that bypasses the varargs.

* Add an entrypoint for calling openat that bypasses the varargs.
This commit is contained in:
Dan Gohman 2019-11-04 16:37:45 -08:00 committed by GitHub
parent 7fcc4f29df
commit a94d2d04e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 10 deletions

View File

@ -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

View File

@ -2,6 +2,7 @@
//
// SPDX-License-Identifier: BSD-2-Clause
#include <wasi/libc.h>
#include <dirent.h>
#include <fcntl.h>
#include <stddef.h>
@ -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;

View File

@ -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>
@ -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;

View File

@ -6,6 +6,7 @@
#include <assert.h>
#include <wasi/core.h>
#include <wasi/libc.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@ -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().

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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>
@ -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