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:
24
wasmtime-wasi-c/sandboxed-system-primitives/src/LICENSE
Normal file
24
wasmtime-wasi-c/sandboxed-system-primitives/src/LICENSE
Normal 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.
|
||||
14
wasmtime-wasi-c/sandboxed-system-primitives/src/README.md
Normal file
14
wasmtime-wasi-c/sandboxed-system-primitives/src/README.md
Normal 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
|
||||
100
wasmtime-wasi-c/sandboxed-system-primitives/src/config.h
Normal file
100
wasmtime-wasi-c/sandboxed-system-primitives/src/config.h
Normal 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
|
||||
215
wasmtime-wasi-c/sandboxed-system-primitives/src/locking.h
Normal file
215
wasmtime-wasi-c/sandboxed-system-primitives/src/locking.h
Normal 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
|
||||
@@ -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
|
||||
2781
wasmtime-wasi-c/sandboxed-system-primitives/src/posix.c
Normal file
2781
wasmtime-wasi-c/sandboxed-system-primitives/src/posix.c
Normal file
File diff suppressed because it is too large
Load Diff
59
wasmtime-wasi-c/sandboxed-system-primitives/src/posix.h
Normal file
59
wasmtime-wasi-c/sandboxed-system-primitives/src/posix.h
Normal 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
|
||||
92
wasmtime-wasi-c/sandboxed-system-primitives/src/queue.h
Normal file
92
wasmtime-wasi-c/sandboxed-system-primitives/src/queue.h
Normal 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
|
||||
92
wasmtime-wasi-c/sandboxed-system-primitives/src/random.c
Normal file
92
wasmtime-wasi-c/sandboxed-system-primitives/src/random.c
Normal 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;
|
||||
}
|
||||
}
|
||||
20
wasmtime-wasi-c/sandboxed-system-primitives/src/random.h
Normal file
20
wasmtime-wasi-c/sandboxed-system-primitives/src/random.h
Normal 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
|
||||
47
wasmtime-wasi-c/sandboxed-system-primitives/src/refcount.h
Normal file
47
wasmtime-wasi-c/sandboxed-system-primitives/src/refcount.h
Normal 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
|
||||
83
wasmtime-wasi-c/sandboxed-system-primitives/src/rights.h
Normal file
83
wasmtime-wasi-c/sandboxed-system-primitives/src/rights.h
Normal 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
|
||||
17
wasmtime-wasi-c/sandboxed-system-primitives/src/signals.h
Normal file
17
wasmtime-wasi-c/sandboxed-system-primitives/src/signals.h
Normal 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
|
||||
33
wasmtime-wasi-c/sandboxed-system-primitives/src/str.c
Normal file
33
wasmtime-wasi-c/sandboxed-system-primitives/src/str.c
Normal 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;
|
||||
}
|
||||
19
wasmtime-wasi-c/sandboxed-system-primitives/src/str.h
Normal file
19
wasmtime-wasi-c/sandboxed-system-primitives/src/str.h
Normal 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
|
||||
Reference in New Issue
Block a user