Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

14
deps/uvwasi/BUILD.gn vendored Normal file
View File

@ -0,0 +1,14 @@
##############################################################################
# #
# DO NOT EDIT THIS FILE! #
# #
##############################################################################
# This file is used by GN for building, which is NOT the build system used for
# building official binaries.
# Please modify the gyp files if you are making changes to build system.
import("unofficial.gni")
uvwasi_gn_build("uvwasi") {
}

21
deps/uvwasi/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Colin Ihrig and Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

288
deps/uvwasi/include/uvwasi.h vendored Normal file
View File

@ -0,0 +1,288 @@
#ifndef __UVWASI_H__
#define __UVWASI_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "uv.h"
#include "wasi_serdes.h"
#include "wasi_types.h"
#define UVWASI_VERSION_MAJOR 0
#define UVWASI_VERSION_MINOR 0
#define UVWASI_VERSION_PATCH 21
#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
(UVWASI_VERSION_MINOR << 8) | \
(UVWASI_VERSION_PATCH))
#define UVWASI_STRINGIFY(v) UVWASI_STRINGIFY_HELPER(v)
#define UVWASI_STRINGIFY_HELPER(v) #v
#define UVWASI_VERSION_STRING UVWASI_STRINGIFY(UVWASI_VERSION_MAJOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_MINOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_PATCH)
#define UVWASI_VERSION_WASI "snapshot_1"
typedef void* (*uvwasi_malloc)(size_t size, void* mem_user_data);
typedef void (*uvwasi_free)(void* ptr, void* mem_user_data);
typedef void* (*uvwasi_calloc)(size_t nmemb, size_t size, void* mem_user_data);
typedef void* (*uvwasi_realloc)(void* ptr, size_t size, void* mem_user_data);
typedef struct uvwasi_mem_s {
void* mem_user_data;
uvwasi_malloc malloc;
uvwasi_free free;
uvwasi_calloc calloc;
uvwasi_realloc realloc;
} uvwasi_mem_t;
struct uvwasi_fd_table_t;
typedef struct uvwasi_s {
struct uvwasi_fd_table_t* fds;
uvwasi_size_t argc;
char** argv;
char* argv_buf;
uvwasi_size_t argv_buf_size;
uvwasi_size_t envc;
char** env;
char* env_buf;
uvwasi_size_t env_buf_size;
const uvwasi_mem_t* allocator;
uv_loop_t* loop;
} uvwasi_t;
typedef struct uvwasi_preopen_s {
const char* mapped_path;
const char* real_path;
} uvwasi_preopen_t;
typedef struct uvwasi_preopen_socket_s {
const char* address;
int port;
} uvwasi_preopen_socket_t;
typedef struct uvwasi_options_s {
uvwasi_size_t fd_table_size;
uvwasi_size_t preopenc;
uvwasi_preopen_t* preopens;
uvwasi_size_t preopen_socketc;
uvwasi_preopen_socket_t* preopen_sockets;
uvwasi_size_t argc;
const char** argv;
const char** envp;
uvwasi_fd_t in;
uvwasi_fd_t out;
uvwasi_fd_t err;
const uvwasi_mem_t* allocator;
} uvwasi_options_t;
/* Embedder API. */
uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options);
void uvwasi_destroy(uvwasi_t* uvwasi);
void uvwasi_options_init(uvwasi_options_t* options);
/* Use int instead of uv_file to avoid needing uv.h */
uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
const uvwasi_fd_t fd,
int new_host_fd);
const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code);
/* WASI system call API. */
uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf);
uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
uvwasi_size_t* argc,
uvwasi_size_t* argv_buf_size);
uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t* resolution);
uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t precision,
uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
char** environment,
char* environ_buf);
uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
uvwasi_size_t* environ_count,
uvwasi_size_t* environ_buf_size);
uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t offset,
uvwasi_filesize_t len,
uvwasi_advice_t advice);
uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t offset,
uvwasi_filesize_t len);
uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_fdstat_t* buf);
uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_fdflags_t flags);
uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting
);
uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filestat_t* buf);
uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t st_size);
uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
uvwasi_size_t* nread);
uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_prestat_t* buf);
uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
char* path,
uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
uvwasi_size_t* nwritten);
uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len,
uvwasi_size_t* nread);
uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
void* buf,
uvwasi_size_t buf_len,
uvwasi_dircookie_t cookie,
uvwasi_size_t* bufused);
uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
uvwasi_fd_t from,
uvwasi_fd_t to);
uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filedelta_t offset,
uvwasi_whence_t whence,
uvwasi_filesize_t* newoffset);
uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t* offset);
uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len,
uvwasi_size_t* nwritten);
uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
uvwasi_size_t path_len,
uvwasi_filestat_t* buf);
uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
uvwasi_size_t path_len,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
uvwasi_lookupflags_t old_flags,
const char* old_path,
uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_fd_t dirfd,
uvwasi_lookupflags_t dirflags,
const char* path,
uvwasi_size_t path_len,
uvwasi_oflags_t o_flags,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting,
uvwasi_fdflags_t fs_flags,
uvwasi_fd_t* fd);
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
uvwasi_size_t path_len,
char* buf,
uvwasi_size_t buf_len,
uvwasi_size_t* bufused);
uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
const char* old_path,
uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
const char* old_path,
uvwasi_size_t old_path_len,
uvwasi_fd_t fd,
const char* new_path,
uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
const uvwasi_subscription_t* in,
uvwasi_event_t* out,
uvwasi_size_t nsubscriptions,
uvwasi_size_t* nevents);
uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval);
uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig);
uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
void* buf,
uvwasi_size_t buf_len);
uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi);
uvwasi_errno_t uvwasi_sock_accept(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
uvwasi_fdflags_t flags,
uvwasi_fd_t* fd);
uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_iovec_t* ri_data,
uvwasi_size_t ri_data_len,
uvwasi_riflags_t ri_flags,
uvwasi_size_t* ro_datalen,
uvwasi_roflags_t* ro_flags);
uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_ciovec_t* si_data,
uvwasi_size_t si_data_len,
uvwasi_siflags_t si_flags,
uvwasi_size_t* so_datalen);
uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
uvwasi_sdflags_t how);
#ifdef __cplusplus
}
#endif
#endif /* __UVWASI_H__ */

146
deps/uvwasi/include/wasi_serdes.h vendored Normal file
View File

@ -0,0 +1,146 @@
#ifndef __UVWASI_SERDES_H__
#define __UVWASI_SERDES_H__
#include "wasi_types.h"
/* Basic uint{8,16,32,64}_t read/write functions. */
#define BASIC_TYPE(name, type) \
void uvwasi_serdes_write_##name(void* ptr, size_t offset, type value); \
type uvwasi_serdes_read_##name(const void* ptr, size_t offset); \
#define BASIC_TYPE_UVWASI(type) BASIC_TYPE(type, uvwasi_##type)
#define UVWASI_SERDES_SIZE_uint8_t sizeof(uint8_t)
BASIC_TYPE(uint8_t, uint8_t)
#define UVWASI_SERDES_SIZE_uint16_t sizeof(uint16_t)
BASIC_TYPE(uint16_t, uint16_t)
#define UVWASI_SERDES_SIZE_uint32_t sizeof(uint32_t)
BASIC_TYPE(uint32_t, uint32_t)
#define UVWASI_SERDES_SIZE_uint64_t sizeof(uint64_t)
BASIC_TYPE(uint64_t, uint64_t)
#define UVWASI_SERDES_SIZE_advice_t sizeof(uvwasi_advice_t)
BASIC_TYPE_UVWASI(advice_t)
#define UVWASI_SERDES_SIZE_clockid_t sizeof(uvwasi_clockid_t)
BASIC_TYPE_UVWASI(clockid_t)
#define UVWASI_SERDES_SIZE_device_t sizeof(uvwasi_device_t)
BASIC_TYPE_UVWASI(device_t)
#define UVWASI_SERDES_SIZE_dircookie_t sizeof(uvwasi_dircookie_t)
BASIC_TYPE_UVWASI(dircookie_t)
#define UVWASI_SERDES_SIZE_eventrwflags_t sizeof(uvwasi_eventrwflags_t)
BASIC_TYPE_UVWASI(eventrwflags_t)
#define UVWASI_SERDES_SIZE_eventtype_t sizeof(uvwasi_eventtype_t)
BASIC_TYPE_UVWASI(eventtype_t)
#define UVWASI_SERDES_SIZE_exitcode_t sizeof(uvwasi_exitcode_t)
BASIC_TYPE_UVWASI(exitcode_t)
#define UVWASI_SERDES_SIZE_fd_t sizeof(uvwasi_fd_t)
BASIC_TYPE_UVWASI(fd_t)
#define UVWASI_SERDES_SIZE_fdflags_t sizeof(uvwasi_fdflags_t)
BASIC_TYPE_UVWASI(fdflags_t)
#define UVWASI_SERDES_SIZE_filesize_t sizeof(uvwasi_filesize_t)
BASIC_TYPE_UVWASI(filesize_t)
#define UVWASI_SERDES_SIZE_fstflags_t sizeof(uvwasi_fstflags_t)
BASIC_TYPE_UVWASI(fstflags_t)
#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
BASIC_TYPE_UVWASI(inode_t)
#define UVWASI_SERDES_SIZE_linkcount_t sizeof(uvwasi_linkcount_t)
BASIC_TYPE_UVWASI(linkcount_t)
#define UVWASI_SERDES_SIZE_lookupflags_t sizeof(uvwasi_lookupflags_t)
BASIC_TYPE_UVWASI(lookupflags_t)
#define UVWASI_SERDES_SIZE_oflags_t sizeof(uvwasi_oflags_t)
BASIC_TYPE_UVWASI(oflags_t)
#define UVWASI_SERDES_SIZE_preopentype_t sizeof(uvwasi_preopentype_t)
BASIC_TYPE_UVWASI(preopentype_t)
#define UVWASI_SERDES_SIZE_riflags_t sizeof(uvwasi_riflags_t)
BASIC_TYPE_UVWASI(riflags_t)
#define UVWASI_SERDES_SIZE_rights_t sizeof(uvwasi_rights_t)
BASIC_TYPE_UVWASI(rights_t)
#define UVWASI_SERDES_SIZE_roflags_t sizeof(uvwasi_roflags_t)
BASIC_TYPE_UVWASI(roflags_t)
#define UVWASI_SERDES_SIZE_sdflags_t sizeof(uvwasi_sdflags_t)
BASIC_TYPE_UVWASI(sdflags_t)
#define UVWASI_SERDES_SIZE_siflags_t sizeof(uvwasi_siflags_t)
BASIC_TYPE_UVWASI(siflags_t)
#define UVWASI_SERDES_SIZE_size_t sizeof(uvwasi_size_t)
BASIC_TYPE_UVWASI(size_t)
#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
BASIC_TYPE_UVWASI(inode_t)
#define UVWASI_SERDES_SIZE_signal_t sizeof(uvwasi_signal_t)
BASIC_TYPE_UVWASI(signal_t)
#define UVWASI_SERDES_SIZE_subclockflags_t sizeof(uvwasi_subclockflags_t)
BASIC_TYPE_UVWASI(subclockflags_t)
#define UVWASI_SERDES_SIZE_timestamp_t sizeof(uvwasi_timestamp_t)
BASIC_TYPE_UVWASI(timestamp_t)
#define UVWASI_SERDES_SIZE_userdata_t sizeof(uvwasi_userdata_t)
BASIC_TYPE_UVWASI(userdata_t)
#define UVWASI_SERDES_SIZE_whence_t sizeof(uvwasi_whence_t)
BASIC_TYPE_UVWASI(whence_t)
#undef BASIC_TYPE_UVWASI
#undef BASIC_TYPE
/* WASI structure read/write functions. */
#define STRUCT(name) \
void uvwasi_serdes_write_##name(void* ptr, \
size_t offset, \
const uvwasi_##name* value); \
void uvwasi_serdes_read_##name(const void* ptr, \
size_t offset, \
uvwasi_##name* value);
/* iovs currently only need to be read from WASM memory. */
#define IOVS_STRUCT(name) \
uvwasi_errno_t uvwasi_serdes_read_##name(const void* ptr, \
size_t end, \
size_t offset, \
uvwasi_##name* value);
#define UVWASI_SERDES_SIZE_ciovec_t 8
IOVS_STRUCT(ciovec_t)
#define UVWASI_SERDES_SIZE_iovec_t 8
IOVS_STRUCT(iovec_t)
#define UVWASI_SERDES_SIZE_dirent_t 24
STRUCT(dirent_t)
#define UVWASI_SERDES_SIZE_fdstat_t 24
STRUCT(fdstat_t)
#define UVWASI_SERDES_SIZE_filestat_t 64
STRUCT(filestat_t)
#define UVWASI_SERDES_SIZE_prestat_t 8
STRUCT(prestat_t)
#define UVWASI_SERDES_SIZE_event_t 32
STRUCT(event_t)
#define UVWASI_SERDES_SIZE_subscription_t 48
STRUCT(subscription_t)
#undef STRUCT
#undef IOVS_STRUCT
uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len);
uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len);
/* Helper functions for memory bounds checking. */
int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size);
int uvwasi_serdes_check_array_bounds(size_t offset,
size_t end,
size_t size,
size_t count);
#endif /* __UVWASI_SERDES_H__ */

325
deps/uvwasi/include/wasi_types.h vendored Normal file
View File

