Provide the C WASI implementation as an option.

This adds the C WASI implementation as a new crate, wasmtime-wasi-c,
and adds a command-line flag to the wasmtime command-line driver to
select which WASI implementation to use.
This commit is contained in:
Dan Gohman
2019-05-19 20:17:38 -07:00
parent d57fbc7d0c
commit 06b6ec42b9
39 changed files with 9597 additions and 16 deletions

View File

@@ -0,0 +1,24 @@
All code is distributed under the following license:
Copyright (c) 2015 Nuxi, https://nuxi.nl/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@@ -0,0 +1,14 @@
This directory consists of selected files copied from the [libemulator]
directory in the [cloudabi-utils] repository, with minor modifications,
along with the accompanying LICENSE file from that repository.
The modifications are marked with `WASMTIME_*` preprocessor macros.
The files were copied at git revision
be1ce21e1dded9c0c0a6ebe144cbea01cf44a874
which is dated
Sun Jan 13 23:26:03 2019 +0100
.
[libemulator]: https://github.com/NuxiNL/cloudabi-utils/tree/master/src/libemulator
[cloudabi-utils]: https://github.com/NuxiNL/cloudabi-utils

View File

@@ -0,0 +1,100 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef CONFIG_H
#define CONFIG_H
#include <stdlib.h>
#if defined(__FreeBSD__) || defined(__APPLE__)
#define CONFIG_HAS_ARC4RANDOM_BUF 1
#else
#define CONFIG_HAS_ARC4RANDOM_BUF 0
#endif
// On Linux, prefer to use getrandom, though it isn't available in
// GLIBC before 2.25.
#if defined(__linux__) && \
(!defined(__GLIBC__) || \
__GLIBC__ > 2 || \
(__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#define CONFIG_HAS_GETRANDOM 1
#else
#define CONFIG_HAS_GETRANDOM 0
#endif
#if defined(__CloudABI__)
#define CONFIG_HAS_CAP_ENTER 1
#else
#define CONFIG_HAS_CAP_ENTER 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__)
#define CONFIG_HAS_CLOCK_NANOSLEEP 1
#else
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__)
#define CONFIG_HAS_FDATASYNC 1
#else
#define CONFIG_HAS_FDATASYNC 0
#endif
#ifndef __CloudABI__
#define CONFIG_HAS_ISATTY 1
#else
#define CONFIG_HAS_ISATTY 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_POSIX_FALLOCATE 1
#else
#define CONFIG_HAS_POSIX_FALLOCATE 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PREADV 1
#else
#define CONFIG_HAS_PREADV 0
#endif
#if defined(__APPLE__) || defined(__CloudABI__)
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
#else
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
#else
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PWRITEV 1
#else
#define CONFIG_HAS_PWRITEV 0
#endif
#ifdef __APPLE__
#define st_atimespec st_atim
#define st_mtimespec st_mtim
#define st_ctimespec st_ctim
#endif
#ifdef __APPLE__
#define CONFIG_TLS_USE_GSBASE 1
#else
#define CONFIG_TLS_USE_GSBASE 0
#endif
#endif

View File

@@ -0,0 +1,215 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef LOCKING_H
#define LOCKING_H
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <time.h>
#ifndef __has_extension
#define __has_extension(x) 0
#endif
#if __has_extension(c_thread_safety_attributes)
#define LOCK_ANNOTATE(x) __attribute__((x))
#else
#define LOCK_ANNOTATE(x)
#endif
// Lock annotation macros.
#define LOCKABLE LOCK_ANNOTATE(lockable)
#define LOCKS_EXCLUSIVE(...) LOCK_ANNOTATE(exclusive_lock_function(__VA_ARGS__))
#define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__))
#define TRYLOCKS_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_trylock_function(__VA_ARGS__))
#define TRYLOCKS_SHARED(...) LOCK_ANNOTATE(shared_trylock_function(__VA_ARGS__))
#define UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__))
#define REQUIRES_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_locks_required(__VA_ARGS__))
#define REQUIRES_SHARED(...) LOCK_ANNOTATE(shared_locks_required(__VA_ARGS__))
#define REQUIRES_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__))
#define NO_LOCK_ANALYSIS LOCK_ANNOTATE(no_thread_safety_analysis)
// Mutex that uses the lock annotations.
struct LOCKABLE mutex {
pthread_mutex_t object;
};
#define MUTEX_INITIALIZER \
{ PTHREAD_MUTEX_INITIALIZER }
static inline void mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
pthread_mutex_init(&lock->object, NULL);
}
static inline void mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
pthread_mutex_destroy(&lock->object);
}
static inline void mutex_lock(struct mutex *lock)
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_mutex_lock(&lock->object);
}
static inline void mutex_unlock(struct mutex *lock)
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
pthread_mutex_unlock(&lock->object);
}
// Read-write lock that uses the lock annotations.
struct LOCKABLE rwlock {
pthread_rwlock_t object;
};
static inline void rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock) {
pthread_rwlock_init(&lock->object, NULL);
}
static inline void rwlock_rdlock(struct rwlock *lock)
LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_rdlock(&lock->object);
}
static inline void rwlock_wrlock(struct rwlock *lock)
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_wrlock(&lock->object);
}
static inline void rwlock_unlock(struct rwlock *lock)
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_unlock(&lock->object);
}
// Condition variable that uses the lock annotations.
struct LOCKABLE cond {
pthread_cond_t object;
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
clockid_t clock;
#endif
};
static inline void cond_init_monotonic(struct cond *cond) {
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond->object, &attr);
pthread_condattr_destroy(&attr);
#else
pthread_cond_init(&cond->object, NULL);
#endif
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_MONOTONIC;
#endif
}
static inline void cond_init_realtime(struct cond *cond) {
pthread_cond_init(&cond->object, NULL);
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_REALTIME;
#endif
}
static inline void cond_destroy(struct cond *cond) {
pthread_cond_destroy(&cond->object);
}
static inline void cond_signal(struct cond *cond) {
pthread_cond_signal(&cond->object);
}
static inline bool cond_timedwait(struct cond *cond, struct mutex *lock,
uint64_t timeout, bool abstime)
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
struct timespec ts = {
.tv_sec = (time_t)(timeout / 1000000000),
.tv_nsec = (long)(timeout % 1000000000),
};
if (abstime) {
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
// No native support for sleeping on monotonic clocks. Convert the
// timeout to a relative value and then to an absolute value for the
// realtime clock.
if (cond->clock != CLOCK_REALTIME) {
struct timespec ts_monotonic;
clock_gettime(cond->clock, &ts_monotonic);
ts.tv_sec -= ts_monotonic.tv_sec;
ts.tv_nsec -= ts_monotonic.tv_nsec;
if (ts.tv_nsec < 0) {
ts.tv_nsec += 1000000000;
--ts.tv_sec;
}
struct timespec ts_realtime;
clock_gettime(CLOCK_REALTIME, &ts_realtime);
ts.tv_sec += ts_realtime.tv_sec;
ts.tv_nsec += ts_realtime.tv_nsec;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
}
#endif
} else {
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
// Implementation supports relative timeouts.
int ret =
pthread_cond_timedwait_relative_np(&cond->object, &lock->object, &ts);
assert((ret == 0 || ret == ETIMEDOUT) &&
"pthread_cond_timedwait_relative_np() failed");
return ret == ETIMEDOUT;
#else
// Convert to absolute timeout.
struct timespec ts_now;
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
clock_gettime(cond->clock, &ts_now);
#else
clock_gettime(CLOCK_REALTIME, &ts_now);
#endif
ts.tv_sec += ts_now.tv_sec;
ts.tv_nsec += ts_now.tv_nsec;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
#endif
}
int ret = pthread_cond_timedwait(&cond->object, &lock->object, &ts);
assert((ret == 0 || ret == ETIMEDOUT) && "pthread_cond_timedwait() failed");
return ret == ETIMEDOUT;
}
static inline void cond_wait(struct cond *cond, struct mutex *lock)
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_cond_wait(&cond->object, &lock->object);
}
#endif

