#include <wasi/api.h>
-#ifdef __wasilibc_unmodified_upstream
-// Translates ENOTCAPABLE to ENOTDIR if not a directory.
-static inline __wasi_errno_t errno_fixup_directory(__wasi_fd_t fd,
- __wasi_errno_t error) {
- if (error == __WASI_ENOTCAPABLE) {
- __wasi_fdstat_t fds;
- if (__wasi_fd_stat_get(fd, &fds) == 0 &&
- fds.fs_filetype != __WASI_FILETYPE_DIRECTORY)
- return __WASI_ENOTDIR;
- }
- return error;
-}
-#else
// WASI syscalls should just return ENOTDIR if that's what the problem is.
static inline __wasi_errno_t errno_fixup_directory(__wasi_fd_t fd,
__wasi_errno_t error) {
return error;
}
-#endif
-
-#ifdef __wasilibc_unmodified_upstream // posix_spawn etc.
-// Translates ENOTCAPABLE to EBADF if a regular file or EACCES otherwise.
-static inline __wasi_errno_t errno_fixup_executable(__wasi_fd_t fd,
- __wasi_errno_t error) {
- if (error == __WASI_ENOTCAPABLE) {
- __wasi_fdstat_t fds;
- if (__wasi_fd_stat_get(fd, &fds) == 0)
- return fds.fs_filetype == __WASI_FILETYPE_REGULAR_FILE
- ? __WASI_EBADF
- : __WASI_EACCES;
- }
- return error;
-}
-#endif
-#ifdef __wasilibc_unmodified_upstream // process file descriptors
-// Translates ENOTCAPABLE to EINVAL if not a process.
-static inline __wasi_errno_t errno_fixup_process(__wasi_fd_t fd,
- __wasi_errno_t error) {
- if (error == __WASI_ENOTCAPABLE) {
- __wasi_fdstat_t fds;
- if (__wasi_fd_stat_get(fd, &fds) == 0 &&
- fds.fs_filetype != __WASI_FILETYPE_PROCESS)
- return __WASI_EINVAL;
- }
- return error;
-}
-#endif
-
-#ifdef __wasilibc_unmodified_upstream
-// Translates ENOTCAPABLE to ENOTSOCK if not a socket.
-static inline __wasi_errno_t errno_fixup_socket(__wasi_fd_t fd,
- __wasi_errno_t error) {
- if (error == __WASI_ENOTCAPABLE) {
- __wasi_fdstat_t fds;
- if (__wasi_fd_stat_get(fd, &fds) == 0 &&
-#ifdef __wasilibc_unmodified_upstream // don't hard-code magic numbers
- (fds.fs_filetype & 0xf0) != 0x80)
-#else
- (fds.fs_filetype != __WASI_FILETYPE_SOCKET_STREAM &&
- fds.fs_filetype != __WASI_FILETYPE_SOCKET_DGRAM))
-#endif
- return __WASI_ENOTSOCK;
- }
- return error;
-}
-#else
// WASI syscalls should just return ENOTSOCK if that's what the problem is.
static inline __wasi_errno_t errno_fixup_socket(__wasi_fd_t fd,
__wasi_errno_t error) {
return error;
}
-#endif
#endif
#include <_/limits.h>
#include <_/types.h>
-#ifdef __wasilibc_unmodified_upstream
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#define RAND_MAX _INT_MAX
-
-#define NULL _NULL
-
-typedef struct {
- int quot;
- int rem;
-} div_t;
-
-typedef struct {
- long quot;
- long rem;
-} ldiv_t;
-
-typedef struct {
- long long quot;
- long long rem;
-} lldiv_t;
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-#ifndef _WCHAR_T_DECLARED
-typedef __wchar_t wchar_t;
-#define _WCHAR_T_DECLARED
-#endif
-
-#ifdef __wasilibc_unmodified_upstream
-// Process wide locale always uses ASCII.
-#define MB_CUR_MAX ((size_t)1)
-#endif
-
-// Keep existing code happy that assumes that MB_CUR_MAX_L is a macro.
-#define MB_CUR_MAX_L MB_CUR_MAX_L
-
-#define alloca(size) __builtin_alloca(size)
-#endif
-
__BEGIN_DECLS
_Noreturn void _Exit(int);
-#ifdef __wasilibc_unmodified_upstream
-size_t MB_CUR_MAX_L(__locale_t);
-long a64l(const char *);
-#endif
_Noreturn void abort(void);
-#ifdef __wasilibc_unmodified_upstream
-int abs(int) __pure2;
-int at_quick_exit(void (*)(void));
-int atexit(void (*)(void));
-void *aligned_alloc(size_t, size_t);
-__uint32_t arc4random(void);
-void arc4random_buf(void *, size_t);
-__uint32_t arc4random_uniform(__uint32_t);
-double atof(const char *);
-int atoi(const char *);
-long atol(const char *);
-long long atoll(const char *);
-void *bsearch(const void *, const void *, size_t, size_t,
- int (*)(const void *, const void *));
-#endif
void *calloc(size_t, size_t);
-#ifdef __wasilibc_unmodified_upstream
-div_t div(int, int) __pure2;
-double drand48(void);
-double erand48(__uint16_t *);
-#endif
_Noreturn void exit(int);
void free(void *);
-#ifdef __wasilibc_unmodified_upstream
-char *getenv(const char *);
-int getsubopt(char **, char *const *, char **);
-long jrand48(__uint16_t *);
-int l64a_r(long, char *, int);
-long labs(long) __pure2;
-ldiv_t ldiv(long, long) __pure2;
-long long llabs(long long) __pure2;
-lldiv_t lldiv(long long, long long) __pure2;
-long lrand48(void);
-#endif
void *malloc(size_t);
-#ifdef __wasilibc_unmodified_upstream
-int mblen(const char *, size_t);
-int mblen_l(const char *, size_t, __locale_t);
-size_t mbstowcs(wchar_t *__restrict, const char *__restrict, size_t);
-size_t mbstowcs_l(wchar_t *__restrict, const char *__restrict, size_t,
- __locale_t);
-int mbtowc(wchar_t *__restrict, const char *__restrict, size_t);
-int mbtowc_l(wchar_t *__restrict, const char *__restrict, size_t, __locale_t);
-long mrand48(void);
-long nrand48(__uint16_t *);
-int posix_memalign(void **, size_t, size_t);
-#endif
void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
-#ifdef __wasilibc_unmodified_upstream
-void qsort_r(void *, size_t, size_t,
- int (*)(const void *, const void *, void *), void *);
-_Noreturn void quick_exit(int);
-int rand(void);
-long random(void);
-#endif
void *realloc(void *, size_t);
-#ifdef __wasilibc_unmodified_upstream
-void *reallocarray(void *, size_t, size_t);
-double strtod(const char *__restrict, char **__restrict);
-double strtod_l(const char *__restrict, char **__restrict, __locale_t);
-float strtof(const char *__restrict, char **__restrict);
-float strtof_l(const char *__restrict, char **__restrict, __locale_t);
-long strtol(const char *__restrict, char **__restrict, int);
-long strtol_l(const char *__restrict, char **__restrict, int, __locale_t);
-long double strtold(const char *__restrict, char **__restrict);
-long double strtold_l(const char *__restrict, char **__restrict, __locale_t);
-long long strtoll(const char *__restrict, char **__restrict, int);
-long long strtoll_l(const char *__restrict, char **__restrict, int, __locale_t);
-unsigned long strtoul(const char *__restrict, char **__restrict, int);
-unsigned long strtoul_l(const char *__restrict, char **__restrict, int,
- __locale_t);
-unsigned long long strtoull(const char *__restrict, char **__restrict, int);
-unsigned long long strtoull_l(const char *__restrict, char **__restrict, int,
- __locale_t);
-size_t wcstombs(char *__restrict, const wchar_t *__restrict, size_t);
-size_t wcstombs_l(char *__restrict, const wchar_t *__restrict, size_t,
- __locale_t);
-int wctomb(char *, wchar_t);
-int wctomb_l(char *, wchar_t, __locale_t);
-#endif
__END_DECLS
#if _CLOUDLIBC_INLINE_FUNCTIONS
-#ifdef __wasilibc_unmodified_upstream
-static __inline double __atof(const char *__str) {
- return strtod(__str, NULL);
-}
-#define atof(str) __atof(str)
-
-static __inline int __atoi(const char *__str) {
- return (int)strtol(__str, NULL, 10);
-}
-#define atoi(str) __atoi(str)
-
-static __inline long __atol(const char *__str) {
- return strtol(__str, NULL, 10);
-}
-#define atol(str) __atol(str)
-
-static __inline long long __atoll(const char *__str) {
- return strtoll(__str, NULL, 10);
-}
-#define atoll(str) __atoll(str)
-
-static __inline int __abs(int __i) {
- return __i < 0 ? -__i : __i;
-}
-#define abs(i) __abs(i)
-
-static __inline long __labs(long __i) {
- return __i < 0 ? -__i : __i;
-}
-#define labs(i) __labs(i)
-
-static __inline long long __llabs(long long __i) {
- return __i < 0 ? -__i : __i;
-}
-#define llabs(i) __llabs(i)
-
-static __inline div_t __div(int __numer, int __denom) {
- div_t __res = {__numer / __denom, __numer % __denom};
- return __res;
-}
-#define div(numer, denom) __div(numer, denom)
-
-static __inline ldiv_t __ldiv(long __numer, long __denom) {
- ldiv_t __res = {__numer / __denom, __numer % __denom};
- return __res;
-}
-#define ldiv(numer, denom) __ldiv(numer, denom)
-
-static __inline lldiv_t __lldiv(long long __numer, long long __denom) {
- lldiv_t __res = {__numer / __denom, __numer % __denom};
- return __res;
-}
-#define lldiv(numer, denom) __lldiv(numer, denom)
-
-static __inline void *__bsearch(const void *__key, const void *__base,
- size_t __nel, size_t __width,
- int (*__compar)(const void *, const void *)) {
- const char *__basep, *__obj;
- size_t __mid, __skip;
- int __cmp;
-
- __basep = (const char *)__base;
- while (__nel > 0) {
- // Pick pivot.
- __mid = __nel / 2;
- __obj = __basep + __mid * __width;
- __cmp = __compar(__key, (const void *)__obj);
- if (__cmp < 0) {
- // key < obj. Restrict search to top of the list.
- __nel = __mid;
- } else if (__cmp > 0) {
- // key > obj. Restrict search to bottom of the list.
- __skip = __mid + 1;
- __basep += __skip * __width;
- __nel -= __skip;
- } else {
- return (void *)__obj;
- }
- }
- return NULL;
-}
-#define bsearch(key, base, nel, width, compar) \
- __preserve_const(void, __bsearch, base, key, base, nel, width, compar)
-#endif
// qsort_r() implementation from Bentley and McIlroy's
// "Engineering a Sort Function".
// Ensure that this is really a directory by already loading the first
// chunk of data.
__wasi_errno_t error =
-#ifdef __wasilibc_unmodified_upstream
- __wasi_file_readdir(fd, dirp->buffer, DIRENT_DEFAULT_BUFFER_SIZE,
-#else
// TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support.
__wasi_fd_readdir(fd, (uint8_t *)dirp->buffer, DIRENT_DEFAULT_BUFFER_SIZE,
-#endif
__WASI_DIRCOOKIE_START, &dirp->buffer_used);
if (error != 0) {
free(dirp->buffer);
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;
// Load more directory entries and continue.
__wasi_errno_t error =
-#ifdef __wasilibc_unmodified_upstream
- __wasi_file_readdir(dirp->fd, dirp->buffer, dirp->buffer_size,
-#else
// TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support.
__wasi_fd_readdir(dirp->fd, (uint8_t *)dirp->buffer, dirp->buffer_size,
-#endif
dirp->cookie, &dirp->buffer_used);
if (error != 0) {
errno = error;
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;
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;
case F_GETFL: {
// Obtain the flags and the rights of the descriptor.
__wasi_fdstat_t fds;
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_fd_stat_get(fildes, &fds);
-#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds);
-#endif
if (error != 0) {
errno = error;
return -1;
// Roughly approximate the access mode by converting the rights.
int oflags = fds.fs_flags;
if ((fds.fs_rights_base &
-#ifdef __wasilibc_unmodified_upstream
- (__WASI_RIGHT_FD_READ | __WASI_RIGHT_FILE_READDIR)) != 0) {
- if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) != 0)
-#else
(__WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR)) != 0) {
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0)
-#endif
oflags |= O_RDWR;
else
oflags |= O_RDONLY;
-#ifdef __wasilibc_unmodified_upstream
- } else if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) != 0) {
-#else
} else if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) {
-#endif
oflags |= O_WRONLY;
-#ifdef __wasilibc_unmodified_upstream
- } else if ((fds.fs_rights_base & __WASI_RIGHT_PROC_EXEC) != 0) {
- oflags |= O_EXEC;
-#endif
} else {
oflags |= O_SEARCH;
}
int flags = va_arg(ap, int);
va_end(ap);
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_fdstat_t fds = {.fs_flags = flags & 0xfff};
- __wasi_errno_t error =
- __wasi_fd_stat_put(fildes, &fds, __WASI_FDSTAT_FLAGS);
-#else
__wasi_fdflags_t fs_flags = flags & 0xfff;
__wasi_errno_t error =
__wasi_fd_fdstat_set_flags(fildes, fs_flags);
-#endif
if (error != 0) {
errno = error;
return -1;
#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
// 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
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;
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;
(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;
int posix_fadvise(int fd, off_t offset, off_t len, int advice) {
if (offset < 0 || len < 0)
return EINVAL;
-#ifdef __wasilibc_unmodified_upstream
- return __wasi_file_advise(fd, offset, len, advice);
-#else
return __wasi_fd_advise(fd, offset, len, advice);
-#endif
}
int posix_fallocate(int fd, off_t offset, off_t len) {
if (offset < 0 || len < 0)
return EINVAL;
-#ifdef __wasilibc_unmodified_upstream
- return __wasi_file_allocate(fd, offset, len);
-#else
return __wasi_fd_allocate(fd, offset, len);
-#endif
}
#include <sched.h>
int sched_yield(void) {
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_thread_yield();
-#else
__wasi_errno_t error = __wasi_sched_yield();
-#endif
if (error != 0) {
errno = error;
return -1;
#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
__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;
};
__wasi_event_t events[__arraycount(subscriptions)];
size_t nevents;
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_poll(
-#else
__wasi_errno_t error = __wasi_poll_oneoff(
-#endif
subscriptions, events, __arraycount(subscriptions), &nevents);
if (error != 0) {
errno = error;
case FIONBIO: {
// Obtain the current file descriptor flags.
__wasi_fdstat_t fds;
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_fd_stat_get(fildes, &fds);
-#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds);
-#endif
if (error != 0) {
errno = error;
return -1;
va_list ap;
va_start(ap, request);
if (*va_arg(ap, const int *) != 0)
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- fds.fs_flags |= __WASI_FDFLAG_NONBLOCK;
-#else
fds.fs_flags |= __WASI_FDFLAGS_NONBLOCK;
-#endif
else
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- fds.fs_flags &= ~__WASI_FDFLAG_NONBLOCK;
-#else
fds.fs_flags &= ~__WASI_FDFLAGS_NONBLOCK;
-#endif
va_end(ap);
// Update the file descriptor flags.
-#ifdef __wasilibc_unmodified_upstream // fstat
- error = __wasi_fd_stat_put(fildes, &fds, __WASI_FDSTAT_FLAGS);
-#else
error = __wasi_fd_fdstat_set_flags(fildes, fds.fs_flags);
-#endif
if (error != 0) {
errno = error;
return -1;
switch (who) {
case RUSAGE_SELF: {
__wasi_timestamp_t usertime = 0;
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- (void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 1000,
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 1000,
-#endif
&usertime);
*r_usage = (struct rusage){
.ru_utime = timestamp_to_timeval(usertime),
}
struct timespec ts = {.tv_sec = timeout->tv_sec,
.tv_nsec = (long)timeout->tv_usec * 1000};
-#ifdef __wasilibc_unmodified_upstream
- return pselect(nfds, readfds, writefds, errorfds, &ts);
-#else
return pselect(nfds, readfds, writefds, errorfds, &ts, NULL);
-#endif
} else {
// No timeout specified.
-#ifdef __wasilibc_unmodified_upstream
- return pselect(nfds, readfds, writefds, errorfds, NULL);
-#else
return pselect(nfds, readfds, writefds, errorfds, NULL, NULL);
-#endif
}
}
#include <string.h>
int getsockopt(int socket, int level, int option_name,
-#ifdef __wasilibc_unmodified_upstream
- void *restrict option_value, size_t *restrict option_len) {
-#else
void *restrict option_value, socklen_t *restrict option_len) {
-#endif
// Only support SOL_SOCKET options for now.
if (level != SOL_SOCKET) {
errno = ENOPROTOOPT;
// Return the type of the socket. This information can simply be
// obtained by looking at the file descriptor type.
__wasi_fdstat_t fsb;
-#ifdef __wasilibc_unmodified_upstream
- if (__wasi_fd_stat_get(socket, &fsb) != 0) {
-#else
if (__wasi_fd_fdstat_get(socket, &fsb) != 0) {
-#endif
errno = EBADF;
return -1;
}
#include <errno.h>
#include <stdint.h>
-#ifdef __wasilibc_unmodified_upstream
-static_assert(MSG_PEEK == __WASI_SOCK_RECV_PEEK, "Value mismatch");
-static_assert(MSG_WAITALL == __WASI_SOCK_RECV_WAITALL, "Value mismatch");
-#else
static_assert(MSG_PEEK == __WASI_RIFLAGS_RECV_PEEK, "Value mismatch");
static_assert(MSG_WAITALL == __WASI_RIFLAGS_RECV_WAITALL, "Value mismatch");
-#endif
ssize_t recv(int socket, void *restrict buffer, size_t length, int flags) {
// Validate flags.
// Prepare input parameters.
__wasi_iovec_t iov = {.buf = buffer, .buf_len = length};
-#ifdef __wasilibc_unmodified_upstream // send/recv
- __wasi_recv_in_t ri = {
- .ri_data = &iov,
- .ri_data_len = 1,
- .ri_flags = flags,
- };
-#else
__wasi_iovec_t *ri_data = &iov;
size_t ri_data_len = 1;
__wasi_riflags_t ri_flags = flags;
-#endif
// Perform system call.
-#ifdef __wasilibc_unmodified_upstream // send/recv
- __wasi_recv_out_t ro;
- __wasi_errno_t error = __wasi_sock_recv(socket, &ri, &ro);
-#else
size_t ro_datalen;
__wasi_roflags_t ro_flags;
__wasi_errno_t error = __wasi_sock_recv(socket,
ri_data, ri_data_len, ri_flags,
&ro_datalen,
&ro_flags);
-#endif
if (error != 0) {
errno = errno_fixup_socket(socket, error);
return -1;
}
-#ifdef __wasilibc_unmodified_upstream // send/recv
- return ro.ro_datalen;
-#else
return ro_datalen;
-#endif
}
// Prepare input parameters.
__wasi_ciovec_t iov = {.buf = buffer, .buf_len = length};
-#ifdef __wasilibc_unmodified_upstream // send/recv
- __wasi_send_in_t si = {
- .si_data = &iov,
- .si_data_len = 1,
- };
-#else
__wasi_ciovec_t *si_data = &iov;
size_t si_data_len = 1;
__wasi_siflags_t si_flags = 0;
-#endif
// Perform system call.
-#ifdef __wasilibc_unmodified_upstream // send/recv
- __wasi_send_out_t so;
- __wasi_errno_t error = __wasi_sock_send(socket, &si, &so);
-#else
size_t so_datalen;
__wasi_errno_t error = __wasi_sock_send(socket, si_data, si_data_len, si_flags, &so_datalen);
-#endif
if (error != 0) {
errno = errno_fixup_socket(socket, error);
return -1;
}
-#ifdef __wasilibc_unmodified_upstream // send/recv
- return so.so_datalen;
-#else
return so_datalen;
-#endif
}
#include <wasi/api.h>
#include <errno.h>
-#ifdef __wasilibc_unmodified_upstream // generated constant names
-static_assert(SHUT_RD == __WASI_SHUT_RD, "Value mismatch");
-static_assert(SHUT_WR == __WASI_SHUT_WR, "Value mismatch");
-#else
static_assert(SHUT_RD == __WASI_SDFLAGS_RD, "Value mismatch");
static_assert(SHUT_WR == __WASI_SDFLAGS_WR, "Value mismatch");
-#endif
int shutdown(int socket, int how) {
// Validate shutdown flags.
int fstat(int fildes, struct stat *buf) {
__wasi_filestat_t internal_stat;
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_errno_t error = __wasi_file_stat_fget(fildes, &internal_stat);
-#else
__wasi_errno_t error = __wasi_fd_filestat_get(fildes, &internal_stat);
-#endif
if (error != 0) {
errno = error;
return -1;
int 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;
int futimens(int fd, const struct timespec *times) {
// Convert timestamps and extract NOW/OMIT flags.
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_filestat_t fs;
- __wasi_fsflags_t flags;
- if (!utimens_get_timestamps(times, &fs, &flags)) {
-#else
__wasi_timestamp_t st_atim;
__wasi_timestamp_t st_mtim;
__wasi_fstflags_t flags;
if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) {
-#endif
errno = EINVAL;
return -1;
}
// Perform system call.
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_errno_t error = __wasi_file_stat_fput(fd, &fs, flags);
-#else
__wasi_errno_t error = __wasi_fd_filestat_set_times(fd, st_atim, st_mtim, flags);
-#endif
if (error != 0) {
errno = error;
return -1;
#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
__wasi_errno_t error = __wasi_path_create_directory(
fd, path, strlen(path));
-#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
static inline void to_public_stat(const __wasi_filestat_t *in,
struct stat *out) {
// Ensure that we don't truncate any values.
-#ifdef __wasilibc_unmodified_upstream
- static_assert(sizeof(in->st_dev) == sizeof(out->st_dev), "Size mismatch");
- static_assert(sizeof(in->st_ino) == sizeof(out->st_ino), "Size mismatch");
- static_assert(sizeof(in->st_filetype) == sizeof(out->__st_filetype),
- "Size mismatch");
-#else
static_assert(sizeof(in->dev) == sizeof(out->st_dev), "Size mismatch");
static_assert(sizeof(in->ino) == sizeof(out->st_ino), "Size mismatch");
/*
* The non-standard __st_filetype field appears to only be used for shared
* memory, which we don't currently support.
*/
-#endif
-#ifdef __wasilibc_unmodified_upstream
- static_assert(sizeof(in->st_nlink) == sizeof(out->st_nlink), "Size mismatch");
- static_assert(sizeof(in->st_size) == sizeof(out->st_size), "Size mismatch");
-#else
/* nlink_t is 64-bit on wasm32, following the x32 ABI. */
static_assert(sizeof(in->nlink) <= sizeof(out->st_nlink), "Size shortfall");
static_assert(sizeof(in->size) == sizeof(out->st_size), "Size mismatch");
-#endif
*out = (struct stat){
-#ifdef __wasilibc_unmodified_upstream
-#define COPY_FIELD(field) .field = in->field
- COPY_FIELD(st_dev),
- COPY_FIELD(st_ino),
- .__st_filetype = in->st_filetype,
- COPY_FIELD(st_nlink),
- COPY_FIELD(st_size),
-#undef COPY_FIELD
-#define COPY_TIMESPEC(field) .field = timestamp_to_timespec(in->field)
- COPY_TIMESPEC(st_atim),
- COPY_TIMESPEC(st_mtim),
- COPY_TIMESPEC(st_ctim),
-#undef COPY_TIMESPEC
-#else
.st_dev = in->dev,
.st_ino = in->ino,
.st_nlink = in->nlink,
.st_atim = timestamp_to_timespec(in->atim),
.st_mtim = timestamp_to_timespec(in->mtim),
.st_ctim = timestamp_to_timespec(in->ctim),
-#endif
};
// Convert file type to legacy types encoded in st_mode.
-#ifdef __wasilibc_unmodified_upstream
- switch (in->st_filetype) {
-#else
switch (in->filetype) {
-#endif
case __WASI_FILETYPE_BLOCK_DEVICE:
out->st_mode |= S_IFBLK;
break;
}
static inline bool utimens_get_timestamps(const struct timespec *times,
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_filestat_t *fs,
- __wasi_fsflags_t *flags) {
-#else
__wasi_timestamp_t *st_atim,
__wasi_timestamp_t *st_mtim,
__wasi_fstflags_t *flags) {
-#endif
if (times == NULL) {
// Update both timestamps.
-#ifdef __wasilibc_unmodified_upstream // fstat
- *flags = __WASI_FILESTAT_ATIM_NOW | __WASI_FILESTAT_MTIM_NOW;
-#else
*flags = __WASI_FSTFLAGS_ATIM_NOW | __WASI_FSTFLAGS_MTIM_NOW;
-#endif
} else {
// Set individual timestamps.
*flags = 0;
switch (times[0].tv_nsec) {
case UTIME_NOW:
-#ifdef __wasilibc_unmodified_upstream // fstat
- *flags |= __WASI_FILESTAT_ATIM_NOW;
-#else
*flags |= __WASI_FSTFLAGS_ATIM_NOW;
-#endif
break;
case UTIME_OMIT:
break;
default:
-#ifdef __wasilibc_unmodified_upstream // fstat
- *flags |= __WASI_FILESTAT_ATIM;
- if (!timespec_to_timestamp_exact(×[0], &fs->st_atim))
-#else
*flags |= __WASI_FSTFLAGS_ATIM;
if (!timespec_to_timestamp_exact(×[0], st_atim))
-#endif
return false;
break;
}
switch (times[1].tv_nsec) {
case UTIME_NOW:
-#ifdef __wasilibc_unmodified_upstream // fstat
- *flags |= __WASI_FILESTAT_MTIM_NOW;
-#else
*flags |= __WASI_FSTFLAGS_MTIM_NOW;
-#endif
break;
case UTIME_OMIT:
break;
default:
-#ifdef __wasilibc_unmodified_upstream // fstat
- *flags |= __WASI_FILESTAT_MTIM;
- if (!timespec_to_timestamp_exact(×[1], &fs->st_mtim))
-#else
*flags |= __WASI_FSTFLAGS_MTIM;
if (!timespec_to_timestamp_exact(×[1], st_mtim))
-#endif
return false;
break;
}
int utimensat(int fd, const char *path, const struct timespec times[2],
int flag) {
// Convert timestamps and extract NOW/OMIT flags.
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_filestat_t fs;
- __wasi_fsflags_t flags;
- if (!utimens_get_timestamps(times, &fs, &flags)) {
-#else
__wasi_timestamp_t st_atim;
__wasi_timestamp_t st_mtim;
__wasi_fstflags_t flags;
if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) {
-#endif
errno = EINVAL;
return -1;
}
// 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_errno_t error =
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t, fstat
- __wasi_file_stat_put(lookup, path, strlen(path), &fs, flags);
-#else
__wasi_path_filestat_set_times(fd, lookup_flags, path, strlen(path), st_atim, st_mtim, flags);
-#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
#include <wasi/api.h>
-#ifdef __wasilibc_unmodified_upstream
-int gettimeofday(struct timeval *restrict tp, ...) {
-#else
int gettimeofday(struct timeval *restrict tp, void *tz) {
-#endif
__wasi_timestamp_t ts = 0;
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- (void)__wasi_clock_time_get(__WASI_CLOCK_REALTIME, 1000, &ts);
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, 1000, &ts);
-#endif
*tp = timestamp_to_timeval(ts);
return 0;
}
clock_t times(struct tms *buffer) {
// Obtain user time.
__wasi_timestamp_t usertime = 0;
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- (void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 0, &usertime);
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 0, &usertime);
-#endif
*buffer = (struct tms){.tms_utime = usertime};
// Obtain real time.
__wasi_timestamp_t realtime = 0;
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- (void)__wasi_clock_time_get(__WASI_CLOCK_MONOTONIC, 0, &realtime);
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &realtime);
-#endif
return realtime;
}
#include <time.h>
const struct __clockid _CLOCK_MONOTONIC = {
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- .id = __WASI_CLOCK_MONOTONIC,
-#else
.id = __WASI_CLOCKID_MONOTONIC,
-#endif
};
#include <time.h>
const struct __clockid _CLOCK_PROCESS_CPUTIME_ID = {
-#ifdef __wasilibc_unmodified_upstream
- .id = __WASI_CLOCK_PROCESS_CPUTIME_ID,
-#else
.id = __WASI_CLOCKID_PROCESS_CPUTIME_ID,
-#endif
};
#include <time.h>
const struct __clockid _CLOCK_REALTIME = {
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- .id = __WASI_CLOCK_REALTIME,
-#else
.id = __WASI_CLOCKID_REALTIME,
-#endif
};
#include <time.h>
const struct __clockid _CLOCK_THREAD_CPUTIME_ID = {
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- .id = __WASI_CLOCK_THREAD_CPUTIME_ID,
-#else
.id = __WASI_CLOCKID_THREAD_CPUTIME_ID,
-#endif
};
clock_t clock(void) {
__wasi_timestamp_t ts = 0;
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- (void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 0, &ts);
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 0, &ts);
-#endif
return ts;
}
#include <errno.h>
#include <time.h>
-#ifdef __wasilibc_unmodified_upstream
-int clock_gettime(clockid_t clock_id, struct timespec *tp) {
-#else
int __clock_gettime(clockid_t clock_id, struct timespec *tp) {
-#endif
__wasi_timestamp_t ts;
__wasi_errno_t error = __wasi_clock_time_get(clock_id->id, 1, &ts);
if (error != 0) {
*tp = timestamp_to_timespec(ts);
return 0;
}
-#ifdef __wasilibc_unmodified_upstream
-#else
extern __typeof(__clock_gettime) clock_gettime __attribute__((weak, alias("__clock_gettime")));
-#endif
#include <errno.h>
#include <time.h>
-#ifdef __wasilibc_unmodified_upstream // generated constant names
-static_assert(TIMER_ABSTIME == __WASI_SUBSCRIPTION_CLOCK_ABSTIME,
-#else
static_assert(TIMER_ABSTIME == __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME,
-#endif
"Value mismatch");
-#ifdef __wasilibc_unmodified_upstream
-int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
- ...) {
-#else
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
struct timespec *rmtp) {
-#endif
if ((flags & ~TIMER_ABSTIME) != 0)
return EINVAL;
// Block until polling event is triggered.
size_t nevents;
__wasi_event_t ev;
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_poll(&sub, &ev, 1, &nevents);
-#else
__wasi_errno_t error = __wasi_poll_oneoff(&sub, &ev, 1, &nevents);
-#endif
return error == 0 && ev.error == 0 ? 0 : ENOTSUP;
}
#include <threads.h>
#include <time.h>
-#ifdef __wasilibc_unmodified_upstream
-int nanosleep(const struct timespec *rqtp, ...) {
-#else
int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
-#endif
-#ifdef __wasilibc_unmodified_upstream
- int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp);
-#else
int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rem);
-#endif
if (error != 0) {
errno = error;
return -1;
return 0;
}
-#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
+#if defined(_REENTRANT)
__strong_reference(nanosleep, thrd_sleep);
-#else
#endif
time_t time(time_t *tloc) {
__wasi_timestamp_t ts = 0;
-#ifdef __wasilibc_unmodified_upstream
- (void)__wasi_clock_time_get(__WASI_CLOCK_REALTIME, NSEC_PER_SEC, &ts);
-#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, NSEC_PER_SEC, &ts);
-#endif
if (tloc != NULL)
*tloc = ts / NSEC_PER_SEC;
return ts / NSEC_PER_SEC;
}
// Check for target file existence and obtain the file type.
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
- __wasi_lookup_t lookup = {
- .fd = fd,
- .flags = __WASI_LOOKUP_SYMLINK_FOLLOW,
- };
-#else
__wasi_lookupflags_t lookup_flags = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
-#endif
__wasi_filestat_t file;
__wasi_errno_t error =
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
- __wasi_file_stat_get(lookup, path, strlen(path), &file);
-#else
__wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &file);
-#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
// directory file descriptor.
if (amode != 0) {
__wasi_fdstat_t directory;
-#ifdef __wasilibc_unmodified_upstream
- error = __wasi_fd_stat_get(fd, &directory);
-#else
error = __wasi_fd_fdstat_get(fd, &directory);
-#endif
if (error != 0) {
errno = error;
return -1;
__wasi_rights_t min = 0;
if ((amode & R_OK) != 0)
-#ifdef __wasilibc_unmodified_upstream
- min |= file.st_filetype == __WASI_FILETYPE_DIRECTORY
- ? __WASI_RIGHT_FILE_READDIR
- : __WASI_RIGHT_FD_READ;
-#else
min |= file.filetype == __WASI_FILETYPE_DIRECTORY
? __WASI_RIGHTS_FD_READDIR
: __WASI_RIGHTS_FD_READ;
-#endif
if ((amode & W_OK) != 0)
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- min |= __WASI_RIGHT_FD_WRITE;
-#else
min |= __WASI_RIGHTS_FD_WRITE;
-#endif
-#ifdef __wasilibc_unmodified_upstream // RIGHT_PROC_EXEC
- if ((amode & X_OK) != 0 && file.st_filetype != __WASI_FILETYPE_DIRECTORY)
- min |= __WASI_RIGHT_PROC_EXEC;
-#endif
if ((min & directory.fs_rights_inheriting) != min) {
errno = EACCES;
errno = EINVAL;
return -1;
}
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_filestat_t fs = {
- .st_size = length,
- };
-#else
__wasi_filesize_t st_size = length;
-#endif
__wasi_errno_t error =
-#ifdef __wasilibc_unmodified_upstream // fstat
- __wasi_file_stat_fput(fildes, &fs, __WASI_FILESTAT_SIZE);
-#else
__wasi_fd_filestat_set_size(fildes, st_size);
-#endif
if (error != 0) {
errno = error;
return -1;
int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) {
// Create lookup properties.
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
- __wasi_lookup_t lookup1 = {.fd = fd1, .flags = 0};
-#else
__wasi_lookupflags_t lookup1_flags = 0;
-#endif
if ((flag & AT_SYMLINK_FOLLOW) != 0)
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
- lookup1.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
-#else
lookup1_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
-#endif
// Perform system call.
-#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
- __wasi_errno_t error = __wasi_file_link(lookup1, path1, strlen(path1),
-#else
__wasi_errno_t error = __wasi_path_link(fd1, lookup1_flags, path1, strlen(path1),
-#endif
- fd2, path2, strlen(path2));
+ fd2, path2, strlen(path2));
if (error != 0) {
errno = errno_fixup_directory(fd1, errno_fixup_directory(fd2, error));
return -1;
static_assert(SEEK_END == __WASI_WHENCE_END, "Value mismatch");
static_assert(SEEK_SET == __WASI_WHENCE_SET, "Value mismatch");
-#ifdef __wasilibc_unmodified_upstream // Provide an __lseek entry point
-off_t lseek(int fildes, off_t offset, int whence) {
-#else
off_t __lseek(int fildes, off_t offset, int whence) {
-#endif
__wasi_filesize_t new_offset;
__wasi_errno_t error =
__wasi_fd_seek(fildes, offset, whence, &new_offset);
return new_offset;
}
-#ifdef __wasilibc_unmodified_upstream // Provide an __lseek entry point
-#else
extern __typeof(__lseek) lseek __attribute__((weak, alias("__lseek")));
-#endif
__wasi_fd_pread(fildes, &iov, 1, offset, &bytes_read);
if (error != 0) {
__wasi_fdstat_t fds;
-#ifdef __wasilibc_unmodified_upstream
- if (error == ENOTCAPABLE && __wasi_fd_stat_get(fildes, &fds) == 0) {
-#else
if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) {
-#endif
// Determine why we got ENOTCAPABLE.
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- if ((fds.fs_rights_base & __WASI_RIGHT_FD_READ) == 0)
-#else
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_READ) == 0)
-#endif
error = EBADF;
else
error = ESPIPE;
__wasi_fd_pwrite(fildes, &iov, 1, offset, &bytes_written);
if (error != 0) {
__wasi_fdstat_t fds;
-#ifdef __wasilibc_unmodified_upstream
- if (error == ENOTCAPABLE && __wasi_fd_stat_get(fildes, &fds) == 0) {
-#else
if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) {
-#endif
// Determine why we got ENOTCAPABLE.
-#ifdef __wasilibc_unmodified_upstream // generated constant names
- if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) == 0)
-#else
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) == 0)
-#endif
error = EBADF;
else
error = ESPIPE;
ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf,
size_t bufsize) {
size_t bufused;
-#ifdef __wasilibc_unmodified_upstream
- __wasi_errno_t error = __wasi_file_readlink(fd, path, strlen(path),
- buf, bufsize, &bufused);
-#else
// TODO: Remove the cast on `buf` once the witx is updated with char8 support.
__wasi_errno_t error = __wasi_path_readlink(fd, path, strlen(path),
(uint8_t*)buf, bufsize, &bufused);
-#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
unsigned int sleep(unsigned int seconds) {
struct timespec ts = {.tv_sec = seconds, .tv_nsec = 0};
-#ifdef __wasilibc_unmodified_upstream
- if (clock_nanosleep(CLOCK_REALTIME, 0, &ts) != 0)
-#else
if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL) != 0)
-#endif
return seconds;
return 0;
}
int symlinkat(const char *path1, int fd, const char *path2) {
__wasi_errno_t error =
-#ifdef __wasilibc_unmodified_upstream
- __wasi_file_symlink(path1, strlen(path1), fd, path2, strlen(path2));
-#else
__wasi_path_symlink(path1, strlen(path1), fd, path2, strlen(path2));
-#endif
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
#include <common/errno.h>
#include <wasi/api.h>
-#ifdef __wasilibc_unmodified_upstream // unlink
-#else
#include <wasi/libc.h>
-#endif
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int unlinkat(int fd, const char *path, int flag) {
-#ifdef __wasilibc_unmodified_upstream // unlink
- __wasi_ulflags_t ulflags = 0;
- if ((flag & AT_REMOVEDIR) != 0)
- ulflags |= __WASI_UNLINK_REMOVEDIR;
- __wasi_errno_t error =
- __wasi_file_unlink(fd, path, strlen(path), ulflags);
- if (error != 0) {
- errno = errno_fixup_directory(fd, error);
- return -1;
- }
- return 0;
-#else
if ((flag & AT_REMOVEDIR) != 0) {
return __wasilibc_rmdirat(fd, path);
}
return __wasilibc_unlinkat(fd, path);
-#endif
}
int usleep(useconds_t useconds) {
struct timespec ts = {.tv_sec = useconds / 1000000,
.tv_nsec = useconds % 1000000 * 1000};
-#ifdef __wasilibc_unmodified_upstream
- int error = clock_nanosleep(CLOCK_REALTIME, 0, &ts);
-#else
int error = clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
-#endif
if (error != 0) {
errno = error;
return -1;