@ -0,0 +1,325 @@
#ifndef __UVWASI_WASI_TYPES_H__
#define __UVWASI_WASI_TYPES_H__
#include <stddef.h>
#include <stdint.h>
/* API: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md */
typedef uint32_t uvwasi_size_t;
typedef uint8_t uvwasi_advice_t;
#define UVWASI_ADVICE_NORMAL 0
#define UVWASI_ADVICE_SEQUENTIAL 1
#define UVWASI_ADVICE_RANDOM 2
#define UVWASI_ADVICE_WILLNEED 3
#define UVWASI_ADVICE_DONTNEED 4
#define UVWASI_ADVICE_NOREUSE 5
typedef struct uvwasi_ciovec_s {
const void* buf;
uvwasi_size_t buf_len;
} uvwasi_ciovec_t;
typedef uint32_t uvwasi_clockid_t;
#define UVWASI_CLOCK_REALTIME 0
#define UVWASI_CLOCK_MONOTONIC 1
#define UVWASI_CLOCK_PROCESS_CPUTIME_ID 2
#define UVWASI_CLOCK_THREAD_CPUTIME_ID 3
typedef uint64_t uvwasi_device_t;
typedef uint64_t uvwasi_dircookie_t;
#define UVWASI_DIRCOOKIE_START 0
typedef uint16_t uvwasi_errno_t;
#define UVWASI_ESUCCESS 0
#define UVWASI_E2BIG 1
#define UVWASI_EACCES 2
#define UVWASI_EADDRINUSE 3
#define UVWASI_EADDRNOTAVAIL 4
#define UVWASI_EAFNOSUPPORT 5
#define UVWASI_EAGAIN 6
#define UVWASI_EALREADY 7
#define UVWASI_EBADF 8
#define UVWASI_EBADMSG 9
#define UVWASI_EBUSY 10
#define UVWASI_ECANCELED 11
#define UVWASI_ECHILD 12
#define UVWASI_ECONNABORTED 13
#define UVWASI_ECONNREFUSED 14
#define UVWASI_ECONNRESET 15
#define UVWASI_EDEADLK 16
#define UVWASI_EDESTADDRREQ 17
#define UVWASI_EDOM 18
#define UVWASI_EDQUOT 19
#define UVWASI_EEXIST 20
#define UVWASI_EFAULT 21
#define UVWASI_EFBIG 22
#define UVWASI_EHOSTUNREACH 23
#define UVWASI_EIDRM 24
#define UVWASI_EILSEQ 25
#define UVWASI_EINPROGRESS 26
#define UVWASI_EINTR 27
#define UVWASI_EINVAL 28
#define UVWASI_EIO 29
#define UVWASI_EISCONN 30
#define UVWASI_EISDIR 31
#define UVWASI_ELOOP 32
#define UVWASI_EMFILE 33
#define UVWASI_EMLINK 34
#define UVWASI_EMSGSIZE 35
#define UVWASI_EMULTIHOP 36
#define UVWASI_ENAMETOOLONG 37
#define UVWASI_ENETDOWN 38
#define UVWASI_ENETRESET 39
#define UVWASI_ENETUNREACH 40
#define UVWASI_ENFILE 41
#define UVWASI_ENOBUFS 42
#define UVWASI_ENODEV 43
#define UVWASI_ENOENT 44
#define UVWASI_ENOEXEC 45
#define UVWASI_ENOLCK 46
#define UVWASI_ENOLINK 47
#define UVWASI_ENOMEM 48
#define UVWASI_ENOMSG 49
#define UVWASI_ENOPROTOOPT 50
#define UVWASI_ENOSPC 51
#define UVWASI_ENOSYS 52
#define UVWASI_ENOTCONN 53
#define UVWASI_ENOTDIR 54
#define UVWASI_ENOTEMPTY 55
#define UVWASI_ENOTRECOVERABLE 56
#define UVWASI_ENOTSOCK 57
#define UVWASI_ENOTSUP 58
#define UVWASI_ENOTTY 59
#define UVWASI_ENXIO 60
#define UVWASI_EOVERFLOW 61
#define UVWASI_EOWNERDEAD 62
#define UVWASI_EPERM 63
#define UVWASI_EPIPE 64
#define UVWASI_EPROTO 65
#define UVWASI_EPROTONOSUPPORT 66
#define UVWASI_EPROTOTYPE 67
#define UVWASI_ERANGE 68
#define UVWASI_EROFS 69
#define UVWASI_ESPIPE 70
#define UVWASI_ESRCH 71
#define UVWASI_ESTALE 72
#define UVWASI_ETIMEDOUT 73
#define UVWASI_ETXTBSY 74
#define UVWASI_EXDEV 75
#define UVWASI_ENOTCAPABLE 76
typedef uint16_t uvwasi_eventrwflags_t; /* Bitfield */
#define UVWASI_EVENT_FD_READWRITE_HANGUP (1 << 0)
typedef uint8_t uvwasi_eventtype_t;
#define UVWASI_EVENTTYPE_CLOCK 0
#define UVWASI_EVENTTYPE_FD_READ 1
#define UVWASI_EVENTTYPE_FD_WRITE 2
typedef uint32_t uvwasi_exitcode_t;
typedef uint32_t uvwasi_fd_t;
typedef uint16_t uvwasi_fdflags_t; /* Bitfield */
#define UVWASI_FDFLAG_APPEND (1 << 0)
#define UVWASI_FDFLAG_DSYNC (1 << 1)
#define UVWASI_FDFLAG_NONBLOCK (1 << 2)
#define UVWASI_FDFLAG_RSYNC (1 << 3)
#define UVWASI_FDFLAG_SYNC (1 << 4)
typedef int64_t uvwasi_filedelta_t;
typedef uint64_t uvwasi_filesize_t;
typedef uint8_t uvwasi_filetype_t;
#define UVWASI_FILETYPE_UNKNOWN 0
#define UVWASI_FILETYPE_BLOCK_DEVICE 1
#define UVWASI_FILETYPE_CHARACTER_DEVICE 2
#define UVWASI_FILETYPE_DIRECTORY 3
#define UVWASI_FILETYPE_REGULAR_FILE 4
#define UVWASI_FILETYPE_SOCKET_DGRAM 5
#define UVWASI_FILETYPE_SOCKET_STREAM 6
#define UVWASI_FILETYPE_SYMBOLIC_LINK 7
typedef uint16_t uvwasi_fstflags_t; /* Bitfield */
#define UVWASI_FILESTAT_SET_ATIM (1 << 0)
#define UVWASI_FILESTAT_SET_ATIM_NOW (1 << 1)
#define UVWASI_FILESTAT_SET_MTIM (1 << 2)
#define UVWASI_FILESTAT_SET_MTIM_NOW (1 << 3)
typedef uint64_t uvwasi_inode_t;
typedef struct uvwasi_iovec_s {
void* buf;
uvwasi_size_t buf_len;
} uvwasi_iovec_t;
typedef uint64_t uvwasi_linkcount_t;
typedef uint32_t uvwasi_lookupflags_t; /* Bitfield */
#define UVWASI_LOOKUP_SYMLINK_FOLLOW (1 << 0)
typedef uint16_t uvwasi_oflags_t; /* Bitfield */
#define UVWASI_O_CREAT (1 << 0)
#define UVWASI_O_DIRECTORY (1 << 1)
#define UVWASI_O_EXCL (1 << 2)
#define UVWASI_O_TRUNC (1 << 3)
typedef uint8_t uvwasi_preopentype_t;
#define UVWASI_PREOPENTYPE_DIR 0
typedef struct uvwasi_prestat_s {
uvwasi_preopentype_t pr_type;
union uvwasi_prestat_u {
struct uvwasi_prestat_dir_t {
uvwasi_size_t pr_name_len;
} dir;
} u;
} uvwasi_prestat_t;
typedef uint16_t uvwasi_riflags_t; /* Bitfield */
#define UVWASI_SOCK_RECV_PEEK (1 << 0)
#define UVWASI_SOCK_RECV_WAITALL (1 << 1)
typedef uint64_t uvwasi_rights_t; /* Bitfield */
#define UVWASI_RIGHT_FD_DATASYNC (1 << 0)
#define UVWASI_RIGHT_FD_READ (1 << 1)
#define UVWASI_RIGHT_FD_SEEK (1 << 2)
#define UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS (1 << 3)
#define UVWASI_RIGHT_FD_SYNC (1 << 4)
#define UVWASI_RIGHT_FD_TELL (1 << 5)
#define UVWASI_RIGHT_FD_WRITE (1 << 6)
#define UVWASI_RIGHT_FD_ADVISE (1 << 7)
#define UVWASI_RIGHT_FD_ALLOCATE (1 << 8)
#define UVWASI_RIGHT_PATH_CREATE_DIRECTORY (1 << 9)
#define UVWASI_RIGHT_PATH_CREATE_FILE (1 << 10)
#define UVWASI_RIGHT_PATH_LINK_SOURCE (1 << 11)
#define UVWASI_RIGHT_PATH_LINK_TARGET (1 << 12)
#define UVWASI_RIGHT_PATH_OPEN (1 << 13)
#define UVWASI_RIGHT_FD_READDIR (1 << 14)
#define UVWASI_RIGHT_PATH_READLINK (1 << 15)
#define UVWASI_RIGHT_PATH_RENAME_SOURCE (1 << 16)
#define UVWASI_RIGHT_PATH_RENAME_TARGET (1 << 17)
#define UVWASI_RIGHT_PATH_FILESTAT_GET (1 << 18)
#define UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE (1 << 19)
#define UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES (1 << 20)
#define UVWASI_RIGHT_FD_FILESTAT_GET (1 << 21)
#define UVWASI_RIGHT_FD_FILESTAT_SET_SIZE (1 << 22)
#define UVWASI_RIGHT_FD_FILESTAT_SET_TIMES (1 << 23)
#define UVWASI_RIGHT_PATH_SYMLINK (1 << 24)
#define UVWASI_RIGHT_PATH_REMOVE_DIRECTORY (1 << 25)
#define UVWASI_RIGHT_PATH_UNLINK_FILE (1 << 26)
#define UVWASI_RIGHT_POLL_FD_READWRITE (1 << 27)
#define UVWASI_RIGHT_SOCK_SHUTDOWN (1 << 28)
#define UVWASI_RIGHT_SOCK_ACCEPT (1 << 29)
typedef uint16_t uvwasi_roflags_t; /* Bitfield */
#define UVWASI_SOCK_RECV_DATA_TRUNCATED (1 << 0)
typedef uint8_t uvwasi_sdflags_t; /* Bitfield */
#define UVWASI_SHUT_RD (1 << 0)
#define UVWASI_SHUT_WR (1 << 1)
typedef uint16_t uvwasi_siflags_t; /* Bitfield */
typedef uint8_t uvwasi_signal_t;
#define UVWASI_SIGHUP 1
#define UVWASI_SIGINT 2
#define UVWASI_SIGQUIT 3
#define UVWASI_SIGILL 4
#define UVWASI_SIGTRAP 5
#define UVWASI_SIGABRT 6
#define UVWASI_SIGBUS 7
#define UVWASI_SIGFPE 8
#define UVWASI_SIGKILL 9
#define UVWASI_SIGUSR1 10
#define UVWASI_SIGSEGV 11
#define UVWASI_SIGUSR2 12
#define UVWASI_SIGPIPE 13
#define UVWASI_SIGALRM 14
#define UVWASI_SIGTERM 15
#define UVWASI_SIGCHLD 16
#define UVWASI_SIGCONT 17
#define UVWASI_SIGSTOP 18
#define UVWASI_SIGTSTP 19
#define UVWASI_SIGTTIN 20
#define UVWASI_SIGTTOU 21
#define UVWASI_SIGURG 22
#define UVWASI_SIGXCPU 23
#define UVWASI_SIGXFSZ 24
#define UVWASI_SIGVTALRM 25
#define UVWASI_SIGPROF 26
#define UVWASI_SIGWINCH 27
#define UVWASI_SIGPOLL 28
#define UVWASI_SIGPWR 29
#define UVWASI_SIGSYS 30
typedef uint16_t uvwasi_subclockflags_t; /* Bitfield */
#define UVWASI_SUBSCRIPTION_CLOCK_ABSTIME (1 << 0)
typedef uint64_t uvwasi_timestamp_t;
typedef uint64_t uvwasi_userdata_t;
typedef struct uvwasi_subscription_s {
uvwasi_userdata_t userdata;
uvwasi_eventtype_t type;
union {
struct {
uvwasi_clockid_t clock_id;
uvwasi_timestamp_t timeout;
uvwasi_timestamp_t precision;
uvwasi_subclockflags_t flags;
} clock;
struct {
uvwasi_fd_t fd;
} fd_readwrite;
} u;
} uvwasi_subscription_t;
typedef struct uvwasi_dirent_s {
uvwasi_dircookie_t d_next;
uvwasi_inode_t d_ino;
uint32_t d_namlen;
uvwasi_filetype_t d_type;
} uvwasi_dirent_t;
typedef struct uvwasi_fdstat_s {
uvwasi_filetype_t fs_filetype;
uvwasi_fdflags_t fs_flags;
uvwasi_rights_t fs_rights_base;
uvwasi_rights_t fs_rights_inheriting;
} uvwasi_fdstat_t;
typedef struct uvwasi_filestat_s {
uvwasi_device_t st_dev;
uvwasi_inode_t st_ino;
uvwasi_filetype_t st_filetype;
uvwasi_linkcount_t st_nlink;
uvwasi_filesize_t st_size;
uvwasi_timestamp_t st_atim;
uvwasi_timestamp_t st_mtim;
uvwasi_timestamp_t st_ctim;
} uvwasi_filestat_t;
typedef struct uvwasi_event_s {
uvwasi_userdata_t userdata;
uvwasi_errno_t error;
uvwasi_eventtype_t type;
union {
struct {
uvwasi_filesize_t nbytes;
uvwasi_eventrwflags_t flags;
} fd_readwrite;
} u;
} uvwasi_event_t;
typedef uint8_t uvwasi_whence_t;
#define UVWASI_WHENCE_SET 0
#define UVWASI_WHENCE_CUR 1
#define UVWASI_WHENCE_END 2
#endif /* __UVWASI_WASI_TYPES_H__ */