View File

@@ -0,0 +1,42 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2015 Nuxi, https://nuxi.nl/
#ifndef COMMON_LIMITS_H
#define COMMON_LIMITS_H
#include <limits.h>
#define NUMERIC_MIN(t) \
_Generic((t)0, char \
: CHAR_MIN, signed char \
: SCHAR_MIN, unsigned char : 0, short \
: SHRT_MIN, unsigned short : 0, int \
: INT_MIN, unsigned int : 0, long \
: LONG_MIN, unsigned long : 0, long long \
: LLONG_MIN, unsigned long long : 0, default \
: (void)0)
#define NUMERIC_MAX(t) \
_Generic((t)0, char \
: CHAR_MAX, signed char \
: SCHAR_MAX, unsigned char \
: UCHAR_MAX, short \
: SHRT_MAX, unsigned short \
: USHRT_MAX, int \
: INT_MAX, unsigned int \
: UINT_MAX, long \
: LONG_MAX, unsigned long \
: ULONG_MAX, long long \
: LLONG_MAX, unsigned long long \
: ULLONG_MAX, default \
: (void)0)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016-2018 Nuxi, https://nuxi.nl/
#ifndef POSIX_H
#define POSIX_H
#include <stdbool.h>
#include <stddef.h>
#include "locking.h"
struct fd_entry;
struct fd_prestat;
struct syscalls;
struct fd_table {
struct rwlock lock;
struct fd_entry *entries;
size_t size;
size_t used;
};
struct fd_prestats {
struct rwlock lock;
struct fd_prestat *prestats;
size_t size;
size_t used;
};
struct argv_environ_values {
size_t argc;
size_t argv_buf_size;
char **argv;
char *argv_buf;
size_t environ_count;
size_t environ_buf_size;
char **environ;
char *environ_buf;
};
void fd_table_init(struct fd_table *);
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
void fd_prestats_init(struct fd_prestats *);
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
void argv_environ_init(struct argv_environ_values *,
const size_t *argv_offsets, size_t argv_offsets_len,
const char *argv_buf, size_t argv_buf_len,
const size_t *environ_offsets, size_t environ_offsets_len,
const char *environ_buf, size_t environ_buf_len);
#endif