180
deps/uvwasi/src/clocks.c vendored Normal file
View File

@ -0,0 +1,180 @@
#ifndef _WIN32
# include <errno.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <time.h>
#endif /* _WIN32 */
#include "uv.h"
#include "clocks.h"
#include "wasi_types.h"
#include "uv_mapping.h"
#define UVWASI__WIN_TIME_AND_RETURN(handle, get_times, time) \
do { \
FILETIME create; \
FILETIME exit; \
FILETIME system; \
FILETIME user; \
if (0 == get_times((handle), &create, &exit, &system, &user)) { \
return uvwasi__translate_uv_error( \
uv_translate_sys_error(GetLastError()) \
); \
} \
\
/* FILETIME times are in units of 100 nanoseconds */ \
(time) = (((uvwasi_timestamp_t) \
system.dwHighDateTime << 32 | system.dwLowDateTime) * 100 + \
((uvwasi_timestamp_t) \
user.dwHighDateTime << 32 | user.dwLowDateTime) * 100); \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__CLOCK_GETTIME_AND_RETURN(clk, time) \
do { \
struct timespec ts; \
if (0 != clock_gettime((clk), &ts)) \
return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \
(time) = ((uvwasi_timestamp_t)(ts.tv_sec) * NANOS_PER_SEC) + ts.tv_nsec; \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__GETRUSAGE_AND_RETURN(who, time) \
do { \
struct rusage ru; \
if (0 != getrusage((who), &ru)) \
return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \
(time) = ((uvwasi_timestamp_t)(ru.ru_utime.tv_sec) * NANOS_PER_SEC) + \
(ru.ru_utime.tv_usec * 1000) + \
((uvwasi_timestamp_t)(ru.ru_stime.tv_sec) * NANOS_PER_SEC) + \
(ru.ru_stime.tv_usec * 1000); \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__OSX_THREADTIME_AND_RETURN(time) \
do { \
mach_port_t thread; \
thread_basic_info_data_t info; \
mach_msg_type_number_t count; \
count = THREAD_BASIC_INFO_COUNT; \
thread = pthread_mach_thread_np(pthread_self()); \
if (KERN_SUCCESS != thread_info(thread, \
THREAD_BASIC_INFO, \
(thread_info_t) &info, \
&count)) { \
return UVWASI_ENOSYS; \
} \
(time) = ((uvwasi_timestamp_t)(info.user_time.seconds) * NANOS_PER_SEC) + \
(info.user_time.microseconds * 1000) + \
((uvwasi_timestamp_t)(info.system_time.seconds) * NANOS_PER_SEC) + \
(info.system_time.microseconds * 1000); \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__WIN_GETRES_AND_RETURN(time) \
do { \
/* The GetProcessTimes() docs claim a resolution of 100 ns. */ \
(time) = 100; \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__CLOCK_GETRES_AND_RETURN(clk, time) \
do { \
struct timespec ts; \
/* Try calling clock_getres(). If it doesn't succeed, then default to \
1000000. We implement all of the clocks, and some platforms (such as \
SmartOS) don't support all of the clocks, even though they define \
the constants for them. */ \
if (0 != clock_getres((clk), &ts)) \
(time) = 1000000; \
else \
(time) = ((uvwasi_timestamp_t)(ts.tv_sec) * NANOS_PER_SEC) + ts.tv_nsec; \
return UVWASI_ESUCCESS; \
} while (0)
#define UVWASI__SLOW_GETRES_AND_RETURN(time) \
do { \
/* Assume a "worst case" of 1000000 ns resolution. */ \
(time) = 1000000; \
return UVWASI_ESUCCESS; \
} while (0)
uvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time) {
uv_timeval64_t tv;
int r;
r = uv_gettimeofday(&tv);
if (r != 0)
return uvwasi__translate_uv_error(r);
*time = (tv.tv_sec * NANOS_PER_SEC) + (tv.tv_usec * 1000);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time) {
#if defined(_WIN32)
UVWASI__WIN_TIME_AND_RETURN(GetCurrentProcess(), GetProcessTimes, *time);
#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \
!defined(__APPLE__) && \
!defined(__sun)
UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time);
#else
UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_SELF, *time);
#endif
}
uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time) {
#if defined(_WIN32)
UVWASI__WIN_TIME_AND_RETURN(GetCurrentThread(), GetThreadTimes, *time);
#elif defined(__APPLE__)
UVWASI__OSX_THREADTIME_AND_RETURN(*time);
#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__)
UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time);
#else
# if defined(RUSAGE_LWP)
UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_LWP, *time);
# elif defined(RUSAGE_THREAD)
UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_THREAD, *time);
# else
return UVWASI_ENOSYS;
# endif /* RUSAGE_LWP */
#endif
}
uvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time) {
#if defined(_WIN32)
UVWASI__WIN_GETRES_AND_RETURN(*time);
#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \
!defined(__APPLE__) && \
!defined(__sun)
UVWASI__CLOCK_GETRES_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time);
#else
UVWASI__SLOW_GETRES_AND_RETURN(*time);
#endif
}
uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time) {
#if defined(_WIN32)
UVWASI__WIN_GETRES_AND_RETURN(*time);
#elif defined(__APPLE__)
UVWASI__SLOW_GETRES_AND_RETURN(*time);
#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__)
UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time);
#elif defined(RUSAGE_THREAD) || defined(RUSAGE_LWP)
UVWASI__SLOW_GETRES_AND_RETURN(*time);
#else
return UVWASI_ENOSYS;
#endif
}

13
deps/uvwasi/src/clocks.h vendored Normal file
View File

@ -0,0 +1,13 @@
#ifndef __UVWASI_CLOCKS_H__
#define __UVWASI_CLOCKS_H__
#include "wasi_types.h"
uvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time);
uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time);
#endif /* __UVWASI_CLOCKS_H__ */

15
deps/uvwasi/src/debug.h vendored Normal file
View File

@ -0,0 +1,15 @@
#ifndef __UVWASI_DEBUG_H__
#define __UVWASI_DEBUG_H__
#ifdef UVWASI_DEBUG_LOG
#ifndef __STDC_FORMAT_MACROS
# define __STDC_FORMAT_MACROS
#endif
# include <inttypes.h>
# define UVWASI_DEBUG(...) \
do { fprintf(stderr, __VA_ARGS__); } while (0)
#else
# define UVWASI_DEBUG(fmt, ...)
#endif
#endif /* __UVWASI_DEBUG_H__ */

485
deps/uvwasi/src/fd_table.c vendored Normal file
View File

@ -0,0 +1,485 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#ifndef _WIN32
# include <sys/types.h>
#endif /* _WIN32 */
#include "uv.h"
#include "fd_table.h"
#include "path_resolver.h"
#include "wasi_types.h"
#include "wasi_rights.h"
#include "uv_mapping.h"
#include "uvwasi_alloc.h"
static uvwasi_errno_t uvwasi__insert_stdio(uvwasi_t* uvwasi,
struct uvwasi_fd_table_t* table,
const uvwasi_fd_t fd,
const uvwasi_fd_t expected,
const char* name) {
struct uvwasi_fd_wrap_t* wrap;
uvwasi_filetype_t type;
uvwasi_rights_t base;
uvwasi_rights_t inheriting;
uvwasi_errno_t err;
err = uvwasi__get_filetype_by_fd(fd, &type);
if (err != UVWASI_ESUCCESS)
return err;
err = uvwasi__get_rights(fd, UV_FS_O_RDWR, type, &base, &inheriting);
if (err != UVWASI_ESUCCESS)
return err;
err = uvwasi_fd_table_insert(uvwasi,
table,
fd,
NULL,
name,
name,
type,
base,
inheriting,
0,
&wrap);
if (err != UVWASI_ESUCCESS)
return err;
if (wrap->id != expected)
err = UVWASI_EBADF;
uv_mutex_unlock(&wrap->mutex);
return err;
}
uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi,
struct uvwasi_fd_table_t* table,
uv_file fd,
uv_tcp_t* sock,
const char* mapped_path,
const char* real_path,
uvwasi_filetype_t type,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting,
int preopen,
struct uvwasi_fd_wrap_t** wrap) {
struct uvwasi_fd_wrap_t* entry;
struct uvwasi_fd_wrap_t** new_fds;
uvwasi_errno_t err;
uint32_t new_size;
uint32_t index;
uint32_t i;
int r;
size_t mp_len;
char* mp_copy;
size_t rp_len;
char* rp_copy;
char* np_copy;
if (type != UVWASI_FILETYPE_SOCKET_STREAM) {
mp_len = strlen(mapped_path);
rp_len = strlen(real_path);
} else {
mp_len = 0;
rp_len = 0;
rp_copy = NULL;
mp_copy = NULL;
np_copy = NULL;
}
/* Reserve room for the mapped path, real path, and normalized mapped path. */
entry = (struct uvwasi_fd_wrap_t*)
uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + mp_len + rp_len + 3);
if (entry == NULL)
return UVWASI_ENOMEM;
if (type != UVWASI_FILETYPE_SOCKET_STREAM) {
mp_copy = (char*)(entry + 1);
rp_copy = mp_copy + mp_len + 1;
np_copy = rp_copy + rp_len + 1;
memcpy(mp_copy, mapped_path, mp_len);
mp_copy[mp_len] = '\0';
memcpy(rp_copy, real_path, rp_len);
rp_copy[rp_len] = '\0';
/* Calculate the normalized version of the mapped path, as it will be used for
any path calculations on this fd. Use the length of the mapped path as an
upper bound for the normalized path length. */
err = uvwasi__normalize_path(mp_copy, mp_len, np_copy, mp_len);
if (err) {
uvwasi__free(uvwasi, entry);
goto exit;
}
}
uv_rwlock_wrlock(&table->rwlock);
/* Check that there is room for a new item. If there isn't, grow the table. */
if (table->used >= table->size) {
new_size = table->size * 2;
new_fds = uvwasi__realloc(uvwasi, table->fds, new_size * sizeof(*new_fds));
if (new_fds == NULL) {
uvwasi__free(uvwasi, entry);
err = UVWASI_ENOMEM;
goto exit;
}
for (i = table->size; i < new_size; ++i)
new_fds[i] = NULL;
index = table->size;
table->fds = new_fds;
table->size = new_size;
} else {
/* The table is big enough, so find an empty slot for the new data. */
int valid_slot = 0;
for (i = 0; i < table->size; ++i) {
if (table->fds[i] == NULL) {
valid_slot = 1;
index = i;
break;
}
}
/* This should never happen. */
if (valid_slot == 0) {
uvwasi__free(uvwasi, entry);
err = UVWASI_ENOSPC;
goto exit;
}
}
table->fds[index] = entry;
r = uv_mutex_init(&entry->mutex);
if (r != 0) {
err = uvwasi__translate_uv_error(r);
goto exit;
}
entry->id = index;
entry->fd = fd;
entry->sock = sock;
entry->path = mp_copy;
entry->real_path = rp_copy;
entry->normalized_path = np_copy;
entry->type = type;
entry->rights_base = rights_base;
entry->rights_inheriting = rights_inheriting;
entry->preopen = preopen;
if (wrap != NULL) {
uv_mutex_lock(&entry->mutex);
*wrap = entry;
}
table->used++;
err = UVWASI_ESUCCESS;
exit:
uv_rwlock_wrunlock(&table->rwlock);
return err;
}
uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
const uvwasi_options_t* options) {
struct uvwasi_fd_table_t* table;
uvwasi_errno_t err;
int r;
/* Require an initial size of at least three to store the stdio FDs. */
if (uvwasi == NULL || options == NULL || options->fd_table_size < 3)
return UVWASI_EINVAL;
table = uvwasi__malloc(uvwasi, sizeof(*table));
if (table == NULL)
return UVWASI_ENOMEM;
table->used = 0;
table->size = options->fd_table_size;
table->fds = uvwasi__calloc(uvwasi,
options->fd_table_size,
sizeof(struct uvwasi_fd_wrap_t*));
if (table->fds == NULL) {
uvwasi__free(uvwasi, table);
return UVWASI_ENOMEM;
}
r = uv_rwlock_init(&table->rwlock);
if (r != 0) {
err = uvwasi__translate_uv_error(r);
uvwasi__free(uvwasi, table->fds);
uvwasi__free(uvwasi, table);
return err;
}
/* Create the stdio FDs. */
err = uvwasi__insert_stdio(uvwasi, table, options->in, 0, "<stdin>");
if (err != UVWASI_ESUCCESS)
goto error_exit;
err = uvwasi__insert_stdio(uvwasi, table, options->out, 1, "<stdout>");
if (err != UVWASI_ESUCCESS)
goto error_exit;
err = uvwasi__insert_stdio(uvwasi, table, options->err, 2, "<stderr>");
if (err != UVWASI_ESUCCESS)
goto error_exit;
uvwasi->fds = table;
return UVWASI_ESUCCESS;
error_exit:
uvwasi_fd_table_free(uvwasi, table);
return err;
}
void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
struct uvwasi_fd_wrap_t* entry;
uint32_t i;
if (uvwasi == NULL || table == NULL)
return;
for (i = 0; i < table->size; i++) {
entry = table->fds[i];
if (entry == NULL)
continue;
uv_mutex_destroy(&entry->mutex);
uvwasi__free(uvwasi, entry);
}
if (table->fds != NULL) {
uvwasi__free(uvwasi, table->fds);
table->fds = NULL;
table->size = 0;
table->used = 0;
uv_rwlock_destroy(&table->rwlock);
}
uvwasi__free(uvwasi, table);
}
uvwasi_errno_t uvwasi_fd_table_insert_preopen(uvwasi_t* uvwasi,
struct uvwasi_fd_table_t* table,
const uv_file fd,
const char* path,
const char* real_path) {
uvwasi_filetype_t type;
uvwasi_rights_t base;
uvwasi_rights_t inheriting;
uvwasi_errno_t err;
if (table == NULL || path == NULL || real_path == NULL)
return UVWASI_EINVAL;
err = uvwasi__get_filetype_by_fd(fd, &type);
if (err != UVWASI_ESUCCESS)
return err;
if (type != UVWASI_FILETYPE_DIRECTORY)
return UVWASI_ENOTDIR;
err = uvwasi__get_rights(fd, 0, type, &base, &inheriting);
if (err != UVWASI_ESUCCESS)
return err;
return uvwasi_fd_table_insert(uvwasi,
table,
fd,
NULL,
path,
real_path,
UVWASI_FILETYPE_DIRECTORY,
UVWASI__RIGHTS_DIRECTORY_BASE,
UVWASI__RIGHTS_DIRECTORY_INHERITING,
1,
NULL);
}
uvwasi_errno_t uvwasi_fd_table_insert_preopen_socket(uvwasi_t* uvwasi,
struct uvwasi_fd_table_t* table,
uv_tcp_t* sock) {
if (table == NULL || sock == NULL)
return UVWASI_EINVAL;
return uvwasi_fd_table_insert(uvwasi,
table,
-1,
sock,
NULL,
NULL,
UVWASI_FILETYPE_SOCKET_STREAM,
UVWASI__RIGHTS_SOCKET_BASE,
UVWASI__RIGHTS_SOCKET_INHERITING,
1,
NULL);
}
uvwasi_errno_t uvwasi_fd_table_get(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id,
struct uvwasi_fd_wrap_t** wrap,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting) {
uvwasi_errno_t err;
if (table == NULL)
return UVWASI_EINVAL;
uv_rwlock_wrlock(&table->rwlock);
err = uvwasi_fd_table_get_nolock(table,
id,
wrap,
rights_base,
rights_inheriting);
uv_rwlock_wrunlock(&table->rwlock);
return err;
}
/* uvwasi_fd_table_get_nolock() retrieves a file descriptor and locks its mutex,
but does not lock the file descriptor table like uvwasi_fd_table_get() does.
*/
uvwasi_errno_t uvwasi_fd_table_get_nolock(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id,
struct uvwasi_fd_wrap_t** wrap,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting) {
struct uvwasi_fd_wrap_t* entry;
if (table == NULL || wrap == NULL)
return UVWASI_EINVAL;
if (id >= table->size)
return UVWASI_EBADF;
entry = table->fds[id];
if (entry == NULL || entry->id != id)
return UVWASI_EBADF;
/* Validate that the fd has the necessary rights. */
if ((~entry->rights_base & rights_base) != 0 ||
(~entry->rights_inheriting & rights_inheriting) != 0) {
return UVWASI_ENOTCAPABLE;
}
uv_mutex_lock(&entry->mutex);
*wrap = entry;
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_fd_table_remove_nolock(uvwasi_t* uvwasi,
struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id) {
struct uvwasi_fd_wrap_t* entry;
if (table == NULL)
return UVWASI_EINVAL;
if (id >= table->size)
return UVWASI_EBADF;
entry = table->fds[id];
if (entry == NULL || entry->id != id)
return UVWASI_EBADF;
uv_mutex_destroy(&entry->mutex);
uvwasi__free(uvwasi, entry);
table->fds[id] = NULL;
table->used--;
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_fd_table_renumber(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
const uvwasi_fd_t dst,
const uvwasi_fd_t src) {
struct uvwasi_fd_wrap_t* dst_entry;
struct uvwasi_fd_wrap_t* src_entry;
uv_fs_t req;
uvwasi_errno_t err;
int r;
if (uvwasi == NULL || table == NULL)
return UVWASI_EINVAL;
if (dst == src)
return UVWASI_ESUCCESS;
uv_rwlock_wrlock(&table->rwlock);
if (dst >= table->size || src >= table->size) {
err = UVWASI_EBADF;
goto exit;
}
dst_entry = table->fds[dst];
src_entry = table->fds[src];
if (dst_entry == NULL || dst_entry->id != dst ||
src_entry == NULL || src_entry->id != src) {
err = UVWASI_EBADF;
goto exit;
}
uv_mutex_lock(&dst_entry->mutex);
uv_mutex_lock(&src_entry->mutex);
/* Close the existing destination descriptor. */
r = uv_fs_close(NULL, &req, dst_entry->fd, NULL);
uv_fs_req_cleanup(&req);
if (r != 0) {
uv_mutex_unlock(&src_entry->mutex);
uv_mutex_unlock(&dst_entry->mutex);
err = uvwasi__translate_uv_error(r);
goto exit;
}
/* Move the source entry to the destination slot in the table. */
table->fds[dst] = table->fds[src];
table->fds[dst]->id = dst;
uv_mutex_unlock(&table->fds[dst]->mutex);
table->fds[src] = NULL;
table->used--;
/* Clean up what's left of the old destination entry. */
uv_mutex_unlock(&dst_entry->mutex);
uv_mutex_destroy(&dst_entry->mutex);
uvwasi__free(uvwasi, dst_entry);
err = UVWASI_ESUCCESS;
exit:
uv_rwlock_wrunlock(&table->rwlock);
return err;
}
uvwasi_errno_t uvwasi_fd_table_lock(struct uvwasi_fd_table_t* table) {
if (table == NULL)
return UVWASI_EINVAL;
uv_rwlock_wrlock(&table->rwlock);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_fd_table_unlock(struct uvwasi_fd_table_t* table) {
if (table == NULL)
return UVWASI_EINVAL;
uv_rwlock_wrunlock(&table->rwlock);
return UVWASI_ESUCCESS;
}

75
deps/uvwasi/src/fd_table.h vendored Normal file
View File

@ -0,0 +1,75 @@
#ifndef __UVWASI_FD_TABLE_H__
#define __UVWASI_FD_TABLE_H__
#include <stdint.h>
#include "uv.h"
#include "wasi_types.h"
struct uvwasi_s;
struct uvwasi_options_s;
struct uvwasi_fd_wrap_t {
uvwasi_fd_t id;
uv_file fd;
uv_tcp_t* sock;
char* path;
char* real_path;
char* normalized_path;
uvwasi_filetype_t type;
uvwasi_rights_t rights_base;
uvwasi_rights_t rights_inheriting;
int preopen;
uv_mutex_t mutex;
};
struct uvwasi_fd_table_t {
struct uvwasi_fd_wrap_t** fds;
uint32_t size;
uint32_t used;
uv_rwlock_t rwlock;
};
uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_s* uvwasi,
const struct uvwasi_options_s* options);
void uvwasi_fd_table_free(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table);
uvwasi_errno_t uvwasi_fd_table_insert(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
uv_file fd,
uv_tcp_t* sock,
const char* mapped_path,
const char* real_path,
uvwasi_filetype_t type,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting,
int preopen,
struct uvwasi_fd_wrap_t** wrap);
uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
const uv_file fd,
const char* path,
const char* real_path);
uvwasi_errno_t uvwasi_fd_table_insert_preopen_socket(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
uv_tcp_t* sock);
uvwasi_errno_t uvwasi_fd_table_get(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id,
struct uvwasi_fd_wrap_t** wrap,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting);
uvwasi_errno_t uvwasi_fd_table_get_nolock(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id,
struct uvwasi_fd_wrap_t** wrap,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting);
uvwasi_errno_t uvwasi_fd_table_remove_nolock(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id);
uvwasi_errno_t uvwasi_fd_table_renumber(struct uvwasi_s* uvwasi,
struct uvwasi_fd_table_t* table,
const uvwasi_fd_t dst,
const uvwasi_fd_t src);
uvwasi_errno_t uvwasi_fd_table_lock(struct uvwasi_fd_table_t* table);
uvwasi_errno_t uvwasi_fd_table_unlock(struct uvwasi_fd_table_t* table);
#endif /* __UVWASI_FD_TABLE_H__ */

558
deps/uvwasi/src/path_resolver.c vendored Normal file
View File

@ -0,0 +1,558 @@
#include <string.h>
#include "uv.h"
#include "uvwasi.h"
#include "uvwasi_alloc.h"
#include "uv_mapping.h"
#include "path_resolver.h"
#define UVWASI__MAX_SYMLINK_FOLLOWS 32
#ifndef _WIN32
# define IS_SLASH(c) ((c) == '/')
#else
# define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#endif /* _WIN32 */
static int uvwasi__is_absolute_path(const char* path, uvwasi_size_t path_len) {
/* It's expected that only Unix style paths will be generated by WASI. */
return path != NULL && path_len > 0 && path[0] == '/';
}
static char* uvwasi__strchr_slash(const char* s) {
/* strchr() that identifies /, as well as \ on Windows. */
do {
if (IS_SLASH(*s))
return (char*) s;
} while (*s++);
return NULL;
}
static uvwasi_errno_t uvwasi__combine_paths(const uvwasi_t* uvwasi,
const char* path1,
uvwasi_size_t path1_len,
const char* path2,
uvwasi_size_t path2_len,
char** combined_path,
uvwasi_size_t* combined_len) {
/* This function joins two paths with '/'. */
uvwasi_errno_t err;
char* combined;
int combined_size;
int r;
*combined_path = NULL;
*combined_len = 0;
/* The max combined size is the path1 length + the path2 length
+ 2 for a terminating NULL and a possible path separator. */
combined_size = path1_len + path2_len + 2;
combined = uvwasi__malloc(uvwasi, combined_size);
if (combined == NULL) return UVWASI_ENOMEM;
r = snprintf(combined, combined_size, "%s/%s", path1, path2);
if (r <= 0) {
err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
goto exit;
}
err = UVWASI_ESUCCESS;
*combined_path = combined;
*combined_len = strlen(combined);
exit:
if (err != UVWASI_ESUCCESS) uvwasi__free(uvwasi, combined);
return err;
}
uvwasi_errno_t uvwasi__normalize_path(const char* path,
uvwasi_size_t path_len,
char* normalized_path,
uvwasi_size_t normalized_len) {
const char* cur;
char* ptr;
char* next;
char* last;
size_t cur_len;
int is_absolute;
if (path_len > normalized_len)
return UVWASI_ENOBUFS;
is_absolute = uvwasi__is_absolute_path(path, path_len);
normalized_path[0] = '\0';
ptr = normalized_path;
for (cur = path; cur != NULL; cur = next + 1) {
next = uvwasi__strchr_slash(cur);
cur_len = (next == NULL) ? strlen(cur) : (size_t) (next - cur);
if (cur_len == 0) {
if (ptr == normalized_path && next != NULL && is_absolute) {
*ptr = '/';
ptr++;
}
*ptr = '\0';
} else if (cur_len == 1 && cur[0] == '.') {
/* No-op. Just consume the '.' */
} else if (cur_len == 2 && cur[0] == '.' && cur[1] == '.') {
/* Identify the path segment that preceded the current one. */
last = ptr;
while (!IS_SLASH(*last) && last != normalized_path) {
last--;
}
/* If the result is currently empty, or the last prior path is also '..'
then output '..'. Otherwise, remove the last path segment. */
if (ptr == normalized_path ||
(last == ptr - 2 && last[0] == '.' && last[1] == '.') ||
(last == ptr - 3 && last[0] == '/' &&
last[1] == '.' && last[2] == '.')) {
if (ptr != normalized_path && *(ptr - 1) != '/') {
*ptr = '/';
ptr++;
}
*ptr = '.';
ptr++;
*ptr = '.';
ptr++;
} else {
/* Strip the last segment, but make sure not to strip the '/' if that
is the entire path. */
if (last == normalized_path && *last == '/')
ptr = last + 1;
else
ptr = last;
}
*ptr = '\0';
} else {
if (ptr != normalized_path && *(ptr - 1) != '/') {
*ptr = '/';
ptr++;
}
memcpy(ptr, cur, cur_len);
ptr += cur_len;
*ptr = '\0';
}
if (next == NULL)
break;
}
/* Normalized the path to the empty string. Return either '/' or '.'. */
if (ptr == normalized_path) {
if (1 == is_absolute)
*ptr = '/';
else
*ptr = '.';
ptr++;
*ptr = '\0';
}
return UVWASI_ESUCCESS;
}
static int uvwasi__is_path_sandboxed(const char* path,
uvwasi_size_t path_len,
const char* fd_path,
uvwasi_size_t fd_path_len) {
char* ptr;
int remaining_len;
if (1 == uvwasi__is_absolute_path(fd_path, fd_path_len))
return path == strstr(path, fd_path) ? 1 : 0;
/* Handle relative fds that normalized to '.' */
if (fd_path_len == 1 && fd_path[0] == '.') {
/* If the fd's path is '.', then any path does not begin with '..' is OK. */
if ((path_len == 2 && path[0] == '.' && path[1] == '.') ||
(path_len > 2 && path[0] == '.' && path[1] == '.' && path[2] == '/')) {
return 0;
}
return 1;
}
if (path != strstr(path, fd_path))
return 0;
/* Fail if the remaining path starts with '..', '../', '/..', or '/../'. */
ptr = (char*) path + fd_path_len;
remaining_len = path_len - fd_path_len;
if (remaining_len < 2)
return 1;
/* Strip a leading slash so the check is only for '..' and '../'. */
if (*ptr == '/') {
ptr++;
remaining_len--;
}
if ((remaining_len == 2 && ptr[0] == '.' && ptr[1] == '.') ||
(remaining_len > 2 && ptr[0] == '.' && ptr[1] == '.' && ptr[2] == '/')) {
return 0;
}
return 1;
}
static uvwasi_errno_t uvwasi__normalize_absolute_path(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
uvwasi_size_t path_len,
char** normalized_path,
uvwasi_size_t* normalized_len
) {
/* This function resolves an absolute path to the provided file descriptor.
If the file descriptor's path is relative, then this operation will fail
with UVWASI_ENOTCAPABLE since it doesn't make sense to resolve an absolute
path to a relative prefix. If the file desciptor's path is also absolute,
then we just need to verify that the normalized path still starts with
the file descriptor's path. */
uvwasi_errno_t err;
char* abs_path;
int abs_size;
*normalized_path = NULL;
*normalized_len = 0;
abs_size = path_len + 1;
abs_path = uvwasi__malloc(uvwasi, abs_size);
if (abs_path == NULL) {
err = UVWASI_ENOMEM;
goto exit;
}
/* Normalize the input path first. */
err = uvwasi__normalize_path(path, path_len, abs_path, path_len);
if (err != UVWASI_ESUCCESS)
goto exit;
/* Once the input is normalized, ensure that it is still sandboxed. */
if (0 == uvwasi__is_path_sandboxed(abs_path,
path_len,
fd->normalized_path,
strlen(fd->normalized_path))) {
err = UVWASI_ENOTCAPABLE;
goto exit;
}
*normalized_path = abs_path;
*normalized_len = abs_size - 1;
return UVWASI_ESUCCESS;
exit:
uvwasi__free(uvwasi, abs_path);
return err;
}
static uvwasi_errno_t uvwasi__normalize_relative_path(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
uvwasi_size_t path_len,
char** normalized_path,
uvwasi_size_t* normalized_len
) {
/* This function resolves a relative path to the provided file descriptor.
The relative path is concatenated to the file descriptor's path, and then
normalized. */
uvwasi_errno_t err;
char* combined;
char* normalized = NULL;
uvwasi_size_t combined_len;
uvwasi_size_t fd_path_len;
uvwasi_size_t norm_len;
*normalized_path = NULL;
*normalized_len = 0;
fd_path_len = strlen(fd->normalized_path);
err = uvwasi__combine_paths(uvwasi,
fd->normalized_path,
fd_path_len,
path,
path_len,
&combined,
&combined_len);
if (err != UVWASI_ESUCCESS) goto exit;
normalized = uvwasi__malloc(uvwasi, combined_len + 1);
if (normalized == NULL) {
err = UVWASI_ENOMEM;
goto exit;
}
/* Normalize the input path. */
err = uvwasi__normalize_path(combined,
combined_len,
normalized,
combined_len);
if (err != UVWASI_ESUCCESS)
goto exit;
norm_len = strlen(normalized);
/* Once the path is normalized, ensure that it is still sandboxed. */
if (0 == uvwasi__is_path_sandboxed(normalized,
norm_len,
fd->normalized_path,
fd_path_len)) {
err = UVWASI_ENOTCAPABLE;
goto exit;
}
err = UVWASI_ESUCCESS;
*normalized_path = normalized;
*normalized_len = norm_len;
exit:
if (err != UVWASI_ESUCCESS)
uvwasi__free(uvwasi, normalized);
uvwasi__free(uvwasi, combined);
return err;
}
static uvwasi_errno_t uvwasi__resolve_path_to_host(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
uvwasi_size_t path_len,
char** resolved_path,
uvwasi_size_t* resolved_len
) {
/* Return the normalized path, but resolved to the host's real path. */
char* res_path;
char* stripped_path;
int real_path_len;
int fake_path_len;
int stripped_len;
#ifdef _WIN32
uvwasi_size_t i;
#endif /* _WIN32 */
real_path_len = strlen(fd->real_path);
fake_path_len = strlen(fd->normalized_path);
/* If the fake path is '.' just ignore it. */
if (fake_path_len == 1 && fd->normalized_path[0] == '.') {
fake_path_len = 0;
}
stripped_len = path_len - fake_path_len;
/* The resolved path's length is calculated as: the length of the fd's real
path, + 1 for a path separator, and the length of the input path (with the
fake path stripped off). */
*resolved_len = stripped_len + real_path_len + 1;
*resolved_path = uvwasi__malloc(uvwasi, *resolved_len + 1);
if (*resolved_path == NULL)
return UVWASI_ENOMEM;
res_path = *resolved_path;
stripped_path = (char*) path + fake_path_len;
memcpy(res_path, fd->real_path, real_path_len);
res_path += real_path_len;
if (stripped_len > 1 ||
(stripped_len == 1 && stripped_path[0] != '/')) {
if (stripped_path[0] != '/') {
*res_path = '/';
res_path++;
}
memcpy(res_path, stripped_path, stripped_len);
res_path += stripped_len;
}
*res_path = '\0';
#ifdef _WIN32
/* Replace / with \ on Windows. */
res_path = *resolved_path;
for (i = real_path_len; i < *resolved_len; i++) {
if (res_path[i] == '/')
res_path[i] = '\\';
}
#endif /* _WIN32 */
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
uvwasi_size_t path_len,
char** resolved_path,
uvwasi_lookupflags_t flags) {
uv_fs_t req;
uvwasi_errno_t err;
const char* input;
char* host_path;
char* normalized_path;
char* link_target;
char* normalized_parent;
char* resolved_link_target;
uvwasi_size_t input_len;
uvwasi_size_t host_path_len;
uvwasi_size_t normalized_len;
uvwasi_size_t link_target_len;
uvwasi_size_t normalized_parent_len;
uvwasi_size_t resolved_link_target_len;
int follow_count;
int r;
input = path;
input_len = path_len;
link_target = NULL;
follow_count = 0;
host_path = NULL;
normalized_parent = NULL;
resolved_link_target = NULL;
start:
normalized_path = NULL;
err = UVWASI_ESUCCESS;
if (1 == uvwasi__is_absolute_path(input, input_len)) {
err = uvwasi__normalize_absolute_path(uvwasi,
fd,
input,
input_len,
&normalized_path,
&normalized_len);
} else {
err = uvwasi__normalize_relative_path(uvwasi,
fd,
input,
input_len,
&normalized_path,
&normalized_len);
}
if (err != UVWASI_ESUCCESS)
goto exit;
uvwasi__free(uvwasi, host_path);
err = uvwasi__resolve_path_to_host(uvwasi,
fd,
normalized_path,
normalized_len,
&host_path,
&host_path_len);
if (err != UVWASI_ESUCCESS)
goto exit;
if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
r = uv_fs_readlink(NULL, &req, host_path, NULL);
if (r != 0) {
#ifdef _WIN32
/* uv_fs_readlink() returns UV__UNKNOWN on Windows. Try to get a better
error using uv_fs_stat(). */
if (r == UV__UNKNOWN) {
uv_fs_req_cleanup(&req);
r = uv_fs_stat(NULL, &req, host_path, NULL);
if (r == 0) {
if (uvwasi__stat_to_filetype(&req.statbuf) !=
UVWASI_FILETYPE_SYMBOLIC_LINK) {
r = UV_EINVAL;
}
}
/* Fall through. */
}
#endif /* _WIN32 */
/* Don't report UV_EINVAL or UV_ENOENT. They mean that either the file
does not exist, or it is not a symlink. Both are OK. */
if (r != UV_EINVAL && r != UV_ENOENT)
err = uvwasi__translate_uv_error(r);
uv_fs_req_cleanup(&req);
goto exit;
}
/* Clean up memory and follow the link, unless it's time to return ELOOP. */
follow_count++;
if (follow_count >= UVWASI__MAX_SYMLINK_FOLLOWS) {
uv_fs_req_cleanup(&req);
err = UVWASI_ELOOP;
goto exit;
}
link_target_len = strlen(req.ptr);
uvwasi__free(uvwasi, link_target);
link_target = uvwasi__malloc(uvwasi, link_target_len + 1);
if (link_target == NULL) {
uv_fs_req_cleanup(&req);
err = UVWASI_ENOMEM;
goto exit;
}
memcpy(link_target, req.ptr, link_target_len + 1);
uv_fs_req_cleanup(&req);
if (1 == uvwasi__is_absolute_path(link_target, link_target_len)) {
input = link_target;
input_len = link_target_len;
} else {
uvwasi__free(uvwasi, normalized_parent);
uvwasi__free(uvwasi, resolved_link_target);
err = uvwasi__combine_paths(uvwasi,
normalized_path,
normalized_len,
"..",
2,
&normalized_parent,
&normalized_parent_len);
if (err != UVWASI_ESUCCESS) goto exit;
err = uvwasi__combine_paths(uvwasi,
normalized_parent,
normalized_parent_len,
link_target,
link_target_len,
&resolved_link_target,
&resolved_link_target_len);
if (err != UVWASI_ESUCCESS) goto exit;
input = resolved_link_target;
input_len = resolved_link_target_len;
}
uvwasi__free(uvwasi, normalized_path);
goto start;
}
exit:
if (err == UVWASI_ESUCCESS) {
*resolved_path = host_path;
} else {
*resolved_path = NULL;
uvwasi__free(uvwasi, host_path);
}
uvwasi__free(uvwasi, link_target);
uvwasi__free(uvwasi, normalized_path);
uvwasi__free(uvwasi, normalized_parent);
uvwasi__free(uvwasi, resolved_link_target);
return err;
}

19
deps/uvwasi/src/path_resolver.h vendored Normal file
View File

@ -0,0 +1,19 @@
#ifndef __UVWASI_PATH_RESOLVER_H__
#define __UVWASI_PATH_RESOLVER_H__
#include "fd_table.h"
#include "uvwasi.h"
uvwasi_errno_t uvwasi__normalize_path(const char* path,
uvwasi_size_t path_len,
char* normalized_path,
uvwasi_size_t normalized_len);
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
uvwasi_size_t path_len,
char** resolved_path,
uvwasi_lookupflags_t flags);
#endif /* __UVWASI_PATH_RESOLVER_H__ */

269
deps/uvwasi/src/poll_oneoff.c vendored Normal file
View File

@ -0,0 +1,269 @@
#include "uv.h"
#include "poll_oneoff.h"
#include "uv_mapping.h"
#include "uvwasi_alloc.h"
static void poll_cb(uv_poll_t* handle, int status, int events) {
struct uvwasi_poll_oneoff_state_t* state;
struct uvwasi__poll_fdevent_t* event;
uv_poll_stop(handle);
event = uv_handle_get_data((uv_handle_t*) handle);
event->revents = events;
if (status != 0)
event->error = UVWASI_EIO;
state = uv_loop_get_data(handle->loop);
state->result++;
}
static void timeout_cb(uv_timer_t* handle) {
struct uvwasi_poll_oneoff_state_t* state;
uvwasi_size_t i;
state = uv_loop_get_data(handle->loop);
for (i = 0; i < state->handle_cnt; i++)
uv_poll_stop(&state->poll_handles[i]);
}
uvwasi_errno_t uvwasi__poll_oneoff_state_init(
uvwasi_t* uvwasi,
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_size_t max_fds
) {
uvwasi_errno_t err;
int r;
if (uvwasi == NULL || state == NULL)
return UVWASI_EINVAL;
state->uvwasi = NULL;
state->timeout = 0;
state->has_timer = 0;
state->fdevents = NULL;
state->poll_handles = NULL;
state->max_fds = 0;
state->fdevent_cnt = 0;
state->handle_cnt = 0;
state->result = 0;
r = uv_loop_init(&state->loop);
if (r != 0)
return uvwasi__translate_uv_error(r);
if (max_fds > 0) {
state->fdevents = uvwasi__calloc(uvwasi,
max_fds,
sizeof(*state->fdevents));
if (state->fdevents == NULL) {
err = UVWASI_ENOMEM;
goto error_exit;
}
state->poll_handles = uvwasi__calloc(uvwasi,
max_fds,
sizeof(*state->poll_handles));
if (state->poll_handles == NULL) {
err = UVWASI_ENOMEM;
goto error_exit;
}
}
uv_loop_set_data(&state->loop, (void*) state);
state->uvwasi = uvwasi;
state->max_fds = max_fds;
return UVWASI_ESUCCESS;
error_exit:
uv_loop_close(&state->loop);
uvwasi__free(state->uvwasi, state->fdevents);
uvwasi__free(state->uvwasi, state->poll_handles);
return err;
}
uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
struct uvwasi_poll_oneoff_state_t* state
) {
struct uvwasi__poll_fdevent_t* event;
uvwasi_size_t i;
int r;
if (state == NULL)
return UVWASI_EINVAL;
if (state->has_timer != 0) {
state->timeout = 0;
state->has_timer = 0;
uv_close((uv_handle_t*) &state->timer, NULL);
}
for (i = 0; i < state->fdevent_cnt; i++) {
event = &state->fdevents[i];
if (event->is_duplicate_fd == 0 && event->wrap != NULL)
uv_mutex_unlock(&event->wrap->mutex);
}
for (i = 0; i < state->handle_cnt; i++)
uv_close((uv_handle_t*) &state->poll_handles[i], NULL);
uv_run(&state->loop, UV_RUN_NOWAIT);
state->max_fds = 0;
state->fdevent_cnt = 0;
state->handle_cnt = 0;
uvwasi__free(state->uvwasi, state->fdevents);
uvwasi__free(state->uvwasi, state->poll_handles);
state->fdevents = NULL;
state->poll_handles = NULL;
state->uvwasi = NULL;
r = uv_loop_close(&state->loop);
if (r != 0)
return uvwasi__translate_uv_error(r);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_timestamp_t timeout
) {
int r;
if (state == NULL)
return UVWASI_EINVAL;
r = uv_timer_init(&state->loop, &state->timer);
if (r != 0)
return uvwasi__translate_uv_error(r);
/* Convert WASI timeout from nanoseconds to milliseconds for libuv. */
state->timeout = timeout / 1000000;
state->has_timer = 1;
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_subscription_t* subscription
) {
struct uvwasi__poll_fdevent_t* event;
struct uvwasi__poll_fdevent_t* dup;
uv_poll_t* poll_handle;
uvwasi_eventtype_t type;
uvwasi_rights_t rights;
uvwasi_fd_t fd;
uvwasi_errno_t err;
uvwasi_size_t i;
int r;
if (state == NULL)
return UVWASI_EINVAL;
event = &state->fdevents[state->fdevent_cnt];
fd = subscription->u.fd_readwrite.fd;
type = subscription->type;
if (type == UVWASI_EVENTTYPE_FD_READ) {
event->events = UV_DISCONNECT | UV_READABLE;
rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_READ;
} else if (type == UVWASI_EVENTTYPE_FD_WRITE) {
event->events = UV_DISCONNECT | UV_WRITABLE;
rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_WRITE;
} else {
return UVWASI_EINVAL;
}
/* Check if the same file descriptor is already being polled. If so, use the
wrap and poll handle from the first descriptor. The reasons are that libuv
does not support polling the same fd more than once at the same time, and
uvwasi has the fd's mutex locked. */
event->is_duplicate_fd = 0;
for (i = 0; i < state->fdevent_cnt; i++) {
dup = &state->fdevents[i];
if (dup->wrap->id == fd) {
event->is_duplicate_fd = 1;
event->wrap = dup->wrap;
event->poll_handle = dup->poll_handle;
err = event->error;
goto poll_config_done;
}
}
/* Get the file descriptor. If UVWASI_EBADF is returned, continue on, but
don't do any polling with the handle. */
err = uvwasi_fd_table_get(state->uvwasi->fds, fd, &event->wrap, rights, 0);
if (err == UVWASI_EBADF)
event->wrap = NULL;
else if (err != UVWASI_ESUCCESS)
return err;
if (err == UVWASI_ESUCCESS) {
/* The fd is valid, so setup the poll handle. */
poll_handle = &state->poll_handles[state->handle_cnt];
r = uv_poll_init(&state->loop, poll_handle, event->wrap->fd);
if (r != 0) {
/* If uv_poll_init() fails (for example on Windows because only sockets
are supported), set the error for this event to UVWASI_EBADF, but don't
do any polling with the handle. */
uv_mutex_unlock(&event->wrap->mutex);
return uvwasi__translate_uv_error(r);
} else {
r = uv_poll_start(poll_handle,
event->events,
poll_cb);
if (r != 0) {
uv_mutex_unlock(&event->wrap->mutex);
uv_close((uv_handle_t*) poll_handle, NULL);
return uvwasi__translate_uv_error(r);
}
uv_handle_set_data((uv_handle_t*) poll_handle,
(void*) &state->fdevents[state->fdevent_cnt]);
event->poll_handle = poll_handle;
state->handle_cnt++;
}
}
poll_config_done:
event->type = type;
event->userdata = subscription->userdata;
event->error = err;
event->revents = 0;
state->fdevent_cnt++;
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi__poll_oneoff_run(
struct uvwasi_poll_oneoff_state_t* state
) {
int r;
if (state->has_timer == 1) {
r = uv_timer_start(&state->timer, timeout_cb, state->timeout, 0);
if (r != 0)
return uvwasi__translate_uv_error(r);
if (state->fdevent_cnt > 0)
uv_unref((uv_handle_t*) &state->timer);
}
r = uv_run(&state->loop, UV_RUN_DEFAULT);
if (r != 0)
return uvwasi__translate_uv_error(r);
return UVWASI_ESUCCESS;
}

60
deps/uvwasi/src/poll_oneoff.h vendored Normal file
View File

@ -0,0 +1,60 @@
#ifndef __UVWASI_POLL_ONEOFF_H__
#define __UVWASI_POLL_ONEOFF_H__
#include "fd_table.h"
#include "wasi_types.h"
struct uvwasi_s;
struct uvwasi__poll_fdevent_t {
struct uvwasi_fd_wrap_t* wrap;
uvwasi_userdata_t userdata;
uvwasi_eventtype_t type;
uvwasi_errno_t error;
uv_poll_t* poll_handle;
int is_duplicate_fd;
int events;
int revents;
};
struct uvwasi_poll_oneoff_state_t {
struct uvwasi_s* uvwasi;
struct uvwasi__poll_fdevent_t* fdevents;
uv_poll_t* poll_handles;
uv_timer_t timer;
uint64_t timeout;
uv_loop_t loop;
uvwasi_size_t max_fds;
int has_timer;
uvwasi_size_t fdevent_cnt;
uvwasi_size_t handle_cnt;
int result;
};
uvwasi_errno_t uvwasi__poll_oneoff_state_init(
struct uvwasi_s* uvwasi,
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_size_t max_fds
);
uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
struct uvwasi_poll_oneoff_state_t* state
);
uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_timestamp_t timeout
);
uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
struct uvwasi_poll_oneoff_state_t* state,
uvwasi_subscription_t* subscription
);
uvwasi_errno_t uvwasi__poll_oneoff_run(
struct uvwasi_poll_oneoff_state_t* state
);
#endif /* __UVWASI_POLL_ONEOFF_H__ */

95
deps/uvwasi/src/sync_helpers.c vendored Normal file
View File

@ -0,0 +1,95 @@
#include "uv.h"
#include "sync_helpers.h"
#include "uv_mapping.h"
#include "uvwasi_alloc.h"
typedef struct free_handle_data_s {
uvwasi_t* uvwasi;
int done;
} free_handle_data_t;
static void free_handle_cb(uv_handle_t* handle) {
free_handle_data_t* free_handle_data = uv_handle_get_data((uv_handle_t*) handle);
uvwasi__free(free_handle_data->uvwasi, handle);
free_handle_data->done = 1;
}
int free_handle_sync(struct uvwasi_s* uvwasi, uv_handle_t* handle) {
free_handle_data_t free_handle_data = { uvwasi, 0 };
uv_handle_set_data(handle, (void*) &free_handle_data);
uv_close(handle, free_handle_cb);
uv_loop_t* handle_loop = uv_handle_get_loop(handle);
while(!free_handle_data.done) {
if (uv_run(handle_loop, UV_RUN_ONCE) == 0) {
break;
}
}
return UVWASI_ESUCCESS;
}
static void do_stream_shutdown(uv_shutdown_t* req, int status) {
shutdown_data_t* shutdown_data;
shutdown_data = uv_handle_get_data((uv_handle_t*) req->handle);
shutdown_data->status = status;
shutdown_data->done = 1;
}
int shutdown_stream_sync(struct uvwasi_s* uvwasi,
uv_stream_t* stream,
shutdown_data_t* shutdown_data) {
uv_shutdown_t req;
uv_loop_t* stream_loop;
shutdown_data->done = 0;
shutdown_data->status = 0;
stream_loop = uv_handle_get_loop((uv_handle_t*) stream);
uv_handle_set_data((uv_handle_t*) stream, (void*) shutdown_data);
uv_shutdown(&req, stream, do_stream_shutdown);
while (!shutdown_data->done) {
if (uv_run(stream_loop, UV_RUN_ONCE) == 0) {
return UVWASI_ECANCELED;
}
}
return UVWASI_ESUCCESS;
}
static void recv_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
recv_data_t* recv_data;
recv_data = uv_handle_get_data(handle);
buf->base = recv_data->base;
buf->len = recv_data->len;
}
void do_stream_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
recv_data_t* recv_data;
recv_data = uv_handle_get_data((uv_handle_t*) stream);
uv_read_stop(stream);
recv_data->nread = nread;
recv_data->done = 1;
}
int read_stream_sync(struct uvwasi_s* uvwasi,
uv_stream_t* stream,
recv_data_t* recv_data) {
uv_loop_t* recv_loop;
int r;
recv_data->nread = 0;
recv_data->done = 0;
recv_loop = uv_handle_get_loop((uv_handle_t*) stream);
uv_handle_set_data((uv_handle_t*) stream, (void*) recv_data);
r = uv_read_start(stream, recv_alloc_cb, do_stream_recv);
if (r != 0) {
return uvwasi__translate_uv_error(r);
}
while (!recv_data->done) {
if (uv_run(recv_loop, UV_RUN_ONCE) == 0) {
return UVWASI_ECANCELED;
}
}
return UVWASI_ESUCCESS;
}

27
deps/uvwasi/src/sync_helpers.h vendored Normal file
View File

@ -0,0 +1,27 @@
#ifndef __UVWASI_SYNC_HELPERS_H__
#define __UVWASI_SYNC_HELPERS_H__
struct uvwasi_s;
typedef struct shutdown_data_s {
int status;
int done;
} shutdown_data_t;
typedef struct recv_data_s {
char* base;
size_t len;
ssize_t nread;
int done;
} recv_data_t;
int free_handle_sync(struct uvwasi_s* uvwasi, uv_handle_t* handle);
int shutdown_stream_sync(struct uvwasi_s* uvwasi,
uv_stream_t* stream,
shutdown_data_t* shutdown_data);
int read_stream_sync(struct uvwasi_s* uvwasi,
uv_stream_t* stream,
recv_data_t* recv_data);
#endif /* __UVWASI_SYNC_HELPERS_H__ */

282
deps/uvwasi/src/uv_mapping.c vendored Normal file
View File

@ -0,0 +1,282 @@
#include <sys/stat.h>
#ifndef _WIN32
# include <sys/types.h>
#endif /* _WIN32 */
#include "uv.h"
#include "wasi_types.h"
#include "uv_mapping.h"
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISCHR) && defined(S_IFMT) && defined(S_IFCHR)
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISLNK) && defined(S_IFMT) && defined(S_IFLNK)
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISFIFO) && defined(S_IFMT) && defined(S_IFIFO)
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
uvwasi_errno_t uvwasi__translate_uv_error(int err) {
switch (err) {
case UV_E2BIG: return UVWASI_E2BIG;
case UV_EACCES: return UVWASI_EACCES;
case UV_EADDRINUSE: return UVWASI_EADDRINUSE;
case UV_EADDRNOTAVAIL: return UVWASI_EADDRNOTAVAIL;
case UV_EAFNOSUPPORT: return UVWASI_EAFNOSUPPORT;
case UV_EAGAIN: return UVWASI_EAGAIN;
case UV_EALREADY: return UVWASI_EALREADY;
case UV_EBADF: return UVWASI_EBADF;
case UV_EBUSY: return UVWASI_EBUSY;
case UV_ECANCELED: return UVWASI_ECANCELED;
case UV_ECONNABORTED: return UVWASI_ECONNABORTED;
case UV_ECONNREFUSED: return UVWASI_ECONNREFUSED;
case UV_ECONNRESET: return UVWASI_ECONNRESET;
case UV_EDESTADDRREQ: return UVWASI_EDESTADDRREQ;
case UV_EEXIST: return UVWASI_EEXIST;
case UV_EFAULT: return UVWASI_EFAULT;
case UV_EFBIG: return UVWASI_EFBIG;
case UV_EHOSTUNREACH: return UVWASI_EHOSTUNREACH;
case UV_EINTR: return UVWASI_EINTR;
case UV_EINVAL: return UVWASI_EINVAL;
case UV_EIO: return UVWASI_EIO;
case UV_EISCONN: return UVWASI_EISCONN;
case UV_EISDIR: return UVWASI_EISDIR;
case UV_ELOOP: return UVWASI_ELOOP;
case UV_EMFILE: return UVWASI_EMFILE;
case UV_EMLINK: return UVWASI_EMLINK;
case UV_EMSGSIZE: return UVWASI_EMSGSIZE;
case UV_ENAMETOOLONG: return UVWASI_ENAMETOOLONG;
case UV_ENETDOWN: return UVWASI_ENETDOWN;
case UV_ENETUNREACH: return UVWASI_ENETUNREACH;
case UV_ENFILE: return UVWASI_ENFILE;
case UV_ENOBUFS: return UVWASI_ENOBUFS;
case UV_ENODEV: return UVWASI_ENODEV;
case UV_ENOENT: return UVWASI_ENOENT;
case UV_ENOMEM: return UVWASI_ENOMEM;
case UV_ENOPROTOOPT: return UVWASI_ENOPROTOOPT;
case UV_ENOSPC: return UVWASI_ENOSPC;
case UV_ENOSYS: return UVWASI_ENOSYS;
case UV_ENOTCONN: return UVWASI_ENOTCONN;
case UV_ENOTDIR: return UVWASI_ENOTDIR;
/* On at least some AIX machines, ENOTEMPTY and EEXIST are equivalent. */
#if ENOTEMPTY != EEXIST
case UV_ENOTEMPTY: return UVWASI_ENOTEMPTY;
#endif /* ENOTEMPTY != EEXIST */
case UV_ENOTSOCK: return UVWASI_ENOTSOCK;
case UV_ENOTSUP: return UVWASI_ENOTSUP;
case UV_ENXIO: return UVWASI_ENXIO;
case UV_EPERM: return UVWASI_EPERM;
case UV_EPIPE: return UVWASI_EPIPE;
case UV_EPROTO: return UVWASI_EPROTO;
case UV_EPROTONOSUPPORT: return UVWASI_EPROTONOSUPPORT;
case UV_EPROTOTYPE: return UVWASI_EPROTOTYPE;
case UV_ERANGE: return UVWASI_ERANGE;
case UV_EROFS: return UVWASI_EROFS;
case UV_ESPIPE: return UVWASI_ESPIPE;
case UV_ESRCH: return UVWASI_ESRCH;
case UV_ETIMEDOUT: return UVWASI_ETIMEDOUT;
case UV_ETXTBSY: return UVWASI_ETXTBSY;
case UV_EXDEV: return UVWASI_EXDEV;
case 0: return UVWASI_ESUCCESS;
/* The following libuv error codes have no corresponding WASI error code:
UV_EAI_ADDRFAMILY, UV_EAI_AGAIN, UV_EAI_BADFLAGS, UV_EAI_BADHINTS,
UV_EAI_CANCELED, UV_EAI_FAIL, UV_EAI_FAMILY, UV_EAI_MEMORY,
UV_EAI_NODATA, UV_EAI_NONAME, UV_EAI_OVERFLOW, UV_EAI_PROTOCOL,
UV_EAI_SERVICE, UV_EAI_SOCKTYPE, UV_ECHARSET, UV_ENONET, UV_EOF,
UV_ESHUTDOWN, UV_UNKNOWN
*/
default:
/* libuv errors are < 0 */
if (err > 0)
return err;
return UVWASI_ENOSYS;
}
}
int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig) {
switch (sig) {
#ifdef SIGABRT
case UVWASI_SIGABRT: return SIGABRT;
#endif
#ifdef SIGALRM
case UVWASI_SIGALRM: return SIGALRM;
#endif
#ifdef SIGBUS
case UVWASI_SIGBUS: return SIGBUS;
#endif
#ifdef SIGCHLD
case UVWASI_SIGCHLD: return SIGCHLD;
#endif
#ifdef SIGCONT
case UVWASI_SIGCONT: return SIGCONT;
#endif
#ifdef SIGFPE
case UVWASI_SIGFPE: return SIGFPE;
#endif
#ifdef SIGHUP
case UVWASI_SIGHUP: return SIGHUP;
#endif
#ifdef SIGILL
case UVWASI_SIGILL: return SIGILL;
#endif
#ifdef SIGINT
case UVWASI_SIGINT: return SIGINT;
#endif
#ifdef SIGKILL
case UVWASI_SIGKILL: return SIGKILL;
#endif
#ifdef SIGPIPE
case UVWASI_SIGPIPE: return SIGPIPE;
#endif
#ifdef SIGQUIT
case UVWASI_SIGQUIT: return SIGQUIT;
#endif
#ifdef SIGSEGV
case UVWASI_SIGSEGV: return SIGSEGV;
#endif
#ifdef SIGSTOP
case UVWASI_SIGSTOP: return SIGSTOP;
#endif
#ifdef SIGSYS
case UVWASI_SIGSYS: return SIGSYS;
#endif
#ifdef SIGTERM
case UVWASI_SIGTERM: return SIGTERM;
#endif
#ifdef SIGTRAP
case UVWASI_SIGTRAP: return SIGTRAP;
#endif
#ifdef SIGTSTP
case UVWASI_SIGTSTP: return SIGTSTP;
#endif
#ifdef SIGTTIN
case UVWASI_SIGTTIN: return SIGTTIN;
#endif
#ifdef SIGTTOU
case UVWASI_SIGTTOU: return SIGTTOU;
#endif
#ifdef SIGURG
case UVWASI_SIGURG: return SIGURG;
#endif
#ifdef SIGUSR1
case UVWASI_SIGUSR1: return SIGUSR1;
#endif
#ifdef SIGUSR2
case UVWASI_SIGUSR2: return SIGUSR2;
#endif
#ifdef SIGVTALRM
case UVWASI_SIGVTALRM: return SIGVTALRM;
#endif
#ifdef SIGXCPU
case UVWASI_SIGXCPU: return SIGXCPU;
#endif
#ifdef SIGXFSZ
case UVWASI_SIGXFSZ: return SIGXFSZ;
#endif
default: return -1;
}
}
uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts) {
/* TODO(cjihrig): Handle overflow. */
return (uvwasi_timestamp_t) ts->tv_sec * NANOS_PER_SEC + ts->tv_nsec;
}
uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat) {
uint64_t mode;
mode = stat->st_mode;
if (S_ISREG(mode))
return UVWASI_FILETYPE_REGULAR_FILE;
if (S_ISDIR(mode))
return UVWASI_FILETYPE_DIRECTORY;
if (S_ISCHR(mode))
return UVWASI_FILETYPE_CHARACTER_DEVICE;
if (S_ISLNK(mode))
return UVWASI_FILETYPE_SYMBOLIC_LINK;
#ifdef S_ISSOCK
if (S_ISSOCK(mode))
return UVWASI_FILETYPE_SOCKET_STREAM;
#endif /* S_ISSOCK */
#ifdef S_ISFIFO
if (S_ISFIFO(mode))
return UVWASI_FILETYPE_SOCKET_STREAM;
#endif /* S_ISFIFO */
#ifdef S_ISBLK
if (S_ISBLK(mode))
return UVWASI_FILETYPE_BLOCK_DEVICE;
#endif /* S_ISBLK */
return UVWASI_FILETYPE_UNKNOWN;
}
void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) {
fs->st_dev = stat->st_dev;
fs->st_ino = stat->st_ino;
fs->st_nlink = stat->st_nlink;
fs->st_size = stat->st_size;
fs->st_filetype = uvwasi__stat_to_filetype(stat);
fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim);
fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim);
fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim);
}
uvwasi_errno_t uvwasi__get_filetype_by_fd(uv_file fd, uvwasi_filetype_t* type) {
uv_fs_t req;
int r;
r = uv_fs_fstat(NULL, &req, fd, NULL);
if (r != 0) {
uv_fs_req_cleanup(&req);
uv_handle_type guess;
/*
Windows can't stat a FILE_TYPE_CHAR, which is guessed
as UV_TTY in "ConsoleMode" or UV_FILE otherwise.
*/
guess = uv_guess_handle(fd);
if (guess == UV_TTY || guess == UV_FILE) {
*type = UVWASI_FILETYPE_CHARACTER_DEVICE;
return UVWASI_ESUCCESS;
}
*type = UVWASI_FILETYPE_UNKNOWN;
return uvwasi__translate_uv_error(r);
}
*type = uvwasi__stat_to_filetype(&req.statbuf);
uv_fs_req_cleanup(&req);
if (*type == UVWASI_FILETYPE_SOCKET_STREAM &&
uv_guess_handle(fd) == UV_UDP) {
*type = UVWASI_FILETYPE_SOCKET_DGRAM;
}
return UVWASI_ESUCCESS;
}

16
deps/uvwasi/src/uv_mapping.h vendored Normal file
View File

@ -0,0 +1,16 @@
#ifndef __UVWASI_UV_MAPPING_H__
#define __UVWASI_UV_MAPPING_H__
#include "uv.h"
#include "wasi_types.h"
#define NANOS_PER_SEC 1000000000
uvwasi_errno_t uvwasi__translate_uv_error(int err);
int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig);
uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts);
uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat);
void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs);
uvwasi_errno_t uvwasi__get_filetype_by_fd(uv_file fd, uvwasi_filetype_t* type);
#endif /* __UVWASI_UV_MAPPING_H__ */

2992
deps/uvwasi/src/uvwasi.c vendored Normal file

File diff suppressed because it is too large Load Diff

11
deps/uvwasi/src/uvwasi_alloc.h vendored Normal file
View File

@ -0,0 +1,11 @@
#ifndef __UVWASI_ALLOC_H__
#define __UVWASI_ALLOC_H__
#include "uvwasi.h"
void* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size);
void uvwasi__free(const uvwasi_t* uvwasi, void* ptr);
void* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size);
void* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size);
#endif

62
deps/uvwasi/src/wasi_rights.c vendored Normal file
View File

@ -0,0 +1,62 @@
#include "uv.h"
#include "wasi_rights.h"
#include "wasi_types.h"
uvwasi_errno_t uvwasi__get_rights(uv_file fd,
int flags,
uvwasi_filetype_t type,
uvwasi_rights_t* rights_base,
uvwasi_rights_t* rights_inheriting) {
int read_or_write_only;
if (type == UVWASI_FILETYPE_UNKNOWN)
return UVWASI_EINVAL;
switch (type) {
case UVWASI_FILETYPE_REGULAR_FILE:
*rights_base = UVWASI__RIGHTS_REGULAR_FILE_BASE;
*rights_inheriting = UVWASI__RIGHTS_REGULAR_FILE_INHERITING;
break;
case UVWASI_FILETYPE_DIRECTORY:
*rights_base = UVWASI__RIGHTS_DIRECTORY_BASE;
*rights_inheriting = UVWASI__RIGHTS_DIRECTORY_INHERITING;
break;
case UVWASI_FILETYPE_SOCKET_STREAM:
case UVWASI_FILETYPE_SOCKET_DGRAM:
*rights_base = UVWASI__RIGHTS_SOCKET_BASE;
*rights_inheriting = UVWASI__RIGHTS_SOCKET_INHERITING;
break;
case UVWASI_FILETYPE_CHARACTER_DEVICE:
if (uv_guess_handle(fd) == UV_TTY) {
*rights_base = UVWASI__RIGHTS_TTY_BASE;
*rights_inheriting = UVWASI__RIGHTS_TTY_INHERITING;
} else {
*rights_base = UVWASI__RIGHTS_CHARACTER_DEVICE_BASE;
*rights_inheriting = UVWASI__RIGHTS_CHARACTER_DEVICE_INHERITING;
}
break;
case UVWASI_FILETYPE_BLOCK_DEVICE:
*rights_base = UVWASI__RIGHTS_BLOCK_DEVICE_BASE;
*rights_inheriting = UVWASI__RIGHTS_BLOCK_DEVICE_INHERITING;
break;
default:
*rights_base = 0;
*rights_inheriting = 0;
}
/* Disable read/write bits depending on access mode. */
read_or_write_only = flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
if (read_or_write_only == UV_FS_O_RDONLY)
*rights_base &= ~UVWASI_RIGHT_FD_WRITE;
else if (read_or_write_only == UV_FS_O_WRONLY)
*rights_base &= ~UVWASI_RIGHT_FD_READ;
return UVWASI_ESUCCESS;
}

106
deps/uvwasi/src/wasi_rights.h vendored Normal file
View File

@ -0,0 +1,106 @@
#ifndef __UVWASI_WASI_RIGHTS_H__
#define __UVWASI_WASI_RIGHTS_H__
#include "wasi_types.h"
#define UVWASI__RIGHTS_ALL (UVWASI_RIGHT_FD_DATASYNC | \
UVWASI_RIGHT_FD_READ | \
UVWASI_RIGHT_FD_SEEK | \
UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
UVWASI_RIGHT_FD_SYNC | \
UVWASI_RIGHT_FD_TELL | \
UVWASI_RIGHT_FD_WRITE | \
UVWASI_RIGHT_FD_ADVISE | \
UVWASI_RIGHT_FD_ALLOCATE | \
UVWASI_RIGHT_PATH_CREATE_DIRECTORY | \
UVWASI_RIGHT_PATH_CREATE_FILE | \
UVWASI_RIGHT_PATH_LINK_SOURCE | \
UVWASI_RIGHT_PATH_LINK_TARGET | \
UVWASI_RIGHT_PATH_OPEN | \
UVWASI_RIGHT_FD_READDIR | \
UVWASI_RIGHT_PATH_READLINK | \
UVWASI_RIGHT_PATH_RENAME_SOURCE | \
UVWASI_RIGHT_PATH_RENAME_TARGET | \
UVWASI_RIGHT_PATH_FILESTAT_GET | \
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_PATH_SYMLINK | \
UVWASI_RIGHT_PATH_UNLINK_FILE | \
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
UVWASI_RIGHT_POLL_FD_READWRITE | \
UVWASI_RIGHT_SOCK_SHUTDOWN | \
UVWASI_RIGHT_SOCK_ACCEPT)
#define UVWASI__RIGHTS_BLOCK_DEVICE_BASE UVWASI__RIGHTS_ALL
#define UVWASI__RIGHTS_BLOCK_DEVICE_INHERITING UVWASI__RIGHTS_ALL
#define UVWASI__RIGHTS_CHARACTER_DEVICE_BASE UVWASI__RIGHTS_ALL
#define UVWASI__RIGHTS_CHARACTER_DEVICE_INHERITING UVWASI__RIGHTS_ALL
#define UVWASI__RIGHTS_REGULAR_FILE_BASE (UVWASI_RIGHT_FD_DATASYNC | \
UVWASI_RIGHT_FD_READ | \
UVWASI_RIGHT_FD_SEEK | \
UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
UVWASI_RIGHT_FD_SYNC | \
UVWASI_RIGHT_FD_TELL | \
UVWASI_RIGHT_FD_WRITE | \
UVWASI_RIGHT_FD_ADVISE | \
UVWASI_RIGHT_FD_ALLOCATE | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES |\
UVWASI_RIGHT_POLL_FD_READWRITE)
#define UVWASI__RIGHTS_REGULAR_FILE_INHERITING 0
#define UVWASI__RIGHTS_DIRECTORY_BASE (UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
UVWASI_RIGHT_FD_SYNC | \
UVWASI_RIGHT_FD_ADVISE | \
UVWASI_RIGHT_PATH_CREATE_DIRECTORY | \
UVWASI_RIGHT_PATH_CREATE_FILE | \
UVWASI_RIGHT_PATH_LINK_SOURCE | \
UVWASI_RIGHT_PATH_LINK_TARGET | \
UVWASI_RIGHT_PATH_OPEN | \
UVWASI_RIGHT_FD_READDIR | \
UVWASI_RIGHT_PATH_READLINK | \
UVWASI_RIGHT_PATH_RENAME_SOURCE | \
UVWASI_RIGHT_PATH_RENAME_TARGET | \
UVWASI_RIGHT_PATH_FILESTAT_GET | \
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_PATH_SYMLINK | \
UVWASI_RIGHT_PATH_UNLINK_FILE | \
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
UVWASI_RIGHT_POLL_FD_READWRITE)
#define UVWASI__RIGHTS_DIRECTORY_INHERITING (UVWASI__RIGHTS_DIRECTORY_BASE | \
UVWASI__RIGHTS_REGULAR_FILE_BASE)
#define UVWASI__RIGHTS_SOCKET_BASE (UVWASI_RIGHT_FD_READ | \
UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
UVWASI_RIGHT_FD_WRITE | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_POLL_FD_READWRITE | \
UVWASI_RIGHT_SOCK_SHUTDOWN | \
UVWASI_RIGHT_SOCK_ACCEPT)
#define UVWASI__RIGHTS_SOCKET_INHERITING UVWASI__RIGHTS_ALL
#define UVWASI__RIGHTS_TTY_BASE (UVWASI_RIGHT_FD_READ | \
UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
UVWASI_RIGHT_FD_WRITE | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_POLL_FD_READWRITE)
#define UVWASI__RIGHTS_TTY_INHERITING 0
uvwasi_errno_t uvwasi__get_rights(uv_file fd,
int flags,
uvwasi_filetype_t type,
uvwasi_rights_t* rights_base,
uvwasi_rights_t* rights_inheriting);
#endif /* __UVWASI_WASI_RIGHTS_H__ */

266
deps/uvwasi/src/wasi_serdes.c vendored Normal file
View File

@ -0,0 +1,266 @@
#include "wasi_serdes.h"
#include "wasi_types.h"
void uvwasi_serdes_write_uint64_t(void* ptr,
size_t offset,
uint64_t value) {
uvwasi_serdes_write_uint32_t(ptr, offset, (uint32_t) value);
uvwasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
}
void uvwasi_serdes_write_uint32_t(void* ptr,
size_t offset,
uint32_t value) {
uvwasi_serdes_write_uint16_t(ptr, offset, (uint16_t) value);
uvwasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
}
void uvwasi_serdes_write_uint16_t(void* ptr,
size_t offset,
uint16_t value) {
uvwasi_serdes_write_uint8_t(ptr, offset, (uint8_t) value);
uvwasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
}
void uvwasi_serdes_write_uint8_t(void* ptr,
size_t offset,
uint8_t value) {
((uint8_t*) ptr)[offset] = value;
}
uint64_t uvwasi_serdes_read_uint64_t(const void* ptr, size_t offset) {
uint64_t low = uvwasi_serdes_read_uint32_t(ptr, offset);
uint64_t high = uvwasi_serdes_read_uint32_t(ptr, offset + 4);
return low | (high << 32);
}
uint32_t uvwasi_serdes_read_uint32_t(const void* ptr, size_t offset) {
uint32_t low = uvwasi_serdes_read_uint16_t(ptr, offset);
uint32_t high = uvwasi_serdes_read_uint16_t(ptr, offset + 2);
return low | (high << 16);
}
uint16_t uvwasi_serdes_read_uint16_t(const void* ptr, size_t offset) {
uint16_t low = uvwasi_serdes_read_uint8_t(ptr, offset);
uint16_t high = uvwasi_serdes_read_uint8_t(ptr, offset + 1);
return low | (high << 8);
}
uint8_t uvwasi_serdes_read_uint8_t(const void* ptr, size_t offset) {
return ((const uint8_t*) ptr)[offset];
}
#define TYPE_SWITCH switch (value->type)
#define ALL_TYPES(STRUCT, FIELD, ALIAS) \
\
ALIAS(advice_t, uint8_t) \
ALIAS(clockid_t, uint32_t) \
ALIAS(device_t, uint64_t) \
ALIAS(dircookie_t, uint64_t) \
ALIAS(errno_t, uint16_t) \
ALIAS(eventrwflags_t, uint16_t) \
ALIAS(eventtype_t, uint8_t) \
ALIAS(exitcode_t, uint32_t) \
ALIAS(fd_t, uint32_t) \
ALIAS(fdflags_t, uint16_t) \
ALIAS(filesize_t, uint64_t) \
ALIAS(filetype_t, uint8_t) \
ALIAS(fstflags_t, uint16_t) \
ALIAS(inode_t, uint64_t) \
ALIAS(linkcount_t, uint64_t) \
ALIAS(lookupflags_t, uint32_t) \
ALIAS(oflags_t, uint16_t) \
ALIAS(preopentype_t, uint8_t) \
ALIAS(riflags_t, uint16_t) \
ALIAS(rights_t, uint64_t) \
ALIAS(roflags_t, uint16_t) \
ALIAS(sdflags_t, uint8_t) \
ALIAS(siflags_t, uint16_t) \
ALIAS(signal_t, uint8_t) \
ALIAS(size_t, uint32_t) \
ALIAS(subclockflags_t, uint16_t) \
ALIAS(timestamp_t, uint64_t) \
ALIAS(userdata_t, uint64_t) \
ALIAS(whence_t, uint8_t) \
\
STRUCT(dirent_t) { \
FIELD( 0, dircookie_t, d_next); \
FIELD( 8, inode_t, d_ino); \
FIELD(16, uint32_t, d_namlen); \
FIELD(20, filetype_t, d_type); \
} \
\
STRUCT(fdstat_t) { \
FIELD( 0, filetype_t, fs_filetype); \
FIELD( 2, fdflags_t, fs_flags); \
FIELD( 8, rights_t, fs_rights_base); \
FIELD(16, rights_t, fs_rights_inheriting); \
} \
\
STRUCT(filestat_t) { \
FIELD( 0, device_t, st_dev); \
FIELD( 8, inode_t, st_ino); \
FIELD(16, filetype_t, st_filetype); \
FIELD(24, linkcount_t, st_nlink); \
FIELD(32, filesize_t, st_size); \
FIELD(40, timestamp_t, st_atim); \
FIELD(48, timestamp_t, st_mtim); \
FIELD(56, timestamp_t, st_ctim); \
} \
\
STRUCT(prestat_t) { \
FIELD(0, preopentype_t, pr_type); \
FIELD(4, uint32_t, u.dir.pr_name_len); \
} \
\
STRUCT(event_t) { \
FIELD( 0, userdata_t, userdata); \
FIELD( 8, errno_t, error); \
FIELD(10, eventtype_t, type); \
TYPE_SWITCH { \
case UVWASI_EVENTTYPE_FD_READ: \
case UVWASI_EVENTTYPE_FD_WRITE: \
FIELD(16, filesize_t, u.fd_readwrite.nbytes); \
FIELD(24, eventrwflags_t, u.fd_readwrite.flags); \
} \
} \
\
STRUCT(subscription_t) { \
FIELD(0, userdata_t, userdata); \
FIELD(8, eventtype_t, type); \
TYPE_SWITCH { \
case UVWASI_EVENTTYPE_CLOCK: \
FIELD(16, clockid_t, u.clock.clock_id); \
FIELD(24, timestamp_t, u.clock.timeout); \
FIELD(32, timestamp_t, u.clock.precision); \
FIELD(40, subclockflags_t, u.clock.flags); \
break; \
case UVWASI_EVENTTYPE_FD_READ: \
case UVWASI_EVENTTYPE_FD_WRITE: \
FIELD(16, fd_t, u.fd_readwrite.fd); \
} \
} \
#define WRITE_STRUCT(name) \
void uvwasi_serdes_write_##name(void* ptr, \
size_t offset, \
const uvwasi_##name* value) \
#define READ_STRUCT(name) \
void uvwasi_serdes_read_##name(const void* ptr, \
size_t offset, \
uvwasi_##name* value) \
#define WRITE_FIELD(field_offset, type, field) \
do { \
uvwasi_serdes_write_##type(ptr, offset + field_offset, value->field); \
} while (0) \
#define READ_FIELD(field_offset, type, field) \
do { \
value->field = uvwasi_serdes_read_##type(ptr, offset + field_offset); \
} while (0) \
#define WRITE_ALIAS(new_name, old_name) \
void uvwasi_serdes_write_##new_name(void* ptr, \
size_t offset, \
uvwasi_##new_name value) { \
uvwasi_serdes_write_##old_name(ptr, offset, value); \
} \
#define READ_ALIAS(new_name, old_name) \
uvwasi_##new_name uvwasi_serdes_read_##new_name(const void* ptr, \
size_t offset) { \
return uvwasi_serdes_read_##old_name(ptr, offset); \
} \
ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
uvwasi_errno_t uvwasi_serdes_read_ciovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_ciovec_t* value) {
uint32_t buf_ptr;
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
return UVWASI_EOVERFLOW;
value->buf = ((uint8_t*) ptr + buf_ptr);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_read_iovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_iovec_t* value) {
uint32_t buf_ptr;
buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
return UVWASI_EOVERFLOW;
value->buf = ((uint8_t*) ptr + buf_ptr);
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len) {
uvwasi_errno_t err;
uvwasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = uvwasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
if (err != UVWASI_ESUCCESS)
return err;
offset += UVWASI_SERDES_SIZE_ciovec_t;
}
return UVWASI_ESUCCESS;
}
uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
size_t end,
size_t offset,
uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len) {
uvwasi_errno_t err;
uvwasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = uvwasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
if (err != UVWASI_ESUCCESS)
return err;
offset += UVWASI_SERDES_SIZE_iovec_t;
}
return UVWASI_ESUCCESS;
}
int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size) {
return end > offset && size <= (end - offset);
}
int uvwasi_serdes_check_array_bounds(size_t offset,
size_t end,
size_t size,
size_t count) {
return end > offset &&
((count * size) / size == count) &&
(count * size <= end - offset);
}

32
deps/uvwasi/unofficial.gni vendored Normal file
View File

@ -0,0 +1,32 @@
# This file is used by GN for building, which is NOT the build system used for
# building official binaries.
# Please edit the gyp files if you are making changes to build system.
# The actual configurations are put inside a template in unofficial.gni to
# prevent accidental edits from contributors.
template("uvwasi_gn_build") {
config("uvwasi_config") {
include_dirs = [ "include" ]
}
gypi_values = exec_script("../../tools/gypi_to_gn.py",
[ rebase_path("uvwasi.gyp") ],
"scope",
[ "uvwasi.gyp" ])
source_set(target_name) {
forward_variables_from(invoker, "*")
public_configs = [ ":uvwasi_config" ]
sources = gypi_values.uvwasi_sources
include_dirs = [ "src" ]
deps = [ "../uv" ]
if (is_clang || !is_win) {
cflags_c = [
"-Wno-extra-semi",
"-Wno-shadow",
]
}
}
}

45
deps/uvwasi/uvwasi.gyp vendored Normal file
View File

@ -0,0 +1,45 @@
{
'variables': {
'uvwasi_sources': [
'src/clocks.c',
'src/fd_table.c',
'src/path_resolver.c',
'src/poll_oneoff.c',
'src/sync_helpers.c',
'src/uv_mapping.c',
'src/uvwasi.c',
'src/wasi_rights.c',
'src/wasi_serdes.c',
]
},
'targets': [
{
'target_name': 'uvwasi',
'type': 'static_library',
'cflags': ['-fvisibility=hidden'],
'xcode_settings': {
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
},
'include_dirs': ['include'],
'sources': [
'<@(uvwasi_sources)',
],
'direct_dependent_settings': {
'include_dirs': ['include']
},
'conditions': [
[ 'OS=="linux"', {
'defines': [
'_GNU_SOURCE',
'_POSIX_C_SOURCE=200112',
],
}],
[ 'node_shared_libuv=="false"', {
'dependencies': [
'../uv/uv.gyp:libuv',
],
}],
],
}
]
}