View File

@@ -0,0 +1,92 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef QUEUE_H
#define QUEUE_H
#include <stddef.h>
// LIST: Double-linked list.
#define LIST_HEAD(name, type) \
struct name { \
struct type *l_first; \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *l_next; \
struct type **l_prev; \
}
#define LIST_FOREACH(var, head, field) \
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
#define LIST_INIT(head) \
do { \
(head)->l_first = NULL; \
} while (0)
#define LIST_INSERT_HEAD(head, element, field) \
do { \
(element)->field.l_next = (head)->l_first; \
if ((head)->l_first != NULL) \
(head)->l_first->field.l_prev = &(element)->field.l_next; \
(head)->l_first = (element); \
(element)->field.l_prev = &(head)->l_first; \
} while (0)
#define LIST_REMOVE(element, field) \
do { \
if ((element)->field.l_next != NULL) \
(element)->field.l_next->field.l_prev = (element)->field.l_prev; \
*(element)->field.l_prev = (element)->field.l_next; \
} while (0)
// TAILQ: Double-linked list with tail pointer.
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *t_first; \
struct type **t_last; \
}
#define TAILQ_ENTRY(type) \
struct { \
struct type *t_next; \
struct type **t_prev; \
}
#define TAILQ_EMPTY(head) ((head)->t_first == NULL)
#define TAILQ_FIRST(head) ((head)->t_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
#define TAILQ_INIT(head) \
do { \
(head)->t_first = NULL; \
(head)->t_last = &(head)->t_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) \
do { \
(elm)->field.t_next = NULL; \
(elm)->field.t_prev = (head)->t_last; \
*(head)->t_last = (elm); \
(head)->t_last = &(elm)->field.t_next; \
} while (0)
#define TAILQ_REMOVE(head, element, field) \
do { \
if ((element)->field.t_next != NULL) \
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \
else \
(head)->t_last = (element)->field.t_prev; \
*(element)->field.t_prev = (element)->field.t_next; \
} while (0)
#endif

View File

@@ -0,0 +1,92 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#include "config.h"
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "random.h"
#if CONFIG_HAS_ARC4RANDOM_BUF
void random_buf(void *buf, size_t len) {
arc4random_buf(buf, len);
}
#elif CONFIG_HAS_GETRANDOM
#include <sys/random.h>
void random_buf(void *buf, size_t len) {
for (;;) {
ssize_t x = getrandom(buf, len, 0);
if (x < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "getrandom failed: %s", strerror(errno));
abort();
}
if (x == len)
return;
buf = (void *)((unsigned char *)buf + x);
len -= x;
}
}
#else
static int urandom;
static void open_urandom(void) {
urandom = open("/dev/urandom", O_RDONLY);
if (urandom < 0) {
fputs("Failed to open /dev/urandom\n", stderr);
abort();
}
}
void random_buf(void *buf, size_t len) {
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
pthread_once(&open_once, open_urandom);
if (read(urandom, buf, len) != len) {
fputs("Short read on /dev/urandom\n", stderr);
abort();
}
}
#endif
// Calculates a random number within the range [0, upper - 1] without
// any modulo bias.
//
// The function below repeatedly obtains a random number from
// arc4random() until it lies within the range [2^k % upper, 2^k). As
// this range has length k * upper, we can safely obtain a number
// without any modulo bias.
uintmax_t random_uniform(uintmax_t upper) {
// Compute 2^k % upper
// == (2^k - upper) % upper
// == -upper % upper.
uintmax_t lower = -upper % upper;
for (;;) {
uintmax_t value;
random_buf(&value, sizeof(value));
if (value >= lower)
return value % upper;
}
}

View File

@@ -0,0 +1,20 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef RANDOM_H
#define RANDOM_H
#include <stdint.h>
void random_buf(void *, size_t);
uintmax_t random_uniform(uintmax_t);
#endif

View File

@@ -0,0 +1,47 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef REFCOUNT_H
#define REFCOUNT_H
#include <assert.h>
#include <stdatomic.h>
#include <stdbool.h>
#include "locking.h"
// Simple reference counter.
struct LOCKABLE refcount {
atomic_uint count;
};
#define PRODUCES(...) LOCKS_SHARED(__VA_ARGS__) NO_LOCK_ANALYSIS
#define CONSUMES(...) UNLOCKS(__VA_ARGS__) NO_LOCK_ANALYSIS
// Initialize the reference counter.
static void refcount_init(struct refcount *r, unsigned int count) PRODUCES(*r) {
atomic_init(&r->count, count);
}
// Increment the reference counter.
static inline void refcount_acquire(struct refcount *r) PRODUCES(*r) {
atomic_fetch_add_explicit(&r->count, 1, memory_order_acquire);
}
// Decrement the reference counter, returning whether the reference
// dropped to zero.
static inline bool refcount_release(struct refcount *r) CONSUMES(*r) {
int old = atomic_fetch_sub_explicit(&r->count, 1, memory_order_release);
assert(old != 0 && "Reference count becoming negative");
return old == 1;
}
#endif

View File

@@ -0,0 +1,83 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef RIGHTS_H
#define RIGHTS_H
#define RIGHTS_ALL \
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
__WASI_RIGHT_PATH_CREATE_DIRECTORY | __WASI_RIGHT_PATH_CREATE_FILE | \
__WASI_RIGHT_PATH_LINK_SOURCE | __WASI_RIGHT_PATH_LINK_TARGET | \
__WASI_RIGHT_PATH_OPEN | __WASI_RIGHT_FD_READDIR | \
__WASI_RIGHT_PATH_READLINK | __WASI_RIGHT_PATH_RENAME_SOURCE | \
__WASI_RIGHT_PATH_RENAME_TARGET | __WASI_RIGHT_PATH_FILESTAT_GET | \
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
// Block and character device interaction is outside the scope of
// CloudABI. Simply allow everything.
#define RIGHTS_BLOCK_DEVICE_BASE RIGHTS_ALL
#define RIGHTS_BLOCK_DEVICE_INHERITING RIGHTS_ALL
#define RIGHTS_CHARACTER_DEVICE_BASE RIGHTS_ALL
#define RIGHTS_CHARACTER_DEVICE_INHERITING RIGHTS_ALL
// Only allow directory operations on directories. Directories can only
// yield file descriptors to other directories and files.
#define RIGHTS_DIRECTORY_BASE \
(__WASI_RIGHT_FD_FDSTAT_SET_FLAGS | __WASI_RIGHT_FD_SYNC | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_PATH_CREATE_DIRECTORY | \
__WASI_RIGHT_PATH_CREATE_FILE | __WASI_RIGHT_PATH_LINK_SOURCE | \
__WASI_RIGHT_PATH_LINK_TARGET | __WASI_RIGHT_PATH_OPEN | \
__WASI_RIGHT_FD_READDIR | __WASI_RIGHT_PATH_READLINK | \
__WASI_RIGHT_PATH_RENAME_SOURCE | __WASI_RIGHT_PATH_RENAME_TARGET | \
__WASI_RIGHT_PATH_FILESTAT_GET | \
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
__WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_DIRECTORY_INHERITING \
(RIGHTS_DIRECTORY_BASE | RIGHTS_REGULAR_FILE_BASE)
// Operations that apply to regular files.
#define RIGHTS_REGULAR_FILE_BASE \
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
__WASI_RIGHT_FD_FILESTAT_SET_TIMES | __WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_REGULAR_FILE_INHERITING 0
// Operations that apply to sockets and socket pairs.
#define RIGHTS_SOCKET_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
#define RIGHTS_SOCKET_INHERITING RIGHTS_ALL
// Operations that apply to TTYs.
#define RIGHTS_TTY_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_TTY_INHERITING 0
#endif

View File

@@ -0,0 +1,17 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef SIGNALS_H
#define SIGNALS_H
void signals_init(void);
#endif

View File

@@ -0,0 +1,33 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "str.h"
char *str_nullterminate(const char *s, size_t len) {
// Copy string.
char *ret = strndup(s, len);
if (ret == NULL)
return NULL;
// Ensure that it contains no null bytes within.
if (strlen(ret) != len) {
free(ret);
errno = EILSEQ;
return NULL;
}
return ret;
}

View File

@@ -0,0 +1,19 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef STR_H
#define STR_H
#include "config.h"
char *str_nullterminate(const char *, size_t);
#endif