11cb0ef41Sopenharmony_ci#include <stdlib.h> 21cb0ef41Sopenharmony_ci#include <string.h> 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci#ifndef _WIN32 51cb0ef41Sopenharmony_ci# include <sched.h> 61cb0ef41Sopenharmony_ci# include <sys/types.h> 71cb0ef41Sopenharmony_ci# include <unistd.h> 81cb0ef41Sopenharmony_ci# include <dirent.h> 91cb0ef41Sopenharmony_ci# include <time.h> 101cb0ef41Sopenharmony_ci#else 111cb0ef41Sopenharmony_ci# include <io.h> 121cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#define UVWASI__READDIR_NUM_ENTRIES 1 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#if !defined(_WIN32) && !defined(__ANDROID__) 171cb0ef41Sopenharmony_ci# define UVWASI_FD_READDIR_SUPPORTED 1 181cb0ef41Sopenharmony_ci#endif 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci#include "uvwasi.h" 211cb0ef41Sopenharmony_ci#include "uvwasi_alloc.h" 221cb0ef41Sopenharmony_ci#include "uv.h" 231cb0ef41Sopenharmony_ci#include "uv_mapping.h" 241cb0ef41Sopenharmony_ci#include "fd_table.h" 251cb0ef41Sopenharmony_ci#include "clocks.h" 261cb0ef41Sopenharmony_ci#include "path_resolver.h" 271cb0ef41Sopenharmony_ci#include "poll_oneoff.h" 281cb0ef41Sopenharmony_ci#include "sync_helpers.h" 291cb0ef41Sopenharmony_ci#include "wasi_rights.h" 301cb0ef41Sopenharmony_ci#include "wasi_serdes.h" 311cb0ef41Sopenharmony_ci#include "debug.h" 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci/* IBMi PASE does not support posix_fadvise() */ 341cb0ef41Sopenharmony_ci#ifdef __PASE__ 351cb0ef41Sopenharmony_ci# undef POSIX_FADV_NORMAL 361cb0ef41Sopenharmony_ci#endif 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci#define VALIDATE_FSTFLAGS_OR_RETURN(flags) \ 391cb0ef41Sopenharmony_ci do { \ 401cb0ef41Sopenharmony_ci if ((flags) & ~(UVWASI_FILESTAT_SET_ATIM | \ 411cb0ef41Sopenharmony_ci UVWASI_FILESTAT_SET_ATIM_NOW | \ 421cb0ef41Sopenharmony_ci UVWASI_FILESTAT_SET_MTIM | \ 431cb0ef41Sopenharmony_ci UVWASI_FILESTAT_SET_MTIM_NOW)) { \ 441cb0ef41Sopenharmony_ci return UVWASI_EINVAL; \ 451cb0ef41Sopenharmony_ci } \ 461cb0ef41Sopenharmony_ci } while (0) 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_cistatic uvwasi_errno_t uvwasi__get_filestat_set_times( 491cb0ef41Sopenharmony_ci uvwasi_timestamp_t* st_atim, 501cb0ef41Sopenharmony_ci uvwasi_timestamp_t* st_mtim, 511cb0ef41Sopenharmony_ci uvwasi_fstflags_t fst_flags, 521cb0ef41Sopenharmony_ci uv_file* fd, 531cb0ef41Sopenharmony_ci char* path 541cb0ef41Sopenharmony_ci ) { 551cb0ef41Sopenharmony_ci uvwasi_filestat_t stat; 561cb0ef41Sopenharmony_ci uvwasi_timestamp_t now; 571cb0ef41Sopenharmony_ci uvwasi_errno_t err; 581cb0ef41Sopenharmony_ci uv_fs_t req; 591cb0ef41Sopenharmony_ci int r; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci /* Check if either value requires the current time. */ 621cb0ef41Sopenharmony_ci if ((fst_flags & 631cb0ef41Sopenharmony_ci (UVWASI_FILESTAT_SET_ATIM_NOW | UVWASI_FILESTAT_SET_MTIM_NOW)) != 0) { 641cb0ef41Sopenharmony_ci err = uvwasi__clock_gettime_realtime(&now); 651cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 661cb0ef41Sopenharmony_ci return err; 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci /* Check if either value is omitted. libuv doesn't have an 'omitted' option, 701cb0ef41Sopenharmony_ci so get the current stats for the file. This approach isn't perfect, but it 711cb0ef41Sopenharmony_ci will do until libuv can get better support here. */ 721cb0ef41Sopenharmony_ci if ((fst_flags & 731cb0ef41Sopenharmony_ci (UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW)) == 0 || 741cb0ef41Sopenharmony_ci (fst_flags & 751cb0ef41Sopenharmony_ci (UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) == 0) { 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci if (fd != NULL) 781cb0ef41Sopenharmony_ci r = uv_fs_fstat(NULL, &req, *fd, NULL); 791cb0ef41Sopenharmony_ci else 801cb0ef41Sopenharmony_ci r = uv_fs_lstat(NULL, &req, path, NULL); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci if (r != 0) { 831cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 841cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci uvwasi__stat_to_filestat(&req.statbuf, &stat); 881cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci /* Choose the provided time or 'now' and convert WASI timestamps from 921cb0ef41Sopenharmony_ci nanoseconds to seconds due to libuv. */ 931cb0ef41Sopenharmony_ci if ((fst_flags & UVWASI_FILESTAT_SET_ATIM_NOW) != 0) 941cb0ef41Sopenharmony_ci *st_atim = now / NANOS_PER_SEC; 951cb0ef41Sopenharmony_ci else if ((fst_flags & UVWASI_FILESTAT_SET_ATIM) != 0) 961cb0ef41Sopenharmony_ci *st_atim = *st_atim / NANOS_PER_SEC; 971cb0ef41Sopenharmony_ci else 981cb0ef41Sopenharmony_ci *st_atim = stat.st_atim / NANOS_PER_SEC; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci if ((fst_flags & UVWASI_FILESTAT_SET_MTIM_NOW) != 0) 1011cb0ef41Sopenharmony_ci *st_mtim = now / NANOS_PER_SEC; 1021cb0ef41Sopenharmony_ci else if ((fst_flags & UVWASI_FILESTAT_SET_MTIM) != 0) 1031cb0ef41Sopenharmony_ci *st_mtim = *st_mtim / NANOS_PER_SEC; 1041cb0ef41Sopenharmony_ci else 1051cb0ef41Sopenharmony_ci *st_mtim = stat.st_mtim / NANOS_PER_SEC; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_cistatic void* default_malloc(size_t size, void* mem_user_data) { 1111cb0ef41Sopenharmony_ci return malloc(size); 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_cistatic void default_free(void* ptr, void* mem_user_data) { 1151cb0ef41Sopenharmony_ci free(ptr); 1161cb0ef41Sopenharmony_ci} 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_cistatic void* default_calloc(size_t nmemb, size_t size, void* mem_user_data) { 1191cb0ef41Sopenharmony_ci return calloc(nmemb, size); 1201cb0ef41Sopenharmony_ci} 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cistatic void* default_realloc(void* ptr, size_t size, void* mem_user_data) { 1231cb0ef41Sopenharmony_ci return realloc(ptr, size); 1241cb0ef41Sopenharmony_ci} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_civoid* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size) { 1271cb0ef41Sopenharmony_ci return uvwasi->allocator->malloc(size, uvwasi->allocator->mem_user_data); 1281cb0ef41Sopenharmony_ci} 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_civoid uvwasi__free(const uvwasi_t* uvwasi, void* ptr) { 1311cb0ef41Sopenharmony_ci if (ptr == NULL) 1321cb0ef41Sopenharmony_ci return; 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci uvwasi->allocator->free(ptr, uvwasi->allocator->mem_user_data); 1351cb0ef41Sopenharmony_ci} 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_civoid* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size) { 1381cb0ef41Sopenharmony_ci return uvwasi->allocator->calloc(nmemb, 1391cb0ef41Sopenharmony_ci size, 1401cb0ef41Sopenharmony_ci uvwasi->allocator->mem_user_data); 1411cb0ef41Sopenharmony_ci} 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_civoid* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size) { 1441cb0ef41Sopenharmony_ci return uvwasi->allocator->realloc(ptr, 1451cb0ef41Sopenharmony_ci size, 1461cb0ef41Sopenharmony_ci uvwasi->allocator->mem_user_data); 1471cb0ef41Sopenharmony_ci} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_cistatic const uvwasi_mem_t default_allocator = { 1501cb0ef41Sopenharmony_ci NULL, 1511cb0ef41Sopenharmony_ci default_malloc, 1521cb0ef41Sopenharmony_ci default_free, 1531cb0ef41Sopenharmony_ci default_calloc, 1541cb0ef41Sopenharmony_ci default_realloc, 1551cb0ef41Sopenharmony_ci}; 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_cistatic uvwasi_errno_t uvwasi__lseek(uv_file fd, 1591cb0ef41Sopenharmony_ci uvwasi_filedelta_t offset, 1601cb0ef41Sopenharmony_ci uvwasi_whence_t whence, 1611cb0ef41Sopenharmony_ci uvwasi_filesize_t* newoffset) { 1621cb0ef41Sopenharmony_ci int real_whence; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci if (whence == UVWASI_WHENCE_CUR) 1651cb0ef41Sopenharmony_ci real_whence = SEEK_CUR; 1661cb0ef41Sopenharmony_ci else if (whence == UVWASI_WHENCE_END) 1671cb0ef41Sopenharmony_ci real_whence = SEEK_END; 1681cb0ef41Sopenharmony_ci else if (whence == UVWASI_WHENCE_SET) 1691cb0ef41Sopenharmony_ci real_whence = SEEK_SET; 1701cb0ef41Sopenharmony_ci else 1711cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci#ifdef _WIN32 1741cb0ef41Sopenharmony_ci int64_t r; 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci r = _lseeki64(fd, offset, real_whence); 1771cb0ef41Sopenharmony_ci if (-1L == r) 1781cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 1791cb0ef41Sopenharmony_ci#else 1801cb0ef41Sopenharmony_ci off_t r; 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci r = lseek(fd, offset, real_whence); 1831cb0ef41Sopenharmony_ci if ((off_t) -1 == r) 1841cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 1851cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci *newoffset = r; 1881cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 1891cb0ef41Sopenharmony_ci} 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_cistatic uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi, 1931cb0ef41Sopenharmony_ci uv_buf_t** buffers, 1941cb0ef41Sopenharmony_ci const uvwasi_iovec_t* iovs, 1951cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len) { 1961cb0ef41Sopenharmony_ci uv_buf_t* bufs; 1971cb0ef41Sopenharmony_ci uvwasi_size_t i; 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len) 2001cb0ef41Sopenharmony_ci return UVWASI_ENOMEM; 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs)); 2031cb0ef41Sopenharmony_ci if (bufs == NULL) 2041cb0ef41Sopenharmony_ci return UVWASI_ENOMEM; 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_ci for (i = 0; i < iovs_len; ++i) 2071cb0ef41Sopenharmony_ci bufs[i] = uv_buf_init(iovs[i].buf, iovs[i].buf_len); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci *buffers = bufs; 2101cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 2111cb0ef41Sopenharmony_ci} 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_cistatic uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi, 2151cb0ef41Sopenharmony_ci uv_buf_t** buffers, 2161cb0ef41Sopenharmony_ci const uvwasi_ciovec_t* iovs, 2171cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len) { 2181cb0ef41Sopenharmony_ci uv_buf_t* bufs; 2191cb0ef41Sopenharmony_ci uvwasi_size_t i; 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len) 2221cb0ef41Sopenharmony_ci return UVWASI_ENOMEM; 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs)); 2251cb0ef41Sopenharmony_ci if (bufs == NULL) 2261cb0ef41Sopenharmony_ci return UVWASI_ENOMEM; 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci for (i = 0; i < iovs_len; ++i) 2291cb0ef41Sopenharmony_ci bufs[i] = uv_buf_init((char*)iovs[i].buf, iovs[i].buf_len); 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci *buffers = bufs; 2321cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 2331cb0ef41Sopenharmony_ci} 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_citypedef struct new_connection_data_s { 2361cb0ef41Sopenharmony_ci int done; 2371cb0ef41Sopenharmony_ci} new_connection_data_t; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_civoid on_new_connection(uv_stream_t *server, int status) { 2401cb0ef41Sopenharmony_ci // just do nothing 2411cb0ef41Sopenharmony_ci} 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options) { 2441cb0ef41Sopenharmony_ci uv_fs_t realpath_req; 2451cb0ef41Sopenharmony_ci uv_fs_t open_req; 2461cb0ef41Sopenharmony_ci uvwasi_errno_t err; 2471cb0ef41Sopenharmony_ci uvwasi_size_t args_size; 2481cb0ef41Sopenharmony_ci uvwasi_size_t size; 2491cb0ef41Sopenharmony_ci uvwasi_size_t offset; 2501cb0ef41Sopenharmony_ci uvwasi_size_t env_count; 2511cb0ef41Sopenharmony_ci uvwasi_size_t env_buf_size; 2521cb0ef41Sopenharmony_ci uvwasi_size_t i; 2531cb0ef41Sopenharmony_ci int r; 2541cb0ef41Sopenharmony_ci struct sockaddr_in addr; 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci if (uvwasi == NULL || options == NULL || options->fd_table_size == 0) 2571cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci // loop is only needed if there were pre-open sockets 2601cb0ef41Sopenharmony_ci uvwasi->loop = NULL; 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci uvwasi->allocator = options->allocator; 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci if (uvwasi->allocator == NULL) 2651cb0ef41Sopenharmony_ci uvwasi->allocator = &default_allocator; 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci uvwasi->argv_buf = NULL; 2681cb0ef41Sopenharmony_ci uvwasi->argv = NULL; 2691cb0ef41Sopenharmony_ci uvwasi->env_buf = NULL; 2701cb0ef41Sopenharmony_ci uvwasi->env = NULL; 2711cb0ef41Sopenharmony_ci uvwasi->fds = NULL; 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci args_size = 0; 2741cb0ef41Sopenharmony_ci for (i = 0; i < options->argc; ++i) 2751cb0ef41Sopenharmony_ci args_size += strlen(options->argv[i]) + 1; 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci uvwasi->argc = options->argc; 2781cb0ef41Sopenharmony_ci uvwasi->argv_buf_size = args_size; 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci if (args_size > 0) { 2811cb0ef41Sopenharmony_ci uvwasi->argv_buf = uvwasi__malloc(uvwasi, args_size); 2821cb0ef41Sopenharmony_ci if (uvwasi->argv_buf == NULL) { 2831cb0ef41Sopenharmony_ci err = UVWASI_ENOMEM; 2841cb0ef41Sopenharmony_ci goto exit; 2851cb0ef41Sopenharmony_ci } 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci uvwasi->argv = uvwasi__calloc(uvwasi, options->argc, sizeof(char*)); 2881cb0ef41Sopenharmony_ci if (uvwasi->argv == NULL) { 2891cb0ef41Sopenharmony_ci err = UVWASI_ENOMEM; 2901cb0ef41Sopenharmony_ci goto exit; 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci offset = 0; 2941cb0ef41Sopenharmony_ci for (i = 0; i < options->argc; ++i) { 2951cb0ef41Sopenharmony_ci size = strlen(options->argv[i]) + 1; 2961cb0ef41Sopenharmony_ci memcpy(uvwasi->argv_buf + offset, options->argv[i], size); 2971cb0ef41Sopenharmony_ci uvwasi->argv[i] = uvwasi->argv_buf + offset; 2981cb0ef41Sopenharmony_ci offset += size; 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci } 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci env_count = 0; 3031cb0ef41Sopenharmony_ci env_buf_size = 0; 3041cb0ef41Sopenharmony_ci if (options->envp != NULL) { 3051cb0ef41Sopenharmony_ci while (options->envp[env_count] != NULL) { 3061cb0ef41Sopenharmony_ci env_buf_size += strlen(options->envp[env_count]) + 1; 3071cb0ef41Sopenharmony_ci env_count++; 3081cb0ef41Sopenharmony_ci } 3091cb0ef41Sopenharmony_ci } 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci uvwasi->envc = env_count; 3121cb0ef41Sopenharmony_ci uvwasi->env_buf_size = env_buf_size; 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci if (env_buf_size > 0) { 3151cb0ef41Sopenharmony_ci uvwasi->env_buf = uvwasi__malloc(uvwasi, env_buf_size); 3161cb0ef41Sopenharmony_ci if (uvwasi->env_buf == NULL) { 3171cb0ef41Sopenharmony_ci err = UVWASI_ENOMEM; 3181cb0ef41Sopenharmony_ci goto exit; 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci uvwasi->env = uvwasi__calloc(uvwasi, env_count, sizeof(char*)); 3221cb0ef41Sopenharmony_ci if (uvwasi->env == NULL) { 3231cb0ef41Sopenharmony_ci err = UVWASI_ENOMEM; 3241cb0ef41Sopenharmony_ci goto exit; 3251cb0ef41Sopenharmony_ci } 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci offset = 0; 3281cb0ef41Sopenharmony_ci for (i = 0; i < env_count; ++i) { 3291cb0ef41Sopenharmony_ci size = strlen(options->envp[i]) + 1; 3301cb0ef41Sopenharmony_ci memcpy(uvwasi->env_buf + offset, options->envp[i], size); 3311cb0ef41Sopenharmony_ci uvwasi->env[i] = uvwasi->env_buf + offset; 3321cb0ef41Sopenharmony_ci offset += size; 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci } 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ci for (i = 0; i < options->preopenc; ++i) { 3371cb0ef41Sopenharmony_ci if (options->preopens[i].real_path == NULL || 3381cb0ef41Sopenharmony_ci options->preopens[i].mapped_path == NULL) { 3391cb0ef41Sopenharmony_ci err = UVWASI_EINVAL; 3401cb0ef41Sopenharmony_ci goto exit; 3411cb0ef41Sopenharmony_ci } 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci for (i = 0; i < options->preopen_socketc; ++i) { 3451cb0ef41Sopenharmony_ci if (options->preopen_sockets[i].address == NULL || 3461cb0ef41Sopenharmony_ci options->preopen_sockets[i].port > 65535) { 3471cb0ef41Sopenharmony_ci err = UVWASI_EINVAL; 3481cb0ef41Sopenharmony_ci goto exit; 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci } 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci err = uvwasi_fd_table_init(uvwasi, options); 3531cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 3541cb0ef41Sopenharmony_ci goto exit; 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci for (i = 0; i < options->preopenc; ++i) { 3571cb0ef41Sopenharmony_ci r = uv_fs_realpath(NULL, 3581cb0ef41Sopenharmony_ci &realpath_req, 3591cb0ef41Sopenharmony_ci options->preopens[i].real_path, 3601cb0ef41Sopenharmony_ci NULL); 3611cb0ef41Sopenharmony_ci if (r != 0) { 3621cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 3631cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&realpath_req); 3641cb0ef41Sopenharmony_ci goto exit; 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci r = uv_fs_open(NULL, &open_req, realpath_req.ptr, 0, 0666, NULL); 3681cb0ef41Sopenharmony_ci if (r < 0) { 3691cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 3701cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&realpath_req); 3711cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&open_req); 3721cb0ef41Sopenharmony_ci goto exit; 3731cb0ef41Sopenharmony_ci } 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ci err = uvwasi_fd_table_insert_preopen(uvwasi, 3761cb0ef41Sopenharmony_ci uvwasi->fds, 3771cb0ef41Sopenharmony_ci open_req.result, 3781cb0ef41Sopenharmony_ci options->preopens[i].mapped_path, 3791cb0ef41Sopenharmony_ci realpath_req.ptr); 3801cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&realpath_req); 3811cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&open_req); 3821cb0ef41Sopenharmony_ci 3831cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 3841cb0ef41Sopenharmony_ci goto exit; 3851cb0ef41Sopenharmony_ci } 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci if (options->preopen_socketc > 0) { 3881cb0ef41Sopenharmony_ci uvwasi->loop = uvwasi__malloc(uvwasi, sizeof(uv_loop_t)); 3891cb0ef41Sopenharmony_ci r = uv_loop_init(uvwasi->loop); 3901cb0ef41Sopenharmony_ci if (r != 0) { 3911cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 3921cb0ef41Sopenharmony_ci goto exit; 3931cb0ef41Sopenharmony_ci } 3941cb0ef41Sopenharmony_ci } 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci for (i = 0; i < options->preopen_socketc; ++i) { 3971cb0ef41Sopenharmony_ci uv_tcp_t* socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); 3981cb0ef41Sopenharmony_ci uv_tcp_init(uvwasi->loop, socket); 3991cb0ef41Sopenharmony_ci 4001cb0ef41Sopenharmony_ci uv_ip4_addr(options->preopen_sockets[i].address, options->preopen_sockets[i].port, &addr); 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci uv_tcp_bind(socket, (const struct sockaddr*)&addr, 0); 4031cb0ef41Sopenharmony_ci r = uv_listen((uv_stream_t*) socket, 128, on_new_connection); 4041cb0ef41Sopenharmony_ci if (r != 0) { 4051cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 4061cb0ef41Sopenharmony_ci goto exit; 4071cb0ef41Sopenharmony_ci } 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci err = uvwasi_fd_table_insert_preopen_socket(uvwasi, 4101cb0ef41Sopenharmony_ci uvwasi->fds, 4111cb0ef41Sopenharmony_ci socket); 4121cb0ef41Sopenharmony_ci 4131cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 4141cb0ef41Sopenharmony_ci goto exit; 4151cb0ef41Sopenharmony_ci } 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ciexit: 4201cb0ef41Sopenharmony_ci uvwasi_destroy(uvwasi); 4211cb0ef41Sopenharmony_ci return err; 4221cb0ef41Sopenharmony_ci} 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_civoid uvwasi_destroy(uvwasi_t* uvwasi) { 4261cb0ef41Sopenharmony_ci if (uvwasi == NULL) 4271cb0ef41Sopenharmony_ci return; 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci uvwasi_fd_table_free(uvwasi, uvwasi->fds); 4301cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uvwasi->argv_buf); 4311cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uvwasi->argv); 4321cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uvwasi->env_buf); 4331cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uvwasi->env); 4341cb0ef41Sopenharmony_ci if (uvwasi->loop != NULL) { 4351cb0ef41Sopenharmony_ci uv_stop(uvwasi->loop); 4361cb0ef41Sopenharmony_ci uv_loop_close(uvwasi->loop); 4371cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uvwasi->loop); 4381cb0ef41Sopenharmony_ci uvwasi->loop = NULL; 4391cb0ef41Sopenharmony_ci } 4401cb0ef41Sopenharmony_ci uvwasi->fds = NULL; 4411cb0ef41Sopenharmony_ci uvwasi->argv_buf = NULL; 4421cb0ef41Sopenharmony_ci uvwasi->argv = NULL; 4431cb0ef41Sopenharmony_ci uvwasi->env_buf = NULL; 4441cb0ef41Sopenharmony_ci uvwasi->env = NULL; 4451cb0ef41Sopenharmony_ci} 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_civoid uvwasi_options_init(uvwasi_options_t* options) { 4491cb0ef41Sopenharmony_ci if (options == NULL) 4501cb0ef41Sopenharmony_ci return; 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci options->in = 0; 4531cb0ef41Sopenharmony_ci options->out = 1; 4541cb0ef41Sopenharmony_ci options->err = 2; 4551cb0ef41Sopenharmony_ci options->fd_table_size = 3; 4561cb0ef41Sopenharmony_ci options->argc = 0; 4571cb0ef41Sopenharmony_ci options->argv = NULL; 4581cb0ef41Sopenharmony_ci options->envp = NULL; 4591cb0ef41Sopenharmony_ci options->preopenc = 0; 4601cb0ef41Sopenharmony_ci options->preopens = NULL; 4611cb0ef41Sopenharmony_ci options->preopen_socketc = 0; 4621cb0ef41Sopenharmony_ci options->preopen_sockets = NULL; 4631cb0ef41Sopenharmony_ci options->allocator = NULL; 4641cb0ef41Sopenharmony_ci} 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi, 4681cb0ef41Sopenharmony_ci const uvwasi_fd_t fd, 4691cb0ef41Sopenharmony_ci uv_file new_host_fd) { 4701cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 4711cb0ef41Sopenharmony_ci uvwasi_errno_t err; 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_ci if (uvwasi == NULL) 4741cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0); 4771cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 4781cb0ef41Sopenharmony_ci return err; 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci wrap->fd = new_host_fd; 4811cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 4821cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 4831cb0ef41Sopenharmony_ci} 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) { 4871cb0ef41Sopenharmony_ci uvwasi_size_t i; 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_args_get(uvwasi=%p, argv=%p, argv_buf=%p)\n", 4901cb0ef41Sopenharmony_ci uvwasi, 4911cb0ef41Sopenharmony_ci argv, 4921cb0ef41Sopenharmony_ci argv_buf); 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci if (uvwasi == NULL || argv == NULL || argv_buf == NULL) 4951cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 4961cb0ef41Sopenharmony_ci 4971cb0ef41Sopenharmony_ci for (i = 0; i < uvwasi->argc; ++i) { 4981cb0ef41Sopenharmony_ci argv[i] = argv_buf + (uvwasi->argv[i] - uvwasi->argv_buf); 4991cb0ef41Sopenharmony_ci } 5001cb0ef41Sopenharmony_ci 5011cb0ef41Sopenharmony_ci memcpy(argv_buf, uvwasi->argv_buf, uvwasi->argv_buf_size); 5021cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 5031cb0ef41Sopenharmony_ci} 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi, 5071cb0ef41Sopenharmony_ci uvwasi_size_t* argc, 5081cb0ef41Sopenharmony_ci uvwasi_size_t* argv_buf_size) { 5091cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_args_sizes_get(uvwasi=%p, argc=%p, argv_buf_size=%p)\n", 5101cb0ef41Sopenharmony_ci uvwasi, 5111cb0ef41Sopenharmony_ci argc, 5121cb0ef41Sopenharmony_ci argv_buf_size); 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci if (uvwasi == NULL || argc == NULL || argv_buf_size == NULL) 5151cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ci *argc = uvwasi->argc; 5181cb0ef41Sopenharmony_ci *argv_buf_size = uvwasi->argv_buf_size; 5191cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 5201cb0ef41Sopenharmony_ci} 5211cb0ef41Sopenharmony_ci 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi, 5241cb0ef41Sopenharmony_ci uvwasi_clockid_t clock_id, 5251cb0ef41Sopenharmony_ci uvwasi_timestamp_t* resolution) { 5261cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_clock_res_get(uvwasi=%p, clock_id=%d, resolution=%p)\n", 5271cb0ef41Sopenharmony_ci uvwasi, 5281cb0ef41Sopenharmony_ci clock_id, 5291cb0ef41Sopenharmony_ci resolution); 5301cb0ef41Sopenharmony_ci 5311cb0ef41Sopenharmony_ci if (uvwasi == NULL || resolution == NULL) 5321cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci switch (clock_id) { 5351cb0ef41Sopenharmony_ci case UVWASI_CLOCK_MONOTONIC: 5361cb0ef41Sopenharmony_ci case UVWASI_CLOCK_REALTIME: 5371cb0ef41Sopenharmony_ci *resolution = 1; /* Nanosecond precision. */ 5381cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 5391cb0ef41Sopenharmony_ci case UVWASI_CLOCK_PROCESS_CPUTIME_ID: 5401cb0ef41Sopenharmony_ci return uvwasi__clock_getres_process_cputime(resolution); 5411cb0ef41Sopenharmony_ci case UVWASI_CLOCK_THREAD_CPUTIME_ID: 5421cb0ef41Sopenharmony_ci return uvwasi__clock_getres_thread_cputime(resolution); 5431cb0ef41Sopenharmony_ci default: 5441cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5451cb0ef41Sopenharmony_ci } 5461cb0ef41Sopenharmony_ci} 5471cb0ef41Sopenharmony_ci 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi, 5501cb0ef41Sopenharmony_ci uvwasi_clockid_t clock_id, 5511cb0ef41Sopenharmony_ci uvwasi_timestamp_t precision, 5521cb0ef41Sopenharmony_ci uvwasi_timestamp_t* time) { 5531cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_clock_time_get(uvwasi=%p, clock_id=%d, " 5541cb0ef41Sopenharmony_ci "precision=%"PRIu64", time=%p)\n", 5551cb0ef41Sopenharmony_ci uvwasi, 5561cb0ef41Sopenharmony_ci clock_id, 5571cb0ef41Sopenharmony_ci precision, 5581cb0ef41Sopenharmony_ci time); 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci if (uvwasi == NULL || time == NULL) 5611cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci switch (clock_id) { 5641cb0ef41Sopenharmony_ci case UVWASI_CLOCK_MONOTONIC: 5651cb0ef41Sopenharmony_ci *time = uv_hrtime(); 5661cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 5671cb0ef41Sopenharmony_ci case UVWASI_CLOCK_REALTIME: 5681cb0ef41Sopenharmony_ci return uvwasi__clock_gettime_realtime(time); 5691cb0ef41Sopenharmony_ci case UVWASI_CLOCK_PROCESS_CPUTIME_ID: 5701cb0ef41Sopenharmony_ci return uvwasi__clock_gettime_process_cputime(time); 5711cb0ef41Sopenharmony_ci case UVWASI_CLOCK_THREAD_CPUTIME_ID: 5721cb0ef41Sopenharmony_ci return uvwasi__clock_gettime_thread_cputime(time); 5731cb0ef41Sopenharmony_ci default: 5741cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5751cb0ef41Sopenharmony_ci } 5761cb0ef41Sopenharmony_ci} 5771cb0ef41Sopenharmony_ci 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi, 5801cb0ef41Sopenharmony_ci char** environment, 5811cb0ef41Sopenharmony_ci char* environ_buf) { 5821cb0ef41Sopenharmony_ci uvwasi_size_t i; 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_environ_get(uvwasi=%p, environment=%p, " 5851cb0ef41Sopenharmony_ci "environ_buf=%p)\n", 5861cb0ef41Sopenharmony_ci uvwasi, 5871cb0ef41Sopenharmony_ci environment, 5881cb0ef41Sopenharmony_ci environ_buf); 5891cb0ef41Sopenharmony_ci 5901cb0ef41Sopenharmony_ci if (uvwasi == NULL || environment == NULL || environ_buf == NULL) 5911cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci for (i = 0; i < uvwasi->envc; ++i) { 5941cb0ef41Sopenharmony_ci environment[i] = environ_buf + (uvwasi->env[i] - uvwasi->env_buf); 5951cb0ef41Sopenharmony_ci } 5961cb0ef41Sopenharmony_ci 5971cb0ef41Sopenharmony_ci memcpy(environ_buf, uvwasi->env_buf, uvwasi->env_buf_size); 5981cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 5991cb0ef41Sopenharmony_ci} 6001cb0ef41Sopenharmony_ci 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi, 6031cb0ef41Sopenharmony_ci uvwasi_size_t* environ_count, 6041cb0ef41Sopenharmony_ci uvwasi_size_t* environ_buf_size) { 6051cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_environ_sizes_get(uvwasi=%p, environ_count=%p, " 6061cb0ef41Sopenharmony_ci "environ_buf_size=%p)\n", 6071cb0ef41Sopenharmony_ci uvwasi, 6081cb0ef41Sopenharmony_ci environ_count, 6091cb0ef41Sopenharmony_ci environ_buf_size); 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_ci if (uvwasi == NULL || environ_count == NULL || environ_buf_size == NULL) 6121cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci *environ_count = uvwasi->envc; 6151cb0ef41Sopenharmony_ci *environ_buf_size = uvwasi->env_buf_size; 6161cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 6171cb0ef41Sopenharmony_ci} 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi, 6211cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 6221cb0ef41Sopenharmony_ci uvwasi_filesize_t offset, 6231cb0ef41Sopenharmony_ci uvwasi_filesize_t len, 6241cb0ef41Sopenharmony_ci uvwasi_advice_t advice) { 6251cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 6261cb0ef41Sopenharmony_ci uvwasi_errno_t err; 6271cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6281cb0ef41Sopenharmony_ci int mapped_advice; 6291cb0ef41Sopenharmony_ci int r; 6301cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6311cb0ef41Sopenharmony_ci 6321cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_advise(uvwasi=%p, fd=%d, offset=%"PRIu64", " 6331cb0ef41Sopenharmony_ci "len=%"PRIu64", advice=%d)\n", 6341cb0ef41Sopenharmony_ci uvwasi, 6351cb0ef41Sopenharmony_ci fd, 6361cb0ef41Sopenharmony_ci offset, 6371cb0ef41Sopenharmony_ci len, 6381cb0ef41Sopenharmony_ci advice); 6391cb0ef41Sopenharmony_ci 6401cb0ef41Sopenharmony_ci if (uvwasi == NULL) 6411cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 6421cb0ef41Sopenharmony_ci 6431cb0ef41Sopenharmony_ci switch (advice) { 6441cb0ef41Sopenharmony_ci case UVWASI_ADVICE_DONTNEED: 6451cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6461cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_DONTNEED; 6471cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6481cb0ef41Sopenharmony_ci break; 6491cb0ef41Sopenharmony_ci case UVWASI_ADVICE_NOREUSE: 6501cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6511cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_NOREUSE; 6521cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6531cb0ef41Sopenharmony_ci break; 6541cb0ef41Sopenharmony_ci case UVWASI_ADVICE_NORMAL: 6551cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6561cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_NORMAL; 6571cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6581cb0ef41Sopenharmony_ci break; 6591cb0ef41Sopenharmony_ci case UVWASI_ADVICE_RANDOM: 6601cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6611cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_RANDOM; 6621cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6631cb0ef41Sopenharmony_ci break; 6641cb0ef41Sopenharmony_ci case UVWASI_ADVICE_SEQUENTIAL: 6651cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6661cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_SEQUENTIAL; 6671cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6681cb0ef41Sopenharmony_ci break; 6691cb0ef41Sopenharmony_ci case UVWASI_ADVICE_WILLNEED: 6701cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6711cb0ef41Sopenharmony_ci mapped_advice = POSIX_FADV_WILLNEED; 6721cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6731cb0ef41Sopenharmony_ci break; 6741cb0ef41Sopenharmony_ci default: 6751cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 6761cb0ef41Sopenharmony_ci } 6771cb0ef41Sopenharmony_ci 6781cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0); 6791cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 6801cb0ef41Sopenharmony_ci return err; 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 6831cb0ef41Sopenharmony_ci 6841cb0ef41Sopenharmony_ci#ifdef POSIX_FADV_NORMAL 6851cb0ef41Sopenharmony_ci r = posix_fadvise(wrap->fd, offset, len, mapped_advice); 6861cb0ef41Sopenharmony_ci if (r != 0) 6871cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(uv_translate_sys_error(r)); 6881cb0ef41Sopenharmony_ci#endif /* POSIX_FADV_NORMAL */ 6891cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 6901cb0ef41Sopenharmony_ci return err; 6911cb0ef41Sopenharmony_ci} 6921cb0ef41Sopenharmony_ci 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi, 6951cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 6961cb0ef41Sopenharmony_ci uvwasi_filesize_t offset, 6971cb0ef41Sopenharmony_ci uvwasi_filesize_t len) { 6981cb0ef41Sopenharmony_ci#if !defined(__POSIX__) 6991cb0ef41Sopenharmony_ci uv_fs_t req; 7001cb0ef41Sopenharmony_ci uint64_t st_size; 7011cb0ef41Sopenharmony_ci#endif /* !__POSIX__ */ 7021cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 7031cb0ef41Sopenharmony_ci uvwasi_errno_t err; 7041cb0ef41Sopenharmony_ci int r; 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_allocate(uvwasi=%p, fd=%d, offset=%"PRIu64", " 7071cb0ef41Sopenharmony_ci "len=%"PRIu64")\n", 7081cb0ef41Sopenharmony_ci uvwasi, 7091cb0ef41Sopenharmony_ci fd, 7101cb0ef41Sopenharmony_ci offset, 7111cb0ef41Sopenharmony_ci len); 7121cb0ef41Sopenharmony_ci 7131cb0ef41Sopenharmony_ci if (uvwasi == NULL) 7141cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 7171cb0ef41Sopenharmony_ci fd, 7181cb0ef41Sopenharmony_ci &wrap, 7191cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_ALLOCATE, 7201cb0ef41Sopenharmony_ci 0); 7211cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 7221cb0ef41Sopenharmony_ci return err; 7231cb0ef41Sopenharmony_ci 7241cb0ef41Sopenharmony_ci /* Try to use posix_fallocate(). If that's not an option, fall back to the 7251cb0ef41Sopenharmony_ci race condition prone combination of fstat() + ftruncate(). */ 7261cb0ef41Sopenharmony_ci#if defined(__POSIX__) 7271cb0ef41Sopenharmony_ci r = posix_fallocate(wrap->fd, offset, len); 7281cb0ef41Sopenharmony_ci if (r != 0) { 7291cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(uv_translate_sys_error(r)); 7301cb0ef41Sopenharmony_ci goto exit; 7311cb0ef41Sopenharmony_ci } 7321cb0ef41Sopenharmony_ci#else 7331cb0ef41Sopenharmony_ci r = uv_fs_fstat(NULL, &req, wrap->fd, NULL); 7341cb0ef41Sopenharmony_ci st_size = req.statbuf.st_size; 7351cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 7361cb0ef41Sopenharmony_ci if (r != 0) { 7371cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 7381cb0ef41Sopenharmony_ci goto exit; 7391cb0ef41Sopenharmony_ci } 7401cb0ef41Sopenharmony_ci 7411cb0ef41Sopenharmony_ci if (st_size < offset + len) { 7421cb0ef41Sopenharmony_ci r = uv_fs_ftruncate(NULL, &req, wrap->fd, offset + len, NULL); 7431cb0ef41Sopenharmony_ci if (r != 0) { 7441cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 7451cb0ef41Sopenharmony_ci goto exit; 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci } 7481cb0ef41Sopenharmony_ci#endif /* __POSIX__ */ 7491cb0ef41Sopenharmony_ci 7501cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 7511cb0ef41Sopenharmony_ciexit: 7521cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 7531cb0ef41Sopenharmony_ci return err; 7541cb0ef41Sopenharmony_ci} 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) { 7571cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 7581cb0ef41Sopenharmony_ci uvwasi_errno_t err = 0; 7591cb0ef41Sopenharmony_ci uv_fs_t req; 7601cb0ef41Sopenharmony_ci int r; 7611cb0ef41Sopenharmony_ci 7621cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_close(uvwasi=%p, fd=%d)\n", uvwasi, fd); 7631cb0ef41Sopenharmony_ci 7641cb0ef41Sopenharmony_ci if (uvwasi == NULL) 7651cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 7661cb0ef41Sopenharmony_ci 7671cb0ef41Sopenharmony_ci uvwasi_fd_table_lock(uvwasi->fds); 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, fd, &wrap, 0, 0); 7701cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 7711cb0ef41Sopenharmony_ci goto exit; 7721cb0ef41Sopenharmony_ci 7731cb0ef41Sopenharmony_ci if (wrap->sock == NULL) { 7741cb0ef41Sopenharmony_ci r = uv_fs_close(NULL, &req, wrap->fd, NULL); 7751cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 7761cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 7771cb0ef41Sopenharmony_ci } else { 7781cb0ef41Sopenharmony_ci r = 0; 7791cb0ef41Sopenharmony_ci err = free_handle_sync(uvwasi, (uv_handle_t*) wrap->sock); 7801cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 7811cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 7821cb0ef41Sopenharmony_ci goto exit; 7831cb0ef41Sopenharmony_ci } 7841cb0ef41Sopenharmony_ci } 7851cb0ef41Sopenharmony_ci 7861cb0ef41Sopenharmony_ci if (r != 0) { 7871cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 7881cb0ef41Sopenharmony_ci goto exit; 7891cb0ef41Sopenharmony_ci } 7901cb0ef41Sopenharmony_ci 7911cb0ef41Sopenharmony_ci err = uvwasi_fd_table_remove_nolock(uvwasi, uvwasi->fds, fd); 7921cb0ef41Sopenharmony_ci 7931cb0ef41Sopenharmony_ciexit: 7941cb0ef41Sopenharmony_ci uvwasi_fd_table_unlock(uvwasi->fds); 7951cb0ef41Sopenharmony_ci return err; 7961cb0ef41Sopenharmony_ci} 7971cb0ef41Sopenharmony_ci 7981cb0ef41Sopenharmony_ci 7991cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd) { 8001cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 8011cb0ef41Sopenharmony_ci uvwasi_errno_t err; 8021cb0ef41Sopenharmony_ci uv_fs_t req; 8031cb0ef41Sopenharmony_ci int r; 8041cb0ef41Sopenharmony_ci 8051cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_datasync(uvwasi=%p, fd=%d)\n", uvwasi, fd); 8061cb0ef41Sopenharmony_ci 8071cb0ef41Sopenharmony_ci if (uvwasi == NULL) 8081cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 8111cb0ef41Sopenharmony_ci fd, 8121cb0ef41Sopenharmony_ci &wrap, 8131cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_DATASYNC, 8141cb0ef41Sopenharmony_ci 0); 8151cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 8161cb0ef41Sopenharmony_ci return err; 8171cb0ef41Sopenharmony_ci 8181cb0ef41Sopenharmony_ci r = uv_fs_fdatasync(NULL, &req, wrap->fd, NULL); 8191cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 8201cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 8211cb0ef41Sopenharmony_ci 8221cb0ef41Sopenharmony_ci if (r != 0) 8231cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 8261cb0ef41Sopenharmony_ci} 8271cb0ef41Sopenharmony_ci 8281cb0ef41Sopenharmony_ci 8291cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi, 8301cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 8311cb0ef41Sopenharmony_ci uvwasi_fdstat_t* buf) { 8321cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 8331cb0ef41Sopenharmony_ci uvwasi_errno_t err; 8341cb0ef41Sopenharmony_ci#ifndef _WIN32 8351cb0ef41Sopenharmony_ci int r; 8361cb0ef41Sopenharmony_ci#endif 8371cb0ef41Sopenharmony_ci 8381cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_fdstat_get(uvwasi=%p, fd=%d, buf=%p)\n", 8391cb0ef41Sopenharmony_ci uvwasi, 8401cb0ef41Sopenharmony_ci fd, 8411cb0ef41Sopenharmony_ci buf); 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_ci if (uvwasi == NULL || buf == NULL) 8441cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 8451cb0ef41Sopenharmony_ci 8461cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0); 8471cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 8481cb0ef41Sopenharmony_ci return err; 8491cb0ef41Sopenharmony_ci 8501cb0ef41Sopenharmony_ci buf->fs_filetype = wrap->type; 8511cb0ef41Sopenharmony_ci buf->fs_rights_base = wrap->rights_base; 8521cb0ef41Sopenharmony_ci buf->fs_rights_inheriting = wrap->rights_inheriting; 8531cb0ef41Sopenharmony_ci#ifdef _WIN32 8541cb0ef41Sopenharmony_ci buf->fs_flags = 0; /* TODO(cjihrig): Missing Windows support. */ 8551cb0ef41Sopenharmony_ci#else 8561cb0ef41Sopenharmony_ci r = fcntl(wrap->fd, F_GETFL); 8571cb0ef41Sopenharmony_ci if (r < 0) { 8581cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 8591cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 8601cb0ef41Sopenharmony_ci return err; 8611cb0ef41Sopenharmony_ci } 8621cb0ef41Sopenharmony_ci buf->fs_flags = r; 8631cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 8641cb0ef41Sopenharmony_ci 8651cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 8661cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 8671cb0ef41Sopenharmony_ci} 8681cb0ef41Sopenharmony_ci 8691cb0ef41Sopenharmony_ci 8701cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi, 8711cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 8721cb0ef41Sopenharmony_ci uvwasi_fdflags_t flags) { 8731cb0ef41Sopenharmony_ci#ifdef _WIN32 8741cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n", 8751cb0ef41Sopenharmony_ci uvwasi, 8761cb0ef41Sopenharmony_ci fd, 8771cb0ef41Sopenharmony_ci flags); 8781cb0ef41Sopenharmony_ci 8791cb0ef41Sopenharmony_ci /* TODO(cjihrig): Windows is not supported. */ 8801cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 8811cb0ef41Sopenharmony_ci#else 8821cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 8831cb0ef41Sopenharmony_ci uvwasi_errno_t err; 8841cb0ef41Sopenharmony_ci int mapped_flags; 8851cb0ef41Sopenharmony_ci int r; 8861cb0ef41Sopenharmony_ci 8871cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n", 8881cb0ef41Sopenharmony_ci uvwasi, 8891cb0ef41Sopenharmony_ci fd, 8901cb0ef41Sopenharmony_ci flags); 8911cb0ef41Sopenharmony_ci 8921cb0ef41Sopenharmony_ci if (uvwasi == NULL) 8931cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 8941cb0ef41Sopenharmony_ci 8951cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 8961cb0ef41Sopenharmony_ci fd, 8971cb0ef41Sopenharmony_ci &wrap, 8981cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS, 8991cb0ef41Sopenharmony_ci 0); 9001cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 9011cb0ef41Sopenharmony_ci return err; 9021cb0ef41Sopenharmony_ci 9031cb0ef41Sopenharmony_ci mapped_flags = 0; 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci if ((flags & UVWASI_FDFLAG_APPEND) == UVWASI_FDFLAG_APPEND) 9061cb0ef41Sopenharmony_ci mapped_flags |= O_APPEND; 9071cb0ef41Sopenharmony_ci 9081cb0ef41Sopenharmony_ci if ((flags & UVWASI_FDFLAG_DSYNC) == UVWASI_FDFLAG_DSYNC) 9091cb0ef41Sopenharmony_ci#ifdef O_DSYNC 9101cb0ef41Sopenharmony_ci mapped_flags |= O_DSYNC; 9111cb0ef41Sopenharmony_ci#else 9121cb0ef41Sopenharmony_ci mapped_flags |= O_SYNC; 9131cb0ef41Sopenharmony_ci#endif /* O_DSYNC */ 9141cb0ef41Sopenharmony_ci 9151cb0ef41Sopenharmony_ci if ((flags & UVWASI_FDFLAG_NONBLOCK) == UVWASI_FDFLAG_NONBLOCK) 9161cb0ef41Sopenharmony_ci mapped_flags |= O_NONBLOCK; 9171cb0ef41Sopenharmony_ci 9181cb0ef41Sopenharmony_ci if ((flags & UVWASI_FDFLAG_RSYNC) == UVWASI_FDFLAG_RSYNC) 9191cb0ef41Sopenharmony_ci#ifdef O_RSYNC 9201cb0ef41Sopenharmony_ci mapped_flags |= O_RSYNC; 9211cb0ef41Sopenharmony_ci#else 9221cb0ef41Sopenharmony_ci mapped_flags |= O_SYNC; 9231cb0ef41Sopenharmony_ci#endif /* O_RSYNC */ 9241cb0ef41Sopenharmony_ci 9251cb0ef41Sopenharmony_ci if ((flags & UVWASI_FDFLAG_SYNC) == UVWASI_FDFLAG_SYNC) 9261cb0ef41Sopenharmony_ci mapped_flags |= O_SYNC; 9271cb0ef41Sopenharmony_ci 9281cb0ef41Sopenharmony_ci r = fcntl(wrap->fd, F_SETFL, mapped_flags); 9291cb0ef41Sopenharmony_ci if (r < 0) 9301cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 9311cb0ef41Sopenharmony_ci else 9321cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 9331cb0ef41Sopenharmony_ci 9341cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 9351cb0ef41Sopenharmony_ci return err; 9361cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 9371cb0ef41Sopenharmony_ci} 9381cb0ef41Sopenharmony_ci 9391cb0ef41Sopenharmony_ci 9401cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi, 9411cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 9421cb0ef41Sopenharmony_ci uvwasi_rights_t fs_rights_base, 9431cb0ef41Sopenharmony_ci uvwasi_rights_t fs_rights_inheriting 9441cb0ef41Sopenharmony_ci ) { 9451cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 9461cb0ef41Sopenharmony_ci uvwasi_errno_t err; 9471cb0ef41Sopenharmony_ci 9481cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_fdstat_set_rights(uvwasi=%p, fd=%d, " 9491cb0ef41Sopenharmony_ci "fs_rights_base=%"PRIu64", fs_rights_inheriting=%"PRIu64")\n", 9501cb0ef41Sopenharmony_ci uvwasi, 9511cb0ef41Sopenharmony_ci fd, 9521cb0ef41Sopenharmony_ci fs_rights_base, 9531cb0ef41Sopenharmony_ci fs_rights_inheriting); 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci if (uvwasi == NULL) 9561cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 9571cb0ef41Sopenharmony_ci 9581cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0); 9591cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 9601cb0ef41Sopenharmony_ci return err; 9611cb0ef41Sopenharmony_ci 9621cb0ef41Sopenharmony_ci /* Check for attempts to add new permissions. */ 9631cb0ef41Sopenharmony_ci if ((fs_rights_base | wrap->rights_base) > wrap->rights_base) { 9641cb0ef41Sopenharmony_ci err = UVWASI_ENOTCAPABLE; 9651cb0ef41Sopenharmony_ci goto exit; 9661cb0ef41Sopenharmony_ci } 9671cb0ef41Sopenharmony_ci 9681cb0ef41Sopenharmony_ci if ((fs_rights_inheriting | wrap->rights_inheriting) > 9691cb0ef41Sopenharmony_ci wrap->rights_inheriting) { 9701cb0ef41Sopenharmony_ci err = UVWASI_ENOTCAPABLE; 9711cb0ef41Sopenharmony_ci goto exit; 9721cb0ef41Sopenharmony_ci } 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci wrap->rights_base = fs_rights_base; 9751cb0ef41Sopenharmony_ci wrap->rights_inheriting = fs_rights_inheriting; 9761cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 9771cb0ef41Sopenharmony_ciexit: 9781cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 9791cb0ef41Sopenharmony_ci return err; 9801cb0ef41Sopenharmony_ci} 9811cb0ef41Sopenharmony_ci 9821cb0ef41Sopenharmony_ci 9831cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi, 9841cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 9851cb0ef41Sopenharmony_ci uvwasi_filestat_t* buf) { 9861cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 9871cb0ef41Sopenharmony_ci uv_fs_t req; 9881cb0ef41Sopenharmony_ci uvwasi_errno_t err; 9891cb0ef41Sopenharmony_ci int r; 9901cb0ef41Sopenharmony_ci 9911cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_filestat_get(uvwasi=%p, fd=%d, buf=%p)\n", 9921cb0ef41Sopenharmony_ci uvwasi, 9931cb0ef41Sopenharmony_ci fd, 9941cb0ef41Sopenharmony_ci buf); 9951cb0ef41Sopenharmony_ci 9961cb0ef41Sopenharmony_ci if (uvwasi == NULL || buf == NULL) 9971cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 10001cb0ef41Sopenharmony_ci fd, 10011cb0ef41Sopenharmony_ci &wrap, 10021cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_FILESTAT_GET, 10031cb0ef41Sopenharmony_ci 0); 10041cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 10051cb0ef41Sopenharmony_ci return err; 10061cb0ef41Sopenharmony_ci 10071cb0ef41Sopenharmony_ci r = uv_fs_fstat(NULL, &req, wrap->fd, NULL); 10081cb0ef41Sopenharmony_ci if (r != 0) { 10091cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 10101cb0ef41Sopenharmony_ci goto exit; 10111cb0ef41Sopenharmony_ci } 10121cb0ef41Sopenharmony_ci 10131cb0ef41Sopenharmony_ci uvwasi__stat_to_filestat(&req.statbuf, buf); 10141cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 10151cb0ef41Sopenharmony_ciexit: 10161cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 10171cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 10181cb0ef41Sopenharmony_ci return err; 10191cb0ef41Sopenharmony_ci} 10201cb0ef41Sopenharmony_ci 10211cb0ef41Sopenharmony_ci 10221cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi, 10231cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 10241cb0ef41Sopenharmony_ci uvwasi_filesize_t st_size) { 10251cb0ef41Sopenharmony_ci /* TODO(cjihrig): uv_fs_ftruncate() takes an int64_t. st_size is uint64_t. */ 10261cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 10271cb0ef41Sopenharmony_ci uv_fs_t req; 10281cb0ef41Sopenharmony_ci uvwasi_errno_t err; 10291cb0ef41Sopenharmony_ci int r; 10301cb0ef41Sopenharmony_ci 10311cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_filestat_set_size(uvwasi=%p, fd=%d, " 10321cb0ef41Sopenharmony_ci "st_size=%"PRIu64")\n", 10331cb0ef41Sopenharmony_ci uvwasi, 10341cb0ef41Sopenharmony_ci fd, 10351cb0ef41Sopenharmony_ci st_size); 10361cb0ef41Sopenharmony_ci 10371cb0ef41Sopenharmony_ci if (uvwasi == NULL) 10381cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 10391cb0ef41Sopenharmony_ci 10401cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 10411cb0ef41Sopenharmony_ci fd, 10421cb0ef41Sopenharmony_ci &wrap, 10431cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_FILESTAT_SET_SIZE, 10441cb0ef41Sopenharmony_ci 0); 10451cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 10461cb0ef41Sopenharmony_ci return err; 10471cb0ef41Sopenharmony_ci 10481cb0ef41Sopenharmony_ci r = uv_fs_ftruncate(NULL, &req, wrap->fd, st_size, NULL); 10491cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 10501cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 10511cb0ef41Sopenharmony_ci 10521cb0ef41Sopenharmony_ci if (r != 0) 10531cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 10561cb0ef41Sopenharmony_ci} 10571cb0ef41Sopenharmony_ci 10581cb0ef41Sopenharmony_ci 10591cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi, 10601cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 10611cb0ef41Sopenharmony_ci uvwasi_timestamp_t st_atim, 10621cb0ef41Sopenharmony_ci uvwasi_timestamp_t st_mtim, 10631cb0ef41Sopenharmony_ci uvwasi_fstflags_t fst_flags) { 10641cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 10651cb0ef41Sopenharmony_ci uvwasi_timestamp_t atim; 10661cb0ef41Sopenharmony_ci uvwasi_timestamp_t mtim; 10671cb0ef41Sopenharmony_ci uv_fs_t req; 10681cb0ef41Sopenharmony_ci uvwasi_errno_t err; 10691cb0ef41Sopenharmony_ci int r; 10701cb0ef41Sopenharmony_ci 10711cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_filestat_set_times(uvwasi=%p, fd=%d, " 10721cb0ef41Sopenharmony_ci "st_atim=%"PRIu64", st_mtim=%"PRIu64", fst_flags=%d)\n", 10731cb0ef41Sopenharmony_ci uvwasi, 10741cb0ef41Sopenharmony_ci fd, 10751cb0ef41Sopenharmony_ci st_atim, 10761cb0ef41Sopenharmony_ci st_mtim, 10771cb0ef41Sopenharmony_ci fst_flags); 10781cb0ef41Sopenharmony_ci 10791cb0ef41Sopenharmony_ci if (uvwasi == NULL) 10801cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 10811cb0ef41Sopenharmony_ci 10821cb0ef41Sopenharmony_ci VALIDATE_FSTFLAGS_OR_RETURN(fst_flags); 10831cb0ef41Sopenharmony_ci 10841cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 10851cb0ef41Sopenharmony_ci fd, 10861cb0ef41Sopenharmony_ci &wrap, 10871cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_FILESTAT_SET_TIMES, 10881cb0ef41Sopenharmony_ci 0); 10891cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 10901cb0ef41Sopenharmony_ci return err; 10911cb0ef41Sopenharmony_ci 10921cb0ef41Sopenharmony_ci atim = st_atim; 10931cb0ef41Sopenharmony_ci mtim = st_mtim; 10941cb0ef41Sopenharmony_ci err = uvwasi__get_filestat_set_times(&atim, 10951cb0ef41Sopenharmony_ci &mtim, 10961cb0ef41Sopenharmony_ci fst_flags, 10971cb0ef41Sopenharmony_ci &wrap->fd, 10981cb0ef41Sopenharmony_ci NULL); 10991cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 11001cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 11011cb0ef41Sopenharmony_ci return err; 11021cb0ef41Sopenharmony_ci } 11031cb0ef41Sopenharmony_ci 11041cb0ef41Sopenharmony_ci /* libuv does not currently support nanosecond precision. */ 11051cb0ef41Sopenharmony_ci r = uv_fs_futime(NULL, &req, wrap->fd, atim, mtim, NULL); 11061cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 11071cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 11081cb0ef41Sopenharmony_ci 11091cb0ef41Sopenharmony_ci if (r != 0) 11101cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 11131cb0ef41Sopenharmony_ci} 11141cb0ef41Sopenharmony_ci 11151cb0ef41Sopenharmony_ci 11161cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi, 11171cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 11181cb0ef41Sopenharmony_ci const uvwasi_iovec_t* iovs, 11191cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len, 11201cb0ef41Sopenharmony_ci uvwasi_filesize_t offset, 11211cb0ef41Sopenharmony_ci uvwasi_size_t* nread) { 11221cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 11231cb0ef41Sopenharmony_ci uv_buf_t* bufs; 11241cb0ef41Sopenharmony_ci uv_fs_t req; 11251cb0ef41Sopenharmony_ci uvwasi_errno_t err; 11261cb0ef41Sopenharmony_ci size_t uvread; 11271cb0ef41Sopenharmony_ci int r; 11281cb0ef41Sopenharmony_ci 11291cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_pread(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%d, " 11301cb0ef41Sopenharmony_ci "offset=%"PRIu64", nread=%p)\n", 11311cb0ef41Sopenharmony_ci uvwasi, 11321cb0ef41Sopenharmony_ci fd, 11331cb0ef41Sopenharmony_ci iovs, 11341cb0ef41Sopenharmony_ci iovs_len, 11351cb0ef41Sopenharmony_ci offset, 11361cb0ef41Sopenharmony_ci nread); 11371cb0ef41Sopenharmony_ci 11381cb0ef41Sopenharmony_ci if (uvwasi == NULL || iovs == NULL || nread == NULL) 11391cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 11401cb0ef41Sopenharmony_ci 11411cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 11421cb0ef41Sopenharmony_ci fd, 11431cb0ef41Sopenharmony_ci &wrap, 11441cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_READ | UVWASI_RIGHT_FD_SEEK, 11451cb0ef41Sopenharmony_ci 0); 11461cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 11471cb0ef41Sopenharmony_ci return err; 11481cb0ef41Sopenharmony_ci 11491cb0ef41Sopenharmony_ci err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len); 11501cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 11511cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 11521cb0ef41Sopenharmony_ci return err; 11531cb0ef41Sopenharmony_ci } 11541cb0ef41Sopenharmony_ci 11551cb0ef41Sopenharmony_ci r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL); 11561cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 11571cb0ef41Sopenharmony_ci uvread = req.result; 11581cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 11591cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, bufs); 11601cb0ef41Sopenharmony_ci 11611cb0ef41Sopenharmony_ci if (r < 0) 11621cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 11631cb0ef41Sopenharmony_ci 11641cb0ef41Sopenharmony_ci *nread = (uvwasi_size_t) uvread; 11651cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 11661cb0ef41Sopenharmony_ci} 11671cb0ef41Sopenharmony_ci 11681cb0ef41Sopenharmony_ci 11691cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi, 11701cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 11711cb0ef41Sopenharmony_ci uvwasi_prestat_t* buf) { 11721cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 11731cb0ef41Sopenharmony_ci uvwasi_errno_t err; 11741cb0ef41Sopenharmony_ci 11751cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_prestat_get(uvwasi=%p, fd=%d, buf=%p)\n", 11761cb0ef41Sopenharmony_ci uvwasi, 11771cb0ef41Sopenharmony_ci fd, 11781cb0ef41Sopenharmony_ci buf); 11791cb0ef41Sopenharmony_ci 11801cb0ef41Sopenharmony_ci if (uvwasi == NULL || buf == NULL) 11811cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 11821cb0ef41Sopenharmony_ci 11831cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0); 11841cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 11851cb0ef41Sopenharmony_ci return err; 11861cb0ef41Sopenharmony_ci if (wrap->preopen != 1) { 11871cb0ef41Sopenharmony_ci err = UVWASI_EINVAL; 11881cb0ef41Sopenharmony_ci goto exit; 11891cb0ef41Sopenharmony_ci } 11901cb0ef41Sopenharmony_ci 11911cb0ef41Sopenharmony_ci buf->pr_type = UVWASI_PREOPENTYPE_DIR; 11921cb0ef41Sopenharmony_ci buf->u.dir.pr_name_len = strlen(wrap->path); 11931cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 11941cb0ef41Sopenharmony_ciexit: 11951cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 11961cb0ef41Sopenharmony_ci return err; 11971cb0ef41Sopenharmony_ci} 11981cb0ef41Sopenharmony_ci 11991cb0ef41Sopenharmony_ci 12001cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi, 12011cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 12021cb0ef41Sopenharmony_ci char* path, 12031cb0ef41Sopenharmony_ci uvwasi_size_t path_len) { 12041cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 12051cb0ef41Sopenharmony_ci uvwasi_errno_t err; 12061cb0ef41Sopenharmony_ci size_t size; 12071cb0ef41Sopenharmony_ci 12081cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_prestat_dir_name(uvwasi=%p, fd=%d, path=%p, " 12091cb0ef41Sopenharmony_ci "path_len=%d)\n", 12101cb0ef41Sopenharmony_ci uvwasi, 12111cb0ef41Sopenharmony_ci fd, 12121cb0ef41Sopenharmony_ci path, 12131cb0ef41Sopenharmony_ci path_len); 12141cb0ef41Sopenharmony_ci 12151cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL) 12161cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 12171cb0ef41Sopenharmony_ci 12181cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0); 12191cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 12201cb0ef41Sopenharmony_ci return err; 12211cb0ef41Sopenharmony_ci if (wrap->preopen != 1) { 12221cb0ef41Sopenharmony_ci err = UVWASI_EBADF; 12231cb0ef41Sopenharmony_ci goto exit; 12241cb0ef41Sopenharmony_ci } 12251cb0ef41Sopenharmony_ci 12261cb0ef41Sopenharmony_ci size = strlen(wrap->path); 12271cb0ef41Sopenharmony_ci if (size > (size_t) path_len) { 12281cb0ef41Sopenharmony_ci err = UVWASI_ENOBUFS; 12291cb0ef41Sopenharmony_ci goto exit; 12301cb0ef41Sopenharmony_ci } 12311cb0ef41Sopenharmony_ci 12321cb0ef41Sopenharmony_ci memcpy(path, wrap->path, size); 12331cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 12341cb0ef41Sopenharmony_ciexit: 12351cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 12361cb0ef41Sopenharmony_ci return err; 12371cb0ef41Sopenharmony_ci} 12381cb0ef41Sopenharmony_ci 12391cb0ef41Sopenharmony_ci 12401cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi, 12411cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 12421cb0ef41Sopenharmony_ci const uvwasi_ciovec_t* iovs, 12431cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len, 12441cb0ef41Sopenharmony_ci uvwasi_filesize_t offset, 12451cb0ef41Sopenharmony_ci uvwasi_size_t* nwritten) { 12461cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 12471cb0ef41Sopenharmony_ci uv_buf_t* bufs; 12481cb0ef41Sopenharmony_ci uv_fs_t req; 12491cb0ef41Sopenharmony_ci uvwasi_errno_t err; 12501cb0ef41Sopenharmony_ci size_t uvwritten; 12511cb0ef41Sopenharmony_ci int r; 12521cb0ef41Sopenharmony_ci 12531cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_pwrite(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%d, " 12541cb0ef41Sopenharmony_ci "offset=%"PRIu64", nwritten=%p)\n", 12551cb0ef41Sopenharmony_ci uvwasi, 12561cb0ef41Sopenharmony_ci fd, 12571cb0ef41Sopenharmony_ci iovs, 12581cb0ef41Sopenharmony_ci iovs_len, 12591cb0ef41Sopenharmony_ci offset, 12601cb0ef41Sopenharmony_ci nwritten); 12611cb0ef41Sopenharmony_ci 12621cb0ef41Sopenharmony_ci if (uvwasi == NULL || iovs == NULL || nwritten == NULL) 12631cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 12641cb0ef41Sopenharmony_ci 12651cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 12661cb0ef41Sopenharmony_ci fd, 12671cb0ef41Sopenharmony_ci &wrap, 12681cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_WRITE | UVWASI_RIGHT_FD_SEEK, 12691cb0ef41Sopenharmony_ci 0); 12701cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 12711cb0ef41Sopenharmony_ci return err; 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ci err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len); 12741cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 12751cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 12761cb0ef41Sopenharmony_ci return err; 12771cb0ef41Sopenharmony_ci } 12781cb0ef41Sopenharmony_ci 12791cb0ef41Sopenharmony_ci r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL); 12801cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 12811cb0ef41Sopenharmony_ci uvwritten = req.result; 12821cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 12831cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, bufs); 12841cb0ef41Sopenharmony_ci 12851cb0ef41Sopenharmony_ci if (r < 0) 12861cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 12871cb0ef41Sopenharmony_ci 12881cb0ef41Sopenharmony_ci *nwritten = (uvwasi_size_t) uvwritten; 12891cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 12901cb0ef41Sopenharmony_ci} 12911cb0ef41Sopenharmony_ci 12921cb0ef41Sopenharmony_ci 12931cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi, 12941cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 12951cb0ef41Sopenharmony_ci const uvwasi_iovec_t* iovs, 12961cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len, 12971cb0ef41Sopenharmony_ci uvwasi_size_t* nread) { 12981cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 12991cb0ef41Sopenharmony_ci uv_buf_t* bufs; 13001cb0ef41Sopenharmony_ci uv_fs_t req; 13011cb0ef41Sopenharmony_ci uvwasi_errno_t err; 13021cb0ef41Sopenharmony_ci size_t uvread; 13031cb0ef41Sopenharmony_ci int r; 13041cb0ef41Sopenharmony_ci 13051cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_read(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%d, " 13061cb0ef41Sopenharmony_ci "nread=%p)\n", 13071cb0ef41Sopenharmony_ci uvwasi, 13081cb0ef41Sopenharmony_ci fd, 13091cb0ef41Sopenharmony_ci iovs, 13101cb0ef41Sopenharmony_ci iovs_len, 13111cb0ef41Sopenharmony_ci nread); 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci if (uvwasi == NULL || iovs == NULL || nread == NULL) 13141cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 13151cb0ef41Sopenharmony_ci 13161cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0); 13171cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 13181cb0ef41Sopenharmony_ci return err; 13191cb0ef41Sopenharmony_ci 13201cb0ef41Sopenharmony_ci err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len); 13211cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 13221cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 13231cb0ef41Sopenharmony_ci return err; 13241cb0ef41Sopenharmony_ci } 13251cb0ef41Sopenharmony_ci 13261cb0ef41Sopenharmony_ci r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL); 13271cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 13281cb0ef41Sopenharmony_ci uvread = req.result; 13291cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 13301cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, bufs); 13311cb0ef41Sopenharmony_ci 13321cb0ef41Sopenharmony_ci if (r < 0) 13331cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 13341cb0ef41Sopenharmony_ci 13351cb0ef41Sopenharmony_ci *nread = (uvwasi_size_t) uvread; 13361cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 13371cb0ef41Sopenharmony_ci} 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ci 13401cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi, 13411cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 13421cb0ef41Sopenharmony_ci void* buf, 13431cb0ef41Sopenharmony_ci uvwasi_size_t buf_len, 13441cb0ef41Sopenharmony_ci uvwasi_dircookie_t cookie, 13451cb0ef41Sopenharmony_ci uvwasi_size_t* bufused) { 13461cb0ef41Sopenharmony_ci#if defined(UVWASI_FD_READDIR_SUPPORTED) 13471cb0ef41Sopenharmony_ci /* TODO(cjihrig): Avoid opening and closing the directory on each call. */ 13481cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 13491cb0ef41Sopenharmony_ci uvwasi_dirent_t dirent; 13501cb0ef41Sopenharmony_ci uv_dirent_t dirents[UVWASI__READDIR_NUM_ENTRIES]; 13511cb0ef41Sopenharmony_ci uv_dir_t* dir; 13521cb0ef41Sopenharmony_ci uv_fs_t req; 13531cb0ef41Sopenharmony_ci uvwasi_errno_t err; 13541cb0ef41Sopenharmony_ci size_t name_len; 13551cb0ef41Sopenharmony_ci size_t available; 13561cb0ef41Sopenharmony_ci size_t size_to_cp; 13571cb0ef41Sopenharmony_ci long tell; 13581cb0ef41Sopenharmony_ci int i; 13591cb0ef41Sopenharmony_ci int r; 13601cb0ef41Sopenharmony_ci#endif /* defined(UVWASI_FD_READDIR_SUPPORTED) */ 13611cb0ef41Sopenharmony_ci 13621cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_readdir(uvwasi=%p, fd=%d, buf=%p, buf_len=%d, " 13631cb0ef41Sopenharmony_ci "cookie=%"PRIu64", bufused=%p)\n", 13641cb0ef41Sopenharmony_ci uvwasi, 13651cb0ef41Sopenharmony_ci fd, 13661cb0ef41Sopenharmony_ci buf, 13671cb0ef41Sopenharmony_ci buf_len, 13681cb0ef41Sopenharmony_ci cookie, 13691cb0ef41Sopenharmony_ci bufused); 13701cb0ef41Sopenharmony_ci 13711cb0ef41Sopenharmony_ci if (uvwasi == NULL || buf == NULL || bufused == NULL) 13721cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 13731cb0ef41Sopenharmony_ci 13741cb0ef41Sopenharmony_ci#if defined(UVWASI_FD_READDIR_SUPPORTED) 13751cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 13761cb0ef41Sopenharmony_ci fd, 13771cb0ef41Sopenharmony_ci &wrap, 13781cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_READDIR, 13791cb0ef41Sopenharmony_ci 0); 13801cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 13811cb0ef41Sopenharmony_ci return err; 13821cb0ef41Sopenharmony_ci 13831cb0ef41Sopenharmony_ci /* Open the directory. */ 13841cb0ef41Sopenharmony_ci r = uv_fs_opendir(NULL, &req, wrap->real_path, NULL); 13851cb0ef41Sopenharmony_ci if (r != 0) { 13861cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 13871cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 13881cb0ef41Sopenharmony_ci } 13891cb0ef41Sopenharmony_ci 13901cb0ef41Sopenharmony_ci /* Setup for reading the directory. */ 13911cb0ef41Sopenharmony_ci dir = req.ptr; 13921cb0ef41Sopenharmony_ci dir->dirents = dirents; 13931cb0ef41Sopenharmony_ci dir->nentries = UVWASI__READDIR_NUM_ENTRIES; 13941cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 13951cb0ef41Sopenharmony_ci 13961cb0ef41Sopenharmony_ci /* Seek to the proper location in the directory. */ 13971cb0ef41Sopenharmony_ci if (cookie != UVWASI_DIRCOOKIE_START) 13981cb0ef41Sopenharmony_ci seekdir(dir->dir, cookie); 13991cb0ef41Sopenharmony_ci 14001cb0ef41Sopenharmony_ci /* Read the directory entries into the provided buffer. */ 14011cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 14021cb0ef41Sopenharmony_ci *bufused = 0; 14031cb0ef41Sopenharmony_ci while (0 != (r = uv_fs_readdir(NULL, &req, dir, NULL))) { 14041cb0ef41Sopenharmony_ci if (r < 0) { 14051cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 14061cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 14071cb0ef41Sopenharmony_ci goto exit; 14081cb0ef41Sopenharmony_ci } 14091cb0ef41Sopenharmony_ci 14101cb0ef41Sopenharmony_ci available = 0; 14111cb0ef41Sopenharmony_ci 14121cb0ef41Sopenharmony_ci for (i = 0; i < r; i++) { 14131cb0ef41Sopenharmony_ci tell = telldir(dir->dir); 14141cb0ef41Sopenharmony_ci if (tell < 0) { 14151cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 14161cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 14171cb0ef41Sopenharmony_ci goto exit; 14181cb0ef41Sopenharmony_ci } 14191cb0ef41Sopenharmony_ci 14201cb0ef41Sopenharmony_ci name_len = strlen(dirents[i].name); 14211cb0ef41Sopenharmony_ci dirent.d_next = (uvwasi_dircookie_t) tell; 14221cb0ef41Sopenharmony_ci /* TODO(cjihrig): libuv doesn't provide d_ino, and d_type is not 14231cb0ef41Sopenharmony_ci supported on all platforms. Use stat()? */ 14241cb0ef41Sopenharmony_ci dirent.d_ino = 0; 14251cb0ef41Sopenharmony_ci dirent.d_namlen = name_len; 14261cb0ef41Sopenharmony_ci 14271cb0ef41Sopenharmony_ci switch (dirents[i].type) { 14281cb0ef41Sopenharmony_ci case UV_DIRENT_FILE: 14291cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_REGULAR_FILE; 14301cb0ef41Sopenharmony_ci break; 14311cb0ef41Sopenharmony_ci case UV_DIRENT_DIR: 14321cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_DIRECTORY; 14331cb0ef41Sopenharmony_ci break; 14341cb0ef41Sopenharmony_ci case UV_DIRENT_SOCKET: 14351cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_SOCKET_STREAM; 14361cb0ef41Sopenharmony_ci break; 14371cb0ef41Sopenharmony_ci case UV_DIRENT_LINK: 14381cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_SYMBOLIC_LINK; 14391cb0ef41Sopenharmony_ci break; 14401cb0ef41Sopenharmony_ci case UV_DIRENT_CHAR: 14411cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_CHARACTER_DEVICE; 14421cb0ef41Sopenharmony_ci break; 14431cb0ef41Sopenharmony_ci case UV_DIRENT_BLOCK: 14441cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_BLOCK_DEVICE; 14451cb0ef41Sopenharmony_ci break; 14461cb0ef41Sopenharmony_ci case UV_DIRENT_FIFO: 14471cb0ef41Sopenharmony_ci case UV_DIRENT_UNKNOWN: 14481cb0ef41Sopenharmony_ci default: 14491cb0ef41Sopenharmony_ci dirent.d_type = UVWASI_FILETYPE_UNKNOWN; 14501cb0ef41Sopenharmony_ci break; 14511cb0ef41Sopenharmony_ci } 14521cb0ef41Sopenharmony_ci 14531cb0ef41Sopenharmony_ci /* Write dirent to the buffer if it will fit. */ 14541cb0ef41Sopenharmony_ci if (UVWASI_SERDES_SIZE_dirent_t + *bufused > buf_len) { 14551cb0ef41Sopenharmony_ci /* If there are more entries to be written to the buffer we set 14561cb0ef41Sopenharmony_ci * bufused, which is the return value, to the length of the buffer 14571cb0ef41Sopenharmony_ci * which indicates that there are more entries to be read. 14581cb0ef41Sopenharmony_ci */ 14591cb0ef41Sopenharmony_ci *bufused = buf_len; 14601cb0ef41Sopenharmony_ci break; 14611cb0ef41Sopenharmony_ci } 14621cb0ef41Sopenharmony_ci 14631cb0ef41Sopenharmony_ci uvwasi_serdes_write_dirent_t(buf, *bufused, &dirent); 14641cb0ef41Sopenharmony_ci *bufused += UVWASI_SERDES_SIZE_dirent_t; 14651cb0ef41Sopenharmony_ci available = buf_len - *bufused; 14661cb0ef41Sopenharmony_ci 14671cb0ef41Sopenharmony_ci /* Write as much of the entry name to the buffer as possible. */ 14681cb0ef41Sopenharmony_ci size_to_cp = name_len > available ? available : name_len; 14691cb0ef41Sopenharmony_ci memcpy((char*)buf + *bufused, dirents[i].name, size_to_cp); 14701cb0ef41Sopenharmony_ci *bufused += size_to_cp; 14711cb0ef41Sopenharmony_ci available = buf_len - *bufused; 14721cb0ef41Sopenharmony_ci } 14731cb0ef41Sopenharmony_ci 14741cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 14751cb0ef41Sopenharmony_ci 14761cb0ef41Sopenharmony_ci if (available == 0) 14771cb0ef41Sopenharmony_ci break; 14781cb0ef41Sopenharmony_ci } 14791cb0ef41Sopenharmony_ci 14801cb0ef41Sopenharmony_ciexit: 14811cb0ef41Sopenharmony_ci /* Close the directory. */ 14821cb0ef41Sopenharmony_ci r = uv_fs_closedir(NULL, &req, dir, NULL); 14831cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 14841cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 14851cb0ef41Sopenharmony_ci if (r != 0) 14861cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 14871cb0ef41Sopenharmony_ci 14881cb0ef41Sopenharmony_ci return err; 14891cb0ef41Sopenharmony_ci#else 14901cb0ef41Sopenharmony_ci /* TODO(cjihrig): Need a solution for Windows and Android. */ 14911cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 14921cb0ef41Sopenharmony_ci#endif /* defined(UVWASI_FD_READDIR_SUPPORTED) */ 14931cb0ef41Sopenharmony_ci} 14941cb0ef41Sopenharmony_ci 14951cb0ef41Sopenharmony_ci 14961cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi, 14971cb0ef41Sopenharmony_ci uvwasi_fd_t from, 14981cb0ef41Sopenharmony_ci uvwasi_fd_t to) { 14991cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_renumber(uvwasi=%p, from=%d, to=%d)\n", 15001cb0ef41Sopenharmony_ci uvwasi, 15011cb0ef41Sopenharmony_ci from, 15021cb0ef41Sopenharmony_ci to); 15031cb0ef41Sopenharmony_ci 15041cb0ef41Sopenharmony_ci if (uvwasi == NULL) 15051cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 15061cb0ef41Sopenharmony_ci 15071cb0ef41Sopenharmony_ci return uvwasi_fd_table_renumber(uvwasi, uvwasi->fds, to, from); 15081cb0ef41Sopenharmony_ci} 15091cb0ef41Sopenharmony_ci 15101cb0ef41Sopenharmony_ci 15111cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi, 15121cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 15131cb0ef41Sopenharmony_ci uvwasi_filedelta_t offset, 15141cb0ef41Sopenharmony_ci uvwasi_whence_t whence, 15151cb0ef41Sopenharmony_ci uvwasi_filesize_t* newoffset) { 15161cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 15171cb0ef41Sopenharmony_ci uvwasi_errno_t err; 15181cb0ef41Sopenharmony_ci 15191cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_seek(uvwasi=%p, fd=%d, offset=%"PRId64", " 15201cb0ef41Sopenharmony_ci "whence=%d, newoffset=%p)\n", 15211cb0ef41Sopenharmony_ci uvwasi, 15221cb0ef41Sopenharmony_ci fd, 15231cb0ef41Sopenharmony_ci offset, 15241cb0ef41Sopenharmony_ci whence, 15251cb0ef41Sopenharmony_ci newoffset); 15261cb0ef41Sopenharmony_ci 15271cb0ef41Sopenharmony_ci if (uvwasi == NULL || newoffset == NULL) 15281cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 15291cb0ef41Sopenharmony_ci 15301cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0); 15311cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 15321cb0ef41Sopenharmony_ci return err; 15331cb0ef41Sopenharmony_ci 15341cb0ef41Sopenharmony_ci err = uvwasi__lseek(wrap->fd, offset, whence, newoffset); 15351cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 15361cb0ef41Sopenharmony_ci return err; 15371cb0ef41Sopenharmony_ci} 15381cb0ef41Sopenharmony_ci 15391cb0ef41Sopenharmony_ci 15401cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd) { 15411cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 15421cb0ef41Sopenharmony_ci uv_fs_t req; 15431cb0ef41Sopenharmony_ci uvwasi_errno_t err; 15441cb0ef41Sopenharmony_ci int r; 15451cb0ef41Sopenharmony_ci 15461cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_sync(uvwasi=%p, fd=%d)\n", uvwasi, fd); 15471cb0ef41Sopenharmony_ci 15481cb0ef41Sopenharmony_ci if (uvwasi == NULL) 15491cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 15501cb0ef41Sopenharmony_ci 15511cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 15521cb0ef41Sopenharmony_ci fd, 15531cb0ef41Sopenharmony_ci &wrap, 15541cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_SYNC, 15551cb0ef41Sopenharmony_ci 0); 15561cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 15571cb0ef41Sopenharmony_ci return err; 15581cb0ef41Sopenharmony_ci 15591cb0ef41Sopenharmony_ci r = uv_fs_fsync(NULL, &req, wrap->fd, NULL); 15601cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 15611cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 15621cb0ef41Sopenharmony_ci 15631cb0ef41Sopenharmony_ci if (r != 0) 15641cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 15651cb0ef41Sopenharmony_ci 15661cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 15671cb0ef41Sopenharmony_ci} 15681cb0ef41Sopenharmony_ci 15691cb0ef41Sopenharmony_ci 15701cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi, 15711cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 15721cb0ef41Sopenharmony_ci uvwasi_filesize_t* offset) { 15731cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 15741cb0ef41Sopenharmony_ci uvwasi_errno_t err; 15751cb0ef41Sopenharmony_ci 15761cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_tell(uvwasi=%p, fd=%d, offset=%p)\n", 15771cb0ef41Sopenharmony_ci uvwasi, 15781cb0ef41Sopenharmony_ci fd, 15791cb0ef41Sopenharmony_ci offset); 15801cb0ef41Sopenharmony_ci 15811cb0ef41Sopenharmony_ci if (uvwasi == NULL || offset == NULL) 15821cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 15831cb0ef41Sopenharmony_ci 15841cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0); 15851cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 15861cb0ef41Sopenharmony_ci return err; 15871cb0ef41Sopenharmony_ci 15881cb0ef41Sopenharmony_ci err = uvwasi__lseek(wrap->fd, 0, UVWASI_WHENCE_CUR, offset); 15891cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 15901cb0ef41Sopenharmony_ci return err; 15911cb0ef41Sopenharmony_ci} 15921cb0ef41Sopenharmony_ci 15931cb0ef41Sopenharmony_ci 15941cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi, 15951cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 15961cb0ef41Sopenharmony_ci const uvwasi_ciovec_t* iovs, 15971cb0ef41Sopenharmony_ci uvwasi_size_t iovs_len, 15981cb0ef41Sopenharmony_ci uvwasi_size_t* nwritten) { 15991cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 16001cb0ef41Sopenharmony_ci uv_buf_t* bufs; 16011cb0ef41Sopenharmony_ci uv_fs_t req; 16021cb0ef41Sopenharmony_ci uvwasi_errno_t err; 16031cb0ef41Sopenharmony_ci size_t uvwritten; 16041cb0ef41Sopenharmony_ci int r; 16051cb0ef41Sopenharmony_ci 16061cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_fd_write(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%d, " 16071cb0ef41Sopenharmony_ci "nwritten=%p)\n", 16081cb0ef41Sopenharmony_ci uvwasi, 16091cb0ef41Sopenharmony_ci fd, 16101cb0ef41Sopenharmony_ci iovs, 16111cb0ef41Sopenharmony_ci iovs_len, 16121cb0ef41Sopenharmony_ci nwritten); 16131cb0ef41Sopenharmony_ci 16141cb0ef41Sopenharmony_ci if (uvwasi == NULL || iovs == NULL || nwritten == NULL) 16151cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 16161cb0ef41Sopenharmony_ci 16171cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0); 16181cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 16191cb0ef41Sopenharmony_ci return err; 16201cb0ef41Sopenharmony_ci 16211cb0ef41Sopenharmony_ci err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len); 16221cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 16231cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 16241cb0ef41Sopenharmony_ci return err; 16251cb0ef41Sopenharmony_ci } 16261cb0ef41Sopenharmony_ci 16271cb0ef41Sopenharmony_ci r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL); 16281cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 16291cb0ef41Sopenharmony_ci uvwritten = req.result; 16301cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 16311cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, bufs); 16321cb0ef41Sopenharmony_ci 16331cb0ef41Sopenharmony_ci if (r < 0) 16341cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 16351cb0ef41Sopenharmony_ci 16361cb0ef41Sopenharmony_ci *nwritten = (uvwasi_size_t) uvwritten; 16371cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 16381cb0ef41Sopenharmony_ci} 16391cb0ef41Sopenharmony_ci 16401cb0ef41Sopenharmony_ci 16411cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi, 16421cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 16431cb0ef41Sopenharmony_ci const char* path, 16441cb0ef41Sopenharmony_ci uvwasi_size_t path_len) { 16451cb0ef41Sopenharmony_ci char* resolved_path; 16461cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 16471cb0ef41Sopenharmony_ci uv_fs_t req; 16481cb0ef41Sopenharmony_ci uvwasi_errno_t err; 16491cb0ef41Sopenharmony_ci int r; 16501cb0ef41Sopenharmony_ci 16511cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_create_directory(uvwasi=%p, fd=%d, path='%s', " 16521cb0ef41Sopenharmony_ci "path_len=%d)\n", 16531cb0ef41Sopenharmony_ci uvwasi, 16541cb0ef41Sopenharmony_ci fd, 16551cb0ef41Sopenharmony_ci path, 16561cb0ef41Sopenharmony_ci path_len); 16571cb0ef41Sopenharmony_ci 16581cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL) 16591cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 16601cb0ef41Sopenharmony_ci 16611cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 16621cb0ef41Sopenharmony_ci fd, 16631cb0ef41Sopenharmony_ci &wrap, 16641cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_CREATE_DIRECTORY, 16651cb0ef41Sopenharmony_ci 0); 16661cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 16671cb0ef41Sopenharmony_ci return err; 16681cb0ef41Sopenharmony_ci 16691cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0); 16701cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 16711cb0ef41Sopenharmony_ci goto exit; 16721cb0ef41Sopenharmony_ci 16731cb0ef41Sopenharmony_ci r = uv_fs_mkdir(NULL, &req, resolved_path, 0777, NULL); 16741cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 16751cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 16761cb0ef41Sopenharmony_ci 16771cb0ef41Sopenharmony_ci if (r != 0) { 16781cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 16791cb0ef41Sopenharmony_ci goto exit; 16801cb0ef41Sopenharmony_ci } 16811cb0ef41Sopenharmony_ci 16821cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 16831cb0ef41Sopenharmony_ciexit: 16841cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 16851cb0ef41Sopenharmony_ci return err; 16861cb0ef41Sopenharmony_ci} 16871cb0ef41Sopenharmony_ci 16881cb0ef41Sopenharmony_ci 16891cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi, 16901cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 16911cb0ef41Sopenharmony_ci uvwasi_lookupflags_t flags, 16921cb0ef41Sopenharmony_ci const char* path, 16931cb0ef41Sopenharmony_ci uvwasi_size_t path_len, 16941cb0ef41Sopenharmony_ci uvwasi_filestat_t* buf) { 16951cb0ef41Sopenharmony_ci char* resolved_path; 16961cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 16971cb0ef41Sopenharmony_ci uv_fs_t req; 16981cb0ef41Sopenharmony_ci uvwasi_errno_t err; 16991cb0ef41Sopenharmony_ci int r; 17001cb0ef41Sopenharmony_ci 17011cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_filestat_get(uvwasi=%p, fd=%d, flags=%d, " 17021cb0ef41Sopenharmony_ci "path='%s', path_len=%d, buf=%p)\n", 17031cb0ef41Sopenharmony_ci uvwasi, 17041cb0ef41Sopenharmony_ci fd, 17051cb0ef41Sopenharmony_ci flags, 17061cb0ef41Sopenharmony_ci path, 17071cb0ef41Sopenharmony_ci path_len, 17081cb0ef41Sopenharmony_ci buf); 17091cb0ef41Sopenharmony_ci 17101cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL || buf == NULL) 17111cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 17121cb0ef41Sopenharmony_ci 17131cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 17141cb0ef41Sopenharmony_ci fd, 17151cb0ef41Sopenharmony_ci &wrap, 17161cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_FILESTAT_GET, 17171cb0ef41Sopenharmony_ci 0); 17181cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 17191cb0ef41Sopenharmony_ci return err; 17201cb0ef41Sopenharmony_ci 17211cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 17221cb0ef41Sopenharmony_ci wrap, 17231cb0ef41Sopenharmony_ci path, 17241cb0ef41Sopenharmony_ci path_len, 17251cb0ef41Sopenharmony_ci &resolved_path, 17261cb0ef41Sopenharmony_ci flags); 17271cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 17281cb0ef41Sopenharmony_ci goto exit; 17291cb0ef41Sopenharmony_ci 17301cb0ef41Sopenharmony_ci r = uv_fs_lstat(NULL, &req, resolved_path, NULL); 17311cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 17321cb0ef41Sopenharmony_ci if (r != 0) { 17331cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 17341cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 17351cb0ef41Sopenharmony_ci goto exit; 17361cb0ef41Sopenharmony_ci } 17371cb0ef41Sopenharmony_ci 17381cb0ef41Sopenharmony_ci uvwasi__stat_to_filestat(&req.statbuf, buf); 17391cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 17401cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 17411cb0ef41Sopenharmony_ciexit: 17421cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 17431cb0ef41Sopenharmony_ci return err; 17441cb0ef41Sopenharmony_ci} 17451cb0ef41Sopenharmony_ci 17461cb0ef41Sopenharmony_ci 17471cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi, 17481cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 17491cb0ef41Sopenharmony_ci uvwasi_lookupflags_t flags, 17501cb0ef41Sopenharmony_ci const char* path, 17511cb0ef41Sopenharmony_ci uvwasi_size_t path_len, 17521cb0ef41Sopenharmony_ci uvwasi_timestamp_t st_atim, 17531cb0ef41Sopenharmony_ci uvwasi_timestamp_t st_mtim, 17541cb0ef41Sopenharmony_ci uvwasi_fstflags_t fst_flags) { 17551cb0ef41Sopenharmony_ci char* resolved_path; 17561cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 17571cb0ef41Sopenharmony_ci uvwasi_timestamp_t atim; 17581cb0ef41Sopenharmony_ci uvwasi_timestamp_t mtim; 17591cb0ef41Sopenharmony_ci uv_fs_t req; 17601cb0ef41Sopenharmony_ci uvwasi_errno_t err; 17611cb0ef41Sopenharmony_ci int r; 17621cb0ef41Sopenharmony_ci 17631cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_filestat_set_times(uvwasi=%p, fd=%d, " 17641cb0ef41Sopenharmony_ci "flags=%d, path='%s', path_len=%d, " 17651cb0ef41Sopenharmony_ci "st_atim=%"PRIu64", st_mtim=%"PRIu64", fst_flags=%d)\n", 17661cb0ef41Sopenharmony_ci uvwasi, 17671cb0ef41Sopenharmony_ci fd, 17681cb0ef41Sopenharmony_ci flags, 17691cb0ef41Sopenharmony_ci path, 17701cb0ef41Sopenharmony_ci path_len, 17711cb0ef41Sopenharmony_ci st_atim, 17721cb0ef41Sopenharmony_ci st_mtim, 17731cb0ef41Sopenharmony_ci fst_flags); 17741cb0ef41Sopenharmony_ci 17751cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL) 17761cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 17771cb0ef41Sopenharmony_ci 17781cb0ef41Sopenharmony_ci VALIDATE_FSTFLAGS_OR_RETURN(fst_flags); 17791cb0ef41Sopenharmony_ci 17801cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 17811cb0ef41Sopenharmony_ci fd, 17821cb0ef41Sopenharmony_ci &wrap, 17831cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES, 17841cb0ef41Sopenharmony_ci 0); 17851cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 17861cb0ef41Sopenharmony_ci return err; 17871cb0ef41Sopenharmony_ci 17881cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 17891cb0ef41Sopenharmony_ci wrap, 17901cb0ef41Sopenharmony_ci path, 17911cb0ef41Sopenharmony_ci path_len, 17921cb0ef41Sopenharmony_ci &resolved_path, 17931cb0ef41Sopenharmony_ci flags); 17941cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 17951cb0ef41Sopenharmony_ci goto exit; 17961cb0ef41Sopenharmony_ci 17971cb0ef41Sopenharmony_ci atim = st_atim; 17981cb0ef41Sopenharmony_ci mtim = st_mtim; 17991cb0ef41Sopenharmony_ci err = uvwasi__get_filestat_set_times(&atim, 18001cb0ef41Sopenharmony_ci &mtim, 18011cb0ef41Sopenharmony_ci fst_flags, 18021cb0ef41Sopenharmony_ci NULL, 18031cb0ef41Sopenharmony_ci resolved_path); 18041cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 18051cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 18061cb0ef41Sopenharmony_ci goto exit; 18071cb0ef41Sopenharmony_ci } 18081cb0ef41Sopenharmony_ci 18091cb0ef41Sopenharmony_ci /* libuv does not currently support nanosecond precision. */ 18101cb0ef41Sopenharmony_ci r = uv_fs_lutime(NULL, &req, resolved_path, atim, mtim, NULL); 18111cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 18121cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 18131cb0ef41Sopenharmony_ci 18141cb0ef41Sopenharmony_ci if (r != 0) { 18151cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 18161cb0ef41Sopenharmony_ci goto exit; 18171cb0ef41Sopenharmony_ci } 18181cb0ef41Sopenharmony_ci 18191cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 18201cb0ef41Sopenharmony_ciexit: 18211cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 18221cb0ef41Sopenharmony_ci return err; 18231cb0ef41Sopenharmony_ci} 18241cb0ef41Sopenharmony_ci 18251cb0ef41Sopenharmony_ci 18261cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi, 18271cb0ef41Sopenharmony_ci uvwasi_fd_t old_fd, 18281cb0ef41Sopenharmony_ci uvwasi_lookupflags_t old_flags, 18291cb0ef41Sopenharmony_ci const char* old_path, 18301cb0ef41Sopenharmony_ci uvwasi_size_t old_path_len, 18311cb0ef41Sopenharmony_ci uvwasi_fd_t new_fd, 18321cb0ef41Sopenharmony_ci const char* new_path, 18331cb0ef41Sopenharmony_ci uvwasi_size_t new_path_len) { 18341cb0ef41Sopenharmony_ci char* resolved_old_path; 18351cb0ef41Sopenharmony_ci char* resolved_new_path; 18361cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* old_wrap; 18371cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* new_wrap; 18381cb0ef41Sopenharmony_ci uvwasi_errno_t err; 18391cb0ef41Sopenharmony_ci uv_fs_t req; 18401cb0ef41Sopenharmony_ci int r; 18411cb0ef41Sopenharmony_ci 18421cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_link(uvwasi=%p, old_fd=%d, old_flags=%d, " 18431cb0ef41Sopenharmony_ci "old_path='%s', old_path_len=%d, new_fd=%d, new_path='%s', " 18441cb0ef41Sopenharmony_ci "new_path_len=%d)\n", 18451cb0ef41Sopenharmony_ci uvwasi, 18461cb0ef41Sopenharmony_ci old_fd, 18471cb0ef41Sopenharmony_ci old_flags, 18481cb0ef41Sopenharmony_ci old_path, 18491cb0ef41Sopenharmony_ci old_path_len, 18501cb0ef41Sopenharmony_ci new_fd, 18511cb0ef41Sopenharmony_ci new_path, 18521cb0ef41Sopenharmony_ci new_path_len); 18531cb0ef41Sopenharmony_ci 18541cb0ef41Sopenharmony_ci if (uvwasi == NULL || old_path == NULL || new_path == NULL) 18551cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 18561cb0ef41Sopenharmony_ci 18571cb0ef41Sopenharmony_ci uvwasi_fd_table_lock(uvwasi->fds); 18581cb0ef41Sopenharmony_ci 18591cb0ef41Sopenharmony_ci if (old_fd == new_fd) { 18601cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 18611cb0ef41Sopenharmony_ci old_fd, 18621cb0ef41Sopenharmony_ci &old_wrap, 18631cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_LINK_SOURCE | 18641cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_LINK_TARGET, 18651cb0ef41Sopenharmony_ci 0); 18661cb0ef41Sopenharmony_ci new_wrap = old_wrap; 18671cb0ef41Sopenharmony_ci } else { 18681cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 18691cb0ef41Sopenharmony_ci old_fd, 18701cb0ef41Sopenharmony_ci &old_wrap, 18711cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_LINK_SOURCE, 18721cb0ef41Sopenharmony_ci 0); 18731cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 18741cb0ef41Sopenharmony_ci uvwasi_fd_table_unlock(uvwasi->fds); 18751cb0ef41Sopenharmony_ci return err; 18761cb0ef41Sopenharmony_ci } 18771cb0ef41Sopenharmony_ci 18781cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 18791cb0ef41Sopenharmony_ci new_fd, 18801cb0ef41Sopenharmony_ci &new_wrap, 18811cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_LINK_TARGET, 18821cb0ef41Sopenharmony_ci 0); 18831cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 18841cb0ef41Sopenharmony_ci uv_mutex_unlock(&old_wrap->mutex); 18851cb0ef41Sopenharmony_ci } 18861cb0ef41Sopenharmony_ci 18871cb0ef41Sopenharmony_ci uvwasi_fd_table_unlock(uvwasi->fds); 18881cb0ef41Sopenharmony_ci 18891cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 18901cb0ef41Sopenharmony_ci return err; 18911cb0ef41Sopenharmony_ci 18921cb0ef41Sopenharmony_ci resolved_old_path = NULL; 18931cb0ef41Sopenharmony_ci resolved_new_path = NULL; 18941cb0ef41Sopenharmony_ci 18951cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 18961cb0ef41Sopenharmony_ci old_wrap, 18971cb0ef41Sopenharmony_ci old_path, 18981cb0ef41Sopenharmony_ci old_path_len, 18991cb0ef41Sopenharmony_ci &resolved_old_path, 19001cb0ef41Sopenharmony_ci old_flags); 19011cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 19021cb0ef41Sopenharmony_ci goto exit; 19031cb0ef41Sopenharmony_ci 19041cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 19051cb0ef41Sopenharmony_ci new_wrap, 19061cb0ef41Sopenharmony_ci new_path, 19071cb0ef41Sopenharmony_ci new_path_len, 19081cb0ef41Sopenharmony_ci &resolved_new_path, 19091cb0ef41Sopenharmony_ci 0); 19101cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 19111cb0ef41Sopenharmony_ci goto exit; 19121cb0ef41Sopenharmony_ci 19131cb0ef41Sopenharmony_ci r = uv_fs_link(NULL, &req, resolved_old_path, resolved_new_path, NULL); 19141cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 19151cb0ef41Sopenharmony_ci if (r != 0) { 19161cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 19171cb0ef41Sopenharmony_ci goto exit; 19181cb0ef41Sopenharmony_ci } 19191cb0ef41Sopenharmony_ci 19201cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 19211cb0ef41Sopenharmony_ciexit: 19221cb0ef41Sopenharmony_ci uv_mutex_unlock(&new_wrap->mutex); 19231cb0ef41Sopenharmony_ci if (old_fd != new_fd) 19241cb0ef41Sopenharmony_ci uv_mutex_unlock(&old_wrap->mutex); 19251cb0ef41Sopenharmony_ci 19261cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_old_path); 19271cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_new_path); 19281cb0ef41Sopenharmony_ci return err; 19291cb0ef41Sopenharmony_ci} 19301cb0ef41Sopenharmony_ci 19311cb0ef41Sopenharmony_ci 19321cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi, 19331cb0ef41Sopenharmony_ci uvwasi_fd_t dirfd, 19341cb0ef41Sopenharmony_ci uvwasi_lookupflags_t dirflags, 19351cb0ef41Sopenharmony_ci const char* path, 19361cb0ef41Sopenharmony_ci uvwasi_size_t path_len, 19371cb0ef41Sopenharmony_ci uvwasi_oflags_t o_flags, 19381cb0ef41Sopenharmony_ci uvwasi_rights_t fs_rights_base, 19391cb0ef41Sopenharmony_ci uvwasi_rights_t fs_rights_inheriting, 19401cb0ef41Sopenharmony_ci uvwasi_fdflags_t fs_flags, 19411cb0ef41Sopenharmony_ci uvwasi_fd_t* fd) { 19421cb0ef41Sopenharmony_ci char* resolved_path; 19431cb0ef41Sopenharmony_ci uvwasi_rights_t needed_inheriting; 19441cb0ef41Sopenharmony_ci uvwasi_rights_t needed_base; 19451cb0ef41Sopenharmony_ci uvwasi_rights_t max_base; 19461cb0ef41Sopenharmony_ci uvwasi_rights_t max_inheriting; 19471cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* dirfd_wrap; 19481cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t *wrap; 19491cb0ef41Sopenharmony_ci uvwasi_filetype_t filetype; 19501cb0ef41Sopenharmony_ci uvwasi_errno_t err; 19511cb0ef41Sopenharmony_ci uv_fs_t req; 19521cb0ef41Sopenharmony_ci int flags; 19531cb0ef41Sopenharmony_ci int read; 19541cb0ef41Sopenharmony_ci int write; 19551cb0ef41Sopenharmony_ci int r; 19561cb0ef41Sopenharmony_ci 19571cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_open(uvwasi=%p, dirfd=%d, dirflags=%d, path='%s', " 19581cb0ef41Sopenharmony_ci "path_len=%d, o_flags=%d, fs_rights_base=%"PRIu64", " 19591cb0ef41Sopenharmony_ci "fs_rights_inheriting=%"PRIu64", fs_flags=%d, fd=%p)\n", 19601cb0ef41Sopenharmony_ci uvwasi, 19611cb0ef41Sopenharmony_ci dirfd, 19621cb0ef41Sopenharmony_ci dirflags, 19631cb0ef41Sopenharmony_ci path, 19641cb0ef41Sopenharmony_ci path_len, 19651cb0ef41Sopenharmony_ci o_flags, 19661cb0ef41Sopenharmony_ci fs_rights_base, 19671cb0ef41Sopenharmony_ci fs_rights_inheriting, 19681cb0ef41Sopenharmony_ci fs_flags, 19691cb0ef41Sopenharmony_ci fd); 19701cb0ef41Sopenharmony_ci 19711cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL || fd == NULL) 19721cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 19731cb0ef41Sopenharmony_ci 19741cb0ef41Sopenharmony_ci read = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_READ | 19751cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_READDIR)); 19761cb0ef41Sopenharmony_ci write = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_DATASYNC | 19771cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_WRITE | 19781cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_ALLOCATE | 19791cb0ef41Sopenharmony_ci UVWASI_RIGHT_FD_FILESTAT_SET_SIZE)); 19801cb0ef41Sopenharmony_ci flags = write ? read ? UV_FS_O_RDWR : UV_FS_O_WRONLY : UV_FS_O_RDONLY; 19811cb0ef41Sopenharmony_ci needed_base = UVWASI_RIGHT_PATH_OPEN; 19821cb0ef41Sopenharmony_ci needed_inheriting = fs_rights_base | fs_rights_inheriting; 19831cb0ef41Sopenharmony_ci 19841cb0ef41Sopenharmony_ci if ((o_flags & UVWASI_O_CREAT) != 0) { 19851cb0ef41Sopenharmony_ci flags |= UV_FS_O_CREAT; 19861cb0ef41Sopenharmony_ci needed_base |= UVWASI_RIGHT_PATH_CREATE_FILE; 19871cb0ef41Sopenharmony_ci } 19881cb0ef41Sopenharmony_ci if ((o_flags & UVWASI_O_DIRECTORY) != 0) 19891cb0ef41Sopenharmony_ci flags |= UV_FS_O_DIRECTORY; 19901cb0ef41Sopenharmony_ci if ((o_flags & UVWASI_O_EXCL) != 0) 19911cb0ef41Sopenharmony_ci flags |= UV_FS_O_EXCL; 19921cb0ef41Sopenharmony_ci if ((o_flags & UVWASI_O_TRUNC) != 0) { 19931cb0ef41Sopenharmony_ci flags |= UV_FS_O_TRUNC; 19941cb0ef41Sopenharmony_ci needed_base |= UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE; 19951cb0ef41Sopenharmony_ci } 19961cb0ef41Sopenharmony_ci 19971cb0ef41Sopenharmony_ci if ((fs_flags & UVWASI_FDFLAG_APPEND) != 0) 19981cb0ef41Sopenharmony_ci flags |= UV_FS_O_APPEND; 19991cb0ef41Sopenharmony_ci if ((fs_flags & UVWASI_FDFLAG_DSYNC) != 0) { 20001cb0ef41Sopenharmony_ci flags |= UV_FS_O_DSYNC; 20011cb0ef41Sopenharmony_ci needed_inheriting |= UVWASI_RIGHT_FD_DATASYNC; 20021cb0ef41Sopenharmony_ci } 20031cb0ef41Sopenharmony_ci if ((fs_flags & UVWASI_FDFLAG_NONBLOCK) != 0) 20041cb0ef41Sopenharmony_ci flags |= UV_FS_O_NONBLOCK; 20051cb0ef41Sopenharmony_ci if ((fs_flags & UVWASI_FDFLAG_RSYNC) != 0) { 20061cb0ef41Sopenharmony_ci#ifdef O_RSYNC 20071cb0ef41Sopenharmony_ci flags |= O_RSYNC; /* libuv has no UV_FS_O_RSYNC. */ 20081cb0ef41Sopenharmony_ci#else 20091cb0ef41Sopenharmony_ci flags |= UV_FS_O_SYNC; 20101cb0ef41Sopenharmony_ci#endif 20111cb0ef41Sopenharmony_ci needed_inheriting |= UVWASI_RIGHT_FD_SYNC; 20121cb0ef41Sopenharmony_ci } 20131cb0ef41Sopenharmony_ci if ((fs_flags & UVWASI_FDFLAG_SYNC) != 0) { 20141cb0ef41Sopenharmony_ci flags |= UV_FS_O_SYNC; 20151cb0ef41Sopenharmony_ci needed_inheriting |= UVWASI_RIGHT_FD_SYNC; 20161cb0ef41Sopenharmony_ci } 20171cb0ef41Sopenharmony_ci if (write && (flags & (UV_FS_O_APPEND | UV_FS_O_TRUNC)) == 0) 20181cb0ef41Sopenharmony_ci needed_inheriting |= UVWASI_RIGHT_FD_SEEK; 20191cb0ef41Sopenharmony_ci 20201cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 20211cb0ef41Sopenharmony_ci dirfd, 20221cb0ef41Sopenharmony_ci &dirfd_wrap, 20231cb0ef41Sopenharmony_ci needed_base, 20241cb0ef41Sopenharmony_ci needed_inheriting); 20251cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 20261cb0ef41Sopenharmony_ci return err; 20271cb0ef41Sopenharmony_ci 20281cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 20291cb0ef41Sopenharmony_ci dirfd_wrap, 20301cb0ef41Sopenharmony_ci path, 20311cb0ef41Sopenharmony_ci path_len, 20321cb0ef41Sopenharmony_ci &resolved_path, 20331cb0ef41Sopenharmony_ci dirflags); 20341cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 20351cb0ef41Sopenharmony_ci uv_mutex_unlock(&dirfd_wrap->mutex); 20361cb0ef41Sopenharmony_ci return err; 20371cb0ef41Sopenharmony_ci } 20381cb0ef41Sopenharmony_ci 20391cb0ef41Sopenharmony_ci r = uv_fs_open(NULL, &req, resolved_path, flags, 0666, NULL); 20401cb0ef41Sopenharmony_ci uv_mutex_unlock(&dirfd_wrap->mutex); 20411cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 20421cb0ef41Sopenharmony_ci 20431cb0ef41Sopenharmony_ci if (r < 0) { 20441cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 20451cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 20461cb0ef41Sopenharmony_ci } 20471cb0ef41Sopenharmony_ci 20481cb0ef41Sopenharmony_ci /* Not all platforms support UV_FS_O_DIRECTORY, so get the file type and check 20491cb0ef41Sopenharmony_ci it here. */ 20501cb0ef41Sopenharmony_ci err = uvwasi__get_filetype_by_fd(r, &filetype); 20511cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 20521cb0ef41Sopenharmony_ci goto close_file_and_error_exit; 20531cb0ef41Sopenharmony_ci 20541cb0ef41Sopenharmony_ci if ((o_flags & UVWASI_O_DIRECTORY) != 0 && 20551cb0ef41Sopenharmony_ci filetype != UVWASI_FILETYPE_DIRECTORY) { 20561cb0ef41Sopenharmony_ci err = UVWASI_ENOTDIR; 20571cb0ef41Sopenharmony_ci goto close_file_and_error_exit; 20581cb0ef41Sopenharmony_ci } 20591cb0ef41Sopenharmony_ci 20601cb0ef41Sopenharmony_ci err = uvwasi__get_rights(r, flags, filetype, &max_base, &max_inheriting); 20611cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 20621cb0ef41Sopenharmony_ci goto close_file_and_error_exit; 20631cb0ef41Sopenharmony_ci 20641cb0ef41Sopenharmony_ci err = uvwasi_fd_table_insert(uvwasi, 20651cb0ef41Sopenharmony_ci uvwasi->fds, 20661cb0ef41Sopenharmony_ci r, 20671cb0ef41Sopenharmony_ci NULL, 20681cb0ef41Sopenharmony_ci resolved_path, 20691cb0ef41Sopenharmony_ci resolved_path, 20701cb0ef41Sopenharmony_ci filetype, 20711cb0ef41Sopenharmony_ci fs_rights_base & max_base, 20721cb0ef41Sopenharmony_ci fs_rights_inheriting & max_inheriting, 20731cb0ef41Sopenharmony_ci 0, 20741cb0ef41Sopenharmony_ci &wrap); 20751cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 20761cb0ef41Sopenharmony_ci goto close_file_and_error_exit; 20771cb0ef41Sopenharmony_ci 20781cb0ef41Sopenharmony_ci *fd = wrap->id; 20791cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 20801cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 20811cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 20821cb0ef41Sopenharmony_ci 20831cb0ef41Sopenharmony_ciclose_file_and_error_exit: 20841cb0ef41Sopenharmony_ci uv_fs_close(NULL, &req, r, NULL); 20851cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 20861cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 20871cb0ef41Sopenharmony_ci return err; 20881cb0ef41Sopenharmony_ci} 20891cb0ef41Sopenharmony_ci 20901cb0ef41Sopenharmony_ci 20911cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi, 20921cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 20931cb0ef41Sopenharmony_ci const char* path, 20941cb0ef41Sopenharmony_ci uvwasi_size_t path_len, 20951cb0ef41Sopenharmony_ci char* buf, 20961cb0ef41Sopenharmony_ci uvwasi_size_t buf_len, 20971cb0ef41Sopenharmony_ci uvwasi_size_t* bufused) { 20981cb0ef41Sopenharmony_ci char* resolved_path; 20991cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 21001cb0ef41Sopenharmony_ci uvwasi_errno_t err; 21011cb0ef41Sopenharmony_ci uv_fs_t req; 21021cb0ef41Sopenharmony_ci size_t len; 21031cb0ef41Sopenharmony_ci int r; 21041cb0ef41Sopenharmony_ci 21051cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_readlink(uvwasi=%p, fd=%d, path='%s', path_len=%d, " 21061cb0ef41Sopenharmony_ci "buf=%p, buf_len=%d, bufused=%p)\n", 21071cb0ef41Sopenharmony_ci uvwasi, 21081cb0ef41Sopenharmony_ci fd, 21091cb0ef41Sopenharmony_ci path, 21101cb0ef41Sopenharmony_ci path_len, 21111cb0ef41Sopenharmony_ci buf, 21121cb0ef41Sopenharmony_ci buf_len, 21131cb0ef41Sopenharmony_ci bufused); 21141cb0ef41Sopenharmony_ci 21151cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL || buf == NULL || bufused == NULL) 21161cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 21171cb0ef41Sopenharmony_ci 21181cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 21191cb0ef41Sopenharmony_ci fd, 21201cb0ef41Sopenharmony_ci &wrap, 21211cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_READLINK, 21221cb0ef41Sopenharmony_ci 0); 21231cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 21241cb0ef41Sopenharmony_ci return err; 21251cb0ef41Sopenharmony_ci 21261cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0); 21271cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 21281cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 21291cb0ef41Sopenharmony_ci return err; 21301cb0ef41Sopenharmony_ci } 21311cb0ef41Sopenharmony_ci 21321cb0ef41Sopenharmony_ci r = uv_fs_readlink(NULL, &req, resolved_path, NULL); 21331cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 21341cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 21351cb0ef41Sopenharmony_ci if (r != 0) { 21361cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 21371cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 21381cb0ef41Sopenharmony_ci } 21391cb0ef41Sopenharmony_ci 21401cb0ef41Sopenharmony_ci len = strnlen(req.ptr, buf_len); 21411cb0ef41Sopenharmony_ci if (len >= buf_len) { 21421cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 21431cb0ef41Sopenharmony_ci return UVWASI_ENOBUFS; 21441cb0ef41Sopenharmony_ci } 21451cb0ef41Sopenharmony_ci 21461cb0ef41Sopenharmony_ci memcpy(buf, req.ptr, len); 21471cb0ef41Sopenharmony_ci buf[len] = '\0'; 21481cb0ef41Sopenharmony_ci *bufused = len + 1; 21491cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 21501cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 21511cb0ef41Sopenharmony_ci} 21521cb0ef41Sopenharmony_ci 21531cb0ef41Sopenharmony_ci 21541cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi, 21551cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 21561cb0ef41Sopenharmony_ci const char* path, 21571cb0ef41Sopenharmony_ci uvwasi_size_t path_len) { 21581cb0ef41Sopenharmony_ci char* resolved_path; 21591cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 21601cb0ef41Sopenharmony_ci uv_fs_t req; 21611cb0ef41Sopenharmony_ci uvwasi_errno_t err; 21621cb0ef41Sopenharmony_ci int r; 21631cb0ef41Sopenharmony_ci 21641cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_remove_directory(uvwasi=%p, fd=%d, path='%s', " 21651cb0ef41Sopenharmony_ci "path_len=%d)\n", 21661cb0ef41Sopenharmony_ci uvwasi, 21671cb0ef41Sopenharmony_ci fd, 21681cb0ef41Sopenharmony_ci path, 21691cb0ef41Sopenharmony_ci path_len); 21701cb0ef41Sopenharmony_ci 21711cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL) 21721cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 21731cb0ef41Sopenharmony_ci 21741cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 21751cb0ef41Sopenharmony_ci fd, 21761cb0ef41Sopenharmony_ci &wrap, 21771cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_REMOVE_DIRECTORY, 21781cb0ef41Sopenharmony_ci 0); 21791cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 21801cb0ef41Sopenharmony_ci return err; 21811cb0ef41Sopenharmony_ci 21821cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0); 21831cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 21841cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 21851cb0ef41Sopenharmony_ci return err; 21861cb0ef41Sopenharmony_ci } 21871cb0ef41Sopenharmony_ci 21881cb0ef41Sopenharmony_ci r = uv_fs_rmdir(NULL, &req, resolved_path, NULL); 21891cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 21901cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 21911cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 21921cb0ef41Sopenharmony_ci 21931cb0ef41Sopenharmony_ci if (r != 0) 21941cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 21951cb0ef41Sopenharmony_ci 21961cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 21971cb0ef41Sopenharmony_ci} 21981cb0ef41Sopenharmony_ci 21991cb0ef41Sopenharmony_ci 22001cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi, 22011cb0ef41Sopenharmony_ci uvwasi_fd_t old_fd, 22021cb0ef41Sopenharmony_ci const char* old_path, 22031cb0ef41Sopenharmony_ci uvwasi_size_t old_path_len, 22041cb0ef41Sopenharmony_ci uvwasi_fd_t new_fd, 22051cb0ef41Sopenharmony_ci const char* new_path, 22061cb0ef41Sopenharmony_ci uvwasi_size_t new_path_len) { 22071cb0ef41Sopenharmony_ci char* resolved_old_path; 22081cb0ef41Sopenharmony_ci char* resolved_new_path; 22091cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* old_wrap; 22101cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* new_wrap; 22111cb0ef41Sopenharmony_ci uvwasi_errno_t err; 22121cb0ef41Sopenharmony_ci uv_fs_t req; 22131cb0ef41Sopenharmony_ci int r; 22141cb0ef41Sopenharmony_ci 22151cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_rename(uvwasi=%p, old_fd=%d, old_path='%s', " 22161cb0ef41Sopenharmony_ci "old_path_len=%d, new_fd=%d, new_path='%s', new_path_len=%d)\n", 22171cb0ef41Sopenharmony_ci uvwasi, 22181cb0ef41Sopenharmony_ci old_fd, 22191cb0ef41Sopenharmony_ci old_path, 22201cb0ef41Sopenharmony_ci old_path_len, 22211cb0ef41Sopenharmony_ci new_fd, 22221cb0ef41Sopenharmony_ci new_path, 22231cb0ef41Sopenharmony_ci new_path_len); 22241cb0ef41Sopenharmony_ci 22251cb0ef41Sopenharmony_ci if (uvwasi == NULL || old_path == NULL || new_path == NULL) 22261cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 22271cb0ef41Sopenharmony_ci 22281cb0ef41Sopenharmony_ci uvwasi_fd_table_lock(uvwasi->fds); 22291cb0ef41Sopenharmony_ci 22301cb0ef41Sopenharmony_ci if (old_fd == new_fd) { 22311cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 22321cb0ef41Sopenharmony_ci old_fd, 22331cb0ef41Sopenharmony_ci &old_wrap, 22341cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_RENAME_SOURCE | 22351cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_RENAME_TARGET, 22361cb0ef41Sopenharmony_ci 0); 22371cb0ef41Sopenharmony_ci new_wrap = old_wrap; 22381cb0ef41Sopenharmony_ci } else { 22391cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 22401cb0ef41Sopenharmony_ci old_fd, 22411cb0ef41Sopenharmony_ci &old_wrap, 22421cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_RENAME_SOURCE, 22431cb0ef41Sopenharmony_ci 0); 22441cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 22451cb0ef41Sopenharmony_ci uvwasi_fd_table_unlock(uvwasi->fds); 22461cb0ef41Sopenharmony_ci return err; 22471cb0ef41Sopenharmony_ci } 22481cb0ef41Sopenharmony_ci 22491cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get_nolock(uvwasi->fds, 22501cb0ef41Sopenharmony_ci new_fd, 22511cb0ef41Sopenharmony_ci &new_wrap, 22521cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_RENAME_TARGET, 22531cb0ef41Sopenharmony_ci 0); 22541cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 22551cb0ef41Sopenharmony_ci uv_mutex_unlock(&old_wrap->mutex); 22561cb0ef41Sopenharmony_ci } 22571cb0ef41Sopenharmony_ci 22581cb0ef41Sopenharmony_ci uvwasi_fd_table_unlock(uvwasi->fds); 22591cb0ef41Sopenharmony_ci 22601cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 22611cb0ef41Sopenharmony_ci return err; 22621cb0ef41Sopenharmony_ci 22631cb0ef41Sopenharmony_ci resolved_old_path = NULL; 22641cb0ef41Sopenharmony_ci resolved_new_path = NULL; 22651cb0ef41Sopenharmony_ci 22661cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 22671cb0ef41Sopenharmony_ci old_wrap, 22681cb0ef41Sopenharmony_ci old_path, 22691cb0ef41Sopenharmony_ci old_path_len, 22701cb0ef41Sopenharmony_ci &resolved_old_path, 22711cb0ef41Sopenharmony_ci 0); 22721cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 22731cb0ef41Sopenharmony_ci goto exit; 22741cb0ef41Sopenharmony_ci 22751cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 22761cb0ef41Sopenharmony_ci new_wrap, 22771cb0ef41Sopenharmony_ci new_path, 22781cb0ef41Sopenharmony_ci new_path_len, 22791cb0ef41Sopenharmony_ci &resolved_new_path, 22801cb0ef41Sopenharmony_ci 0); 22811cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 22821cb0ef41Sopenharmony_ci goto exit; 22831cb0ef41Sopenharmony_ci 22841cb0ef41Sopenharmony_ci r = uv_fs_rename(NULL, &req, resolved_old_path, resolved_new_path, NULL); 22851cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 22861cb0ef41Sopenharmony_ci if (r != 0) { 22871cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 22881cb0ef41Sopenharmony_ci goto exit; 22891cb0ef41Sopenharmony_ci } 22901cb0ef41Sopenharmony_ci 22911cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 22921cb0ef41Sopenharmony_ciexit: 22931cb0ef41Sopenharmony_ci uv_mutex_unlock(&new_wrap->mutex); 22941cb0ef41Sopenharmony_ci if (old_fd != new_fd) 22951cb0ef41Sopenharmony_ci uv_mutex_unlock(&old_wrap->mutex); 22961cb0ef41Sopenharmony_ci 22971cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_old_path); 22981cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_new_path); 22991cb0ef41Sopenharmony_ci return err; 23001cb0ef41Sopenharmony_ci} 23011cb0ef41Sopenharmony_ci 23021cb0ef41Sopenharmony_ci 23031cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi, 23041cb0ef41Sopenharmony_ci const char* old_path, 23051cb0ef41Sopenharmony_ci uvwasi_size_t old_path_len, 23061cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 23071cb0ef41Sopenharmony_ci const char* new_path, 23081cb0ef41Sopenharmony_ci uvwasi_size_t new_path_len) { 23091cb0ef41Sopenharmony_ci char* resolved_new_path; 23101cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 23111cb0ef41Sopenharmony_ci uvwasi_errno_t err; 23121cb0ef41Sopenharmony_ci uv_fs_t req; 23131cb0ef41Sopenharmony_ci int r; 23141cb0ef41Sopenharmony_ci 23151cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_symlink(uvwasi=%p, old_path='%s', old_path_len=%d, " 23161cb0ef41Sopenharmony_ci "fd=%d, new_path='%s', new_path_len=%d)\n", 23171cb0ef41Sopenharmony_ci uvwasi, 23181cb0ef41Sopenharmony_ci old_path, 23191cb0ef41Sopenharmony_ci old_path_len, 23201cb0ef41Sopenharmony_ci fd, 23211cb0ef41Sopenharmony_ci new_path, 23221cb0ef41Sopenharmony_ci new_path_len); 23231cb0ef41Sopenharmony_ci 23241cb0ef41Sopenharmony_ci if (uvwasi == NULL || old_path == NULL || new_path == NULL) 23251cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 23261cb0ef41Sopenharmony_ci 23271cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 23281cb0ef41Sopenharmony_ci fd, 23291cb0ef41Sopenharmony_ci &wrap, 23301cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_SYMLINK, 23311cb0ef41Sopenharmony_ci 0); 23321cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 23331cb0ef41Sopenharmony_ci return err; 23341cb0ef41Sopenharmony_ci 23351cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, 23361cb0ef41Sopenharmony_ci wrap, 23371cb0ef41Sopenharmony_ci new_path, 23381cb0ef41Sopenharmony_ci new_path_len, 23391cb0ef41Sopenharmony_ci &resolved_new_path, 23401cb0ef41Sopenharmony_ci 0); 23411cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 23421cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 23431cb0ef41Sopenharmony_ci return err; 23441cb0ef41Sopenharmony_ci } 23451cb0ef41Sopenharmony_ci 23461cb0ef41Sopenharmony_ci /* Windows support may require setting the flags option. */ 23471cb0ef41Sopenharmony_ci r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL); 23481cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 23491cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_new_path); 23501cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 23511cb0ef41Sopenharmony_ci if (r != 0) 23521cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 23531cb0ef41Sopenharmony_ci 23541cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 23551cb0ef41Sopenharmony_ci} 23561cb0ef41Sopenharmony_ci 23571cb0ef41Sopenharmony_ci 23581cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi, 23591cb0ef41Sopenharmony_ci uvwasi_fd_t fd, 23601cb0ef41Sopenharmony_ci const char* path, 23611cb0ef41Sopenharmony_ci uvwasi_size_t path_len) { 23621cb0ef41Sopenharmony_ci char* resolved_path; 23631cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 23641cb0ef41Sopenharmony_ci uv_fs_t req; 23651cb0ef41Sopenharmony_ci uvwasi_errno_t err; 23661cb0ef41Sopenharmony_ci int r; 23671cb0ef41Sopenharmony_ci 23681cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_path_unlink_file(uvwasi=%p, fd=%d, path='%s', " 23691cb0ef41Sopenharmony_ci "path_len=%d)\n", 23701cb0ef41Sopenharmony_ci uvwasi, 23711cb0ef41Sopenharmony_ci fd, 23721cb0ef41Sopenharmony_ci path, 23731cb0ef41Sopenharmony_ci path_len); 23741cb0ef41Sopenharmony_ci 23751cb0ef41Sopenharmony_ci if (uvwasi == NULL || path == NULL) 23761cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 23771cb0ef41Sopenharmony_ci 23781cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 23791cb0ef41Sopenharmony_ci fd, 23801cb0ef41Sopenharmony_ci &wrap, 23811cb0ef41Sopenharmony_ci UVWASI_RIGHT_PATH_UNLINK_FILE, 23821cb0ef41Sopenharmony_ci 0); 23831cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 23841cb0ef41Sopenharmony_ci return err; 23851cb0ef41Sopenharmony_ci 23861cb0ef41Sopenharmony_ci err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0); 23871cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 23881cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 23891cb0ef41Sopenharmony_ci return err; 23901cb0ef41Sopenharmony_ci } 23911cb0ef41Sopenharmony_ci 23921cb0ef41Sopenharmony_ci r = uv_fs_unlink(NULL, &req, resolved_path, NULL); 23931cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 23941cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, resolved_path); 23951cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 23961cb0ef41Sopenharmony_ci 23971cb0ef41Sopenharmony_ci if (r != 0) 23981cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 23991cb0ef41Sopenharmony_ci 24001cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 24011cb0ef41Sopenharmony_ci} 24021cb0ef41Sopenharmony_ci 24031cb0ef41Sopenharmony_ci 24041cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi, 24051cb0ef41Sopenharmony_ci const uvwasi_subscription_t* in, 24061cb0ef41Sopenharmony_ci uvwasi_event_t* out, 24071cb0ef41Sopenharmony_ci uvwasi_size_t nsubscriptions, 24081cb0ef41Sopenharmony_ci uvwasi_size_t* nevents) { 24091cb0ef41Sopenharmony_ci struct uvwasi_poll_oneoff_state_t state; 24101cb0ef41Sopenharmony_ci struct uvwasi__poll_fdevent_t* fdevent; 24111cb0ef41Sopenharmony_ci uvwasi_userdata_t timer_userdata; 24121cb0ef41Sopenharmony_ci uvwasi_timestamp_t min_timeout; 24131cb0ef41Sopenharmony_ci uvwasi_timestamp_t cur_timeout; 24141cb0ef41Sopenharmony_ci uvwasi_timestamp_t now; 24151cb0ef41Sopenharmony_ci uvwasi_subscription_t sub; 24161cb0ef41Sopenharmony_ci uvwasi_event_t* event; 24171cb0ef41Sopenharmony_ci uvwasi_errno_t err; 24181cb0ef41Sopenharmony_ci int has_timeout; 24191cb0ef41Sopenharmony_ci uvwasi_size_t i; 24201cb0ef41Sopenharmony_ci 24211cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_poll_oneoff(uvwasi=%p, in=%p, out=%p, " 24221cb0ef41Sopenharmony_ci "nsubscriptions=%d, nevents=%p)\n", 24231cb0ef41Sopenharmony_ci uvwasi, 24241cb0ef41Sopenharmony_ci in, 24251cb0ef41Sopenharmony_ci out, 24261cb0ef41Sopenharmony_ci nsubscriptions, 24271cb0ef41Sopenharmony_ci nevents); 24281cb0ef41Sopenharmony_ci 24291cb0ef41Sopenharmony_ci if (uvwasi == NULL || in == NULL || out == NULL || 24301cb0ef41Sopenharmony_ci nsubscriptions == 0 || nevents == NULL) { 24311cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 24321cb0ef41Sopenharmony_ci } 24331cb0ef41Sopenharmony_ci 24341cb0ef41Sopenharmony_ci *nevents = 0; 24351cb0ef41Sopenharmony_ci err = uvwasi__poll_oneoff_state_init(uvwasi, &state, nsubscriptions); 24361cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 24371cb0ef41Sopenharmony_ci return err; 24381cb0ef41Sopenharmony_ci 24391cb0ef41Sopenharmony_ci timer_userdata = 0; 24401cb0ef41Sopenharmony_ci has_timeout = 0; 24411cb0ef41Sopenharmony_ci min_timeout = 0; 24421cb0ef41Sopenharmony_ci 24431cb0ef41Sopenharmony_ci for (i = 0; i < nsubscriptions; i++) { 24441cb0ef41Sopenharmony_ci sub = in[i]; 24451cb0ef41Sopenharmony_ci 24461cb0ef41Sopenharmony_ci switch (sub.type) { 24471cb0ef41Sopenharmony_ci case UVWASI_EVENTTYPE_CLOCK: 24481cb0ef41Sopenharmony_ci if (sub.u.clock.flags == UVWASI_SUBSCRIPTION_CLOCK_ABSTIME) { 24491cb0ef41Sopenharmony_ci /* Convert absolute time to relative delay. */ 24501cb0ef41Sopenharmony_ci err = uvwasi__clock_gettime_realtime(&now); 24511cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 24521cb0ef41Sopenharmony_ci goto exit; 24531cb0ef41Sopenharmony_ci 24541cb0ef41Sopenharmony_ci cur_timeout = sub.u.clock.timeout - now; 24551cb0ef41Sopenharmony_ci } else { 24561cb0ef41Sopenharmony_ci cur_timeout = sub.u.clock.timeout; 24571cb0ef41Sopenharmony_ci } 24581cb0ef41Sopenharmony_ci 24591cb0ef41Sopenharmony_ci if (has_timeout == 0 || cur_timeout < min_timeout) { 24601cb0ef41Sopenharmony_ci min_timeout = cur_timeout; 24611cb0ef41Sopenharmony_ci timer_userdata = sub.userdata; 24621cb0ef41Sopenharmony_ci has_timeout = 1; 24631cb0ef41Sopenharmony_ci } 24641cb0ef41Sopenharmony_ci 24651cb0ef41Sopenharmony_ci break; 24661cb0ef41Sopenharmony_ci case UVWASI_EVENTTYPE_FD_READ: 24671cb0ef41Sopenharmony_ci case UVWASI_EVENTTYPE_FD_WRITE: 24681cb0ef41Sopenharmony_ci err = uvwasi__poll_oneoff_state_add_fdevent(&state, &sub); 24691cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 24701cb0ef41Sopenharmony_ci goto exit; 24711cb0ef41Sopenharmony_ci 24721cb0ef41Sopenharmony_ci break; 24731cb0ef41Sopenharmony_ci default: 24741cb0ef41Sopenharmony_ci err = UVWASI_EINVAL; 24751cb0ef41Sopenharmony_ci goto exit; 24761cb0ef41Sopenharmony_ci } 24771cb0ef41Sopenharmony_ci } 24781cb0ef41Sopenharmony_ci 24791cb0ef41Sopenharmony_ci if (has_timeout == 1) { 24801cb0ef41Sopenharmony_ci err = uvwasi__poll_oneoff_state_set_timer(&state, min_timeout); 24811cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 24821cb0ef41Sopenharmony_ci goto exit; 24831cb0ef41Sopenharmony_ci } 24841cb0ef41Sopenharmony_ci 24851cb0ef41Sopenharmony_ci /* Handle poll() errors, then timeouts, then happy path. */ 24861cb0ef41Sopenharmony_ci err = uvwasi__poll_oneoff_run(&state); 24871cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 24881cb0ef41Sopenharmony_ci goto exit; 24891cb0ef41Sopenharmony_ci } else if (state.result == 0) { 24901cb0ef41Sopenharmony_ci event = &out[0]; 24911cb0ef41Sopenharmony_ci event->userdata = timer_userdata; 24921cb0ef41Sopenharmony_ci event->error = UVWASI_ESUCCESS; 24931cb0ef41Sopenharmony_ci event->type = UVWASI_EVENTTYPE_CLOCK; 24941cb0ef41Sopenharmony_ci *nevents = 1; 24951cb0ef41Sopenharmony_ci } else { 24961cb0ef41Sopenharmony_ci for (i = 0; i < state.fdevent_cnt; i++) { 24971cb0ef41Sopenharmony_ci fdevent = &state.fdevents[i]; 24981cb0ef41Sopenharmony_ci event = &out[*nevents]; 24991cb0ef41Sopenharmony_ci 25001cb0ef41Sopenharmony_ci event->userdata = fdevent->userdata; 25011cb0ef41Sopenharmony_ci event->error = fdevent->error; 25021cb0ef41Sopenharmony_ci event->type = fdevent->type; 25031cb0ef41Sopenharmony_ci event->u.fd_readwrite.nbytes = 0; 25041cb0ef41Sopenharmony_ci event->u.fd_readwrite.flags = 0; 25051cb0ef41Sopenharmony_ci 25061cb0ef41Sopenharmony_ci if (fdevent->error != UVWASI_ESUCCESS) 25071cb0ef41Sopenharmony_ci ; 25081cb0ef41Sopenharmony_ci else if ((fdevent->revents & UV_DISCONNECT) != 0) 25091cb0ef41Sopenharmony_ci event->u.fd_readwrite.flags = UVWASI_EVENT_FD_READWRITE_HANGUP; 25101cb0ef41Sopenharmony_ci else if ((fdevent->revents & (UV_READABLE | UV_WRITABLE)) != 0) 25111cb0ef41Sopenharmony_ci ; /* TODO(cjihrig): Set nbytes if type is UVWASI_EVENTTYPE_FD_READ. */ 25121cb0ef41Sopenharmony_ci else 25131cb0ef41Sopenharmony_ci continue; 25141cb0ef41Sopenharmony_ci 25151cb0ef41Sopenharmony_ci *nevents = *nevents + 1; 25161cb0ef41Sopenharmony_ci } 25171cb0ef41Sopenharmony_ci } 25181cb0ef41Sopenharmony_ci 25191cb0ef41Sopenharmony_ci err = UVWASI_ESUCCESS; 25201cb0ef41Sopenharmony_ci 25211cb0ef41Sopenharmony_ciexit: 25221cb0ef41Sopenharmony_ci uvwasi__poll_oneoff_state_cleanup(&state); 25231cb0ef41Sopenharmony_ci return err; 25241cb0ef41Sopenharmony_ci} 25251cb0ef41Sopenharmony_ci 25261cb0ef41Sopenharmony_ci 25271cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) { 25281cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_proc_exit(uvwasi=%p, rval=%d)\n", uvwasi, rval); 25291cb0ef41Sopenharmony_ci exit(rval); 25301cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; /* This doesn't happen. */ 25311cb0ef41Sopenharmony_ci} 25321cb0ef41Sopenharmony_ci 25331cb0ef41Sopenharmony_ci 25341cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) { 25351cb0ef41Sopenharmony_ci int r; 25361cb0ef41Sopenharmony_ci 25371cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_proc_raise(uvwasi=%p, sig=%d)\n", uvwasi, sig); 25381cb0ef41Sopenharmony_ci 25391cb0ef41Sopenharmony_ci if (uvwasi == NULL) 25401cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 25411cb0ef41Sopenharmony_ci 25421cb0ef41Sopenharmony_ci r = uvwasi__translate_to_uv_signal(sig); 25431cb0ef41Sopenharmony_ci if (r == -1) 25441cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 25451cb0ef41Sopenharmony_ci 25461cb0ef41Sopenharmony_ci r = uv_kill(uv_os_getpid(), r); 25471cb0ef41Sopenharmony_ci if (r != 0) 25481cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 25491cb0ef41Sopenharmony_ci 25501cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 25511cb0ef41Sopenharmony_ci} 25521cb0ef41Sopenharmony_ci 25531cb0ef41Sopenharmony_ci 25541cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, 25551cb0ef41Sopenharmony_ci void* buf, 25561cb0ef41Sopenharmony_ci uvwasi_size_t buf_len) { 25571cb0ef41Sopenharmony_ci int r; 25581cb0ef41Sopenharmony_ci 25591cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_random_get(uvwasi=%p, buf=%p, buf_len=%d)\n", 25601cb0ef41Sopenharmony_ci uvwasi, 25611cb0ef41Sopenharmony_ci buf, 25621cb0ef41Sopenharmony_ci buf_len); 25631cb0ef41Sopenharmony_ci 25641cb0ef41Sopenharmony_ci if (uvwasi == NULL || buf == NULL) 25651cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 25661cb0ef41Sopenharmony_ci 25671cb0ef41Sopenharmony_ci r = uv_random(NULL, NULL, buf, buf_len, 0, NULL); 25681cb0ef41Sopenharmony_ci if (r != 0) 25691cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 25701cb0ef41Sopenharmony_ci 25711cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 25721cb0ef41Sopenharmony_ci} 25731cb0ef41Sopenharmony_ci 25741cb0ef41Sopenharmony_ci 25751cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) { 25761cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_sched_yield(uvwasi=%p)\n", uvwasi); 25771cb0ef41Sopenharmony_ci 25781cb0ef41Sopenharmony_ci if (uvwasi == NULL) 25791cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 25801cb0ef41Sopenharmony_ci 25811cb0ef41Sopenharmony_ci#ifndef _WIN32 25821cb0ef41Sopenharmony_ci if (0 != sched_yield()) 25831cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); 25841cb0ef41Sopenharmony_ci#else 25851cb0ef41Sopenharmony_ci SwitchToThread(); 25861cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 25871cb0ef41Sopenharmony_ci 25881cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 25891cb0ef41Sopenharmony_ci} 25901cb0ef41Sopenharmony_ci 25911cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi, 25921cb0ef41Sopenharmony_ci uvwasi_fd_t sock, 25931cb0ef41Sopenharmony_ci const uvwasi_iovec_t* ri_data, 25941cb0ef41Sopenharmony_ci uvwasi_size_t ri_data_len, 25951cb0ef41Sopenharmony_ci uvwasi_riflags_t ri_flags, 25961cb0ef41Sopenharmony_ci uvwasi_size_t* ro_datalen, 25971cb0ef41Sopenharmony_ci uvwasi_roflags_t* ro_flags) { 25981cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 25991cb0ef41Sopenharmony_ci uvwasi_errno_t err = 0; 26001cb0ef41Sopenharmony_ci recv_data_t recv_data; 26011cb0ef41Sopenharmony_ci 26021cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_sock_recv(uvwasi=%p, sock=%d, ri_data=%p, " 26031cb0ef41Sopenharmony_ci "ri_data_len=%d, ri_flags=%d, ro_datalen=%p, ro_flags=%p)\n", 26041cb0ef41Sopenharmony_ci uvwasi, 26051cb0ef41Sopenharmony_ci sock, 26061cb0ef41Sopenharmony_ci ri_data, 26071cb0ef41Sopenharmony_ci ri_data_len, 26081cb0ef41Sopenharmony_ci ri_flags, 26091cb0ef41Sopenharmony_ci ro_datalen, 26101cb0ef41Sopenharmony_ci ro_flags); 26111cb0ef41Sopenharmony_ci 26121cb0ef41Sopenharmony_ci if (uvwasi == NULL || ri_data == NULL || ro_datalen == NULL || ro_flags == NULL) 26131cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 26141cb0ef41Sopenharmony_ci 26151cb0ef41Sopenharmony_ci if (ri_flags != 0) 26161cb0ef41Sopenharmony_ci return UVWASI_ENOTSUP; 26171cb0ef41Sopenharmony_ci 26181cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 26191cb0ef41Sopenharmony_ci sock, 26201cb0ef41Sopenharmony_ci &wrap, 26211cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_BASE, 26221cb0ef41Sopenharmony_ci 0); 26231cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 26241cb0ef41Sopenharmony_ci return err; 26251cb0ef41Sopenharmony_ci 26261cb0ef41Sopenharmony_ci recv_data.base = ri_data->buf; 26271cb0ef41Sopenharmony_ci recv_data.len = ri_data->buf_len; 26281cb0ef41Sopenharmony_ci err = read_stream_sync(uvwasi, (uv_stream_t*) wrap->sock, &recv_data); 26291cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 26301cb0ef41Sopenharmony_ci if (err != 0) { 26311cb0ef41Sopenharmony_ci return err; 26321cb0ef41Sopenharmony_ci } 26331cb0ef41Sopenharmony_ci 26341cb0ef41Sopenharmony_ci if (recv_data.nread == 0) { 26351cb0ef41Sopenharmony_ci return UVWASI_EAGAIN; 26361cb0ef41Sopenharmony_ci } else if (recv_data.nread < 0) { 26371cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(recv_data.nread); 26381cb0ef41Sopenharmony_ci } 26391cb0ef41Sopenharmony_ci 26401cb0ef41Sopenharmony_ci *ro_datalen = recv_data.nread; 26411cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 26421cb0ef41Sopenharmony_ci} 26431cb0ef41Sopenharmony_ci 26441cb0ef41Sopenharmony_ci 26451cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi, 26461cb0ef41Sopenharmony_ci uvwasi_fd_t sock, 26471cb0ef41Sopenharmony_ci const uvwasi_ciovec_t* si_data, 26481cb0ef41Sopenharmony_ci uvwasi_size_t si_data_len, 26491cb0ef41Sopenharmony_ci uvwasi_siflags_t si_flags, 26501cb0ef41Sopenharmony_ci uvwasi_size_t* so_datalen) { 26511cb0ef41Sopenharmony_ci 26521cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 26531cb0ef41Sopenharmony_ci uvwasi_errno_t err = 0; 26541cb0ef41Sopenharmony_ci uv_buf_t* bufs; 26551cb0ef41Sopenharmony_ci int r = 0; 26561cb0ef41Sopenharmony_ci 26571cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_sock_send(uvwasi=%p, sock=%d, si_data=%p, " 26581cb0ef41Sopenharmony_ci "si_data_len=%d, si_flags=%d, so_datalen=%p)\n", 26591cb0ef41Sopenharmony_ci uvwasi, 26601cb0ef41Sopenharmony_ci sock, 26611cb0ef41Sopenharmony_ci si_data, 26621cb0ef41Sopenharmony_ci si_data_len, 26631cb0ef41Sopenharmony_ci si_flags, 26641cb0ef41Sopenharmony_ci so_datalen); 26651cb0ef41Sopenharmony_ci 26661cb0ef41Sopenharmony_ci if (uvwasi == NULL || si_data == NULL || so_datalen == NULL || 26671cb0ef41Sopenharmony_ci si_flags != 0) 26681cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 26691cb0ef41Sopenharmony_ci 26701cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 26711cb0ef41Sopenharmony_ci sock, 26721cb0ef41Sopenharmony_ci &wrap, 26731cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_BASE, 26741cb0ef41Sopenharmony_ci 0); 26751cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 26761cb0ef41Sopenharmony_ci return err; 26771cb0ef41Sopenharmony_ci 26781cb0ef41Sopenharmony_ci err = uvwasi__setup_ciovs(uvwasi, &bufs, si_data, si_data_len); 26791cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 26801cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 26811cb0ef41Sopenharmony_ci return err; 26821cb0ef41Sopenharmony_ci } 26831cb0ef41Sopenharmony_ci 26841cb0ef41Sopenharmony_ci r = uv_try_write((uv_stream_t*) wrap->sock, bufs, si_data_len); 26851cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, bufs); 26861cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 26871cb0ef41Sopenharmony_ci if (r < 0) 26881cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 26891cb0ef41Sopenharmony_ci 26901cb0ef41Sopenharmony_ci *so_datalen = (uvwasi_size_t) r; 26911cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 26921cb0ef41Sopenharmony_ci} 26931cb0ef41Sopenharmony_ci 26941cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi, 26951cb0ef41Sopenharmony_ci uvwasi_fd_t sock, 26961cb0ef41Sopenharmony_ci uvwasi_sdflags_t how) { 26971cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 26981cb0ef41Sopenharmony_ci uvwasi_errno_t err = 0; 26991cb0ef41Sopenharmony_ci shutdown_data_t shutdown_data; 27001cb0ef41Sopenharmony_ci 27011cb0ef41Sopenharmony_ci if (how & ~UVWASI_SHUT_WR) 27021cb0ef41Sopenharmony_ci return UVWASI_ENOTSUP; 27031cb0ef41Sopenharmony_ci 27041cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_sock_shutdown(uvwasi=%p, sock=%d, how=%d)\n", 27051cb0ef41Sopenharmony_ci uvwasi, 27061cb0ef41Sopenharmony_ci sock, 27071cb0ef41Sopenharmony_ci how); 27081cb0ef41Sopenharmony_ci 27091cb0ef41Sopenharmony_ci if (uvwasi == NULL) 27101cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 27111cb0ef41Sopenharmony_ci 27121cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 27131cb0ef41Sopenharmony_ci sock, 27141cb0ef41Sopenharmony_ci &wrap, 27151cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_BASE, 27161cb0ef41Sopenharmony_ci 0); 27171cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 27181cb0ef41Sopenharmony_ci return err; 27191cb0ef41Sopenharmony_ci 27201cb0ef41Sopenharmony_ci if (how & UVWASI_SHUT_WR) { 27211cb0ef41Sopenharmony_ci err = shutdown_stream_sync(uvwasi, (uv_stream_t*) wrap->sock, &shutdown_data); 27221cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 27231cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 27241cb0ef41Sopenharmony_ci return err; 27251cb0ef41Sopenharmony_ci } 27261cb0ef41Sopenharmony_ci } 27271cb0ef41Sopenharmony_ci 27281cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 27291cb0ef41Sopenharmony_ci 27301cb0ef41Sopenharmony_ci if (shutdown_data.status != 0) 27311cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(shutdown_data.status); 27321cb0ef41Sopenharmony_ci 27331cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 27341cb0ef41Sopenharmony_ci} 27351cb0ef41Sopenharmony_ci 27361cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi_sock_accept(uvwasi_t* uvwasi, 27371cb0ef41Sopenharmony_ci uvwasi_fd_t sock, 27381cb0ef41Sopenharmony_ci uvwasi_fdflags_t flags, 27391cb0ef41Sopenharmony_ci uvwasi_fd_t* connect_sock) { 27401cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* wrap; 27411cb0ef41Sopenharmony_ci struct uvwasi_fd_wrap_t* connected_wrap; 27421cb0ef41Sopenharmony_ci uvwasi_errno_t err = 0; 27431cb0ef41Sopenharmony_ci uv_loop_t* sock_loop = NULL; 27441cb0ef41Sopenharmony_ci int r = 0; 27451cb0ef41Sopenharmony_ci 27461cb0ef41Sopenharmony_ci UVWASI_DEBUG("uvwasi_sock_accept(uvwasi=%p, sock=%d, flags=%d, " 27471cb0ef41Sopenharmony_ci "connect_sock=%p)\n", 27481cb0ef41Sopenharmony_ci uvwasi, 27491cb0ef41Sopenharmony_ci sock, 27501cb0ef41Sopenharmony_ci flags, 27511cb0ef41Sopenharmony_ci connect_sock); 27521cb0ef41Sopenharmony_ci 27531cb0ef41Sopenharmony_ci if (uvwasi == NULL || connect_sock == NULL) 27541cb0ef41Sopenharmony_ci return UVWASI_EINVAL; 27551cb0ef41Sopenharmony_ci 27561cb0ef41Sopenharmony_ci if (flags & ~UVWASI_FDFLAG_NONBLOCK) 27571cb0ef41Sopenharmony_ci return UVWASI_ENOTSUP; 27581cb0ef41Sopenharmony_ci 27591cb0ef41Sopenharmony_ci err = uvwasi_fd_table_get(uvwasi->fds, 27601cb0ef41Sopenharmony_ci sock, 27611cb0ef41Sopenharmony_ci &wrap, 27621cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_BASE, 27631cb0ef41Sopenharmony_ci 0); 27641cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 27651cb0ef41Sopenharmony_ci return err; 27661cb0ef41Sopenharmony_ci 27671cb0ef41Sopenharmony_ci sock_loop = uv_handle_get_loop((uv_handle_t*) wrap->sock); 27681cb0ef41Sopenharmony_ci uv_tcp_t* uv_connect_sock = (uv_tcp_t*) uvwasi__malloc(uvwasi, sizeof(uv_tcp_t)); 27691cb0ef41Sopenharmony_ci uv_tcp_init(sock_loop, uv_connect_sock); 27701cb0ef41Sopenharmony_ci 27711cb0ef41Sopenharmony_ci r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); 27721cb0ef41Sopenharmony_ci if (r != 0) { 27731cb0ef41Sopenharmony_ci if (r == UV_EAGAIN) { 27741cb0ef41Sopenharmony_ci // if not blocking then just return as we have to wait for a connection 27751cb0ef41Sopenharmony_ci if (flags & UVWASI_FDFLAG_NONBLOCK) { 27761cb0ef41Sopenharmony_ci err = free_handle_sync(uvwasi, (uv_handle_t*) uv_connect_sock); 27771cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 27781cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) { 27791cb0ef41Sopenharmony_ci return err; 27801cb0ef41Sopenharmony_ci } 27811cb0ef41Sopenharmony_ci return UVWASI_EAGAIN; 27821cb0ef41Sopenharmony_ci } 27831cb0ef41Sopenharmony_ci } else { 27841cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 27851cb0ef41Sopenharmony_ci goto close_sock_and_error_exit; 27861cb0ef41Sopenharmony_ci } 27871cb0ef41Sopenharmony_ci 27881cb0ef41Sopenharmony_ci // request was blocking and we have no connection yet. run 27891cb0ef41Sopenharmony_ci // the loop until a connection comes in 27901cb0ef41Sopenharmony_ci while (1) { 27911cb0ef41Sopenharmony_ci err = 0; 27921cb0ef41Sopenharmony_ci if (uv_run(sock_loop, UV_RUN_ONCE) == 0) { 27931cb0ef41Sopenharmony_ci err = UVWASI_ECONNABORTED; 27941cb0ef41Sopenharmony_ci goto close_sock_and_error_exit; 27951cb0ef41Sopenharmony_ci } 27961cb0ef41Sopenharmony_ci 27971cb0ef41Sopenharmony_ci int r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); 27981cb0ef41Sopenharmony_ci if (r == UV_EAGAIN) { 27991cb0ef41Sopenharmony_ci // still no connection or error so run the loop again 28001cb0ef41Sopenharmony_ci continue; 28011cb0ef41Sopenharmony_ci } 28021cb0ef41Sopenharmony_ci 28031cb0ef41Sopenharmony_ci if (r != 0) { 28041cb0ef41Sopenharmony_ci // An error occurred accepting the connection. Break out of the loop and 28051cb0ef41Sopenharmony_ci // report an error. 28061cb0ef41Sopenharmony_ci err = uvwasi__translate_uv_error(r); 28071cb0ef41Sopenharmony_ci goto close_sock_and_error_exit; 28081cb0ef41Sopenharmony_ci } 28091cb0ef41Sopenharmony_ci 28101cb0ef41Sopenharmony_ci // if we get here a new connection was successfully accepted 28111cb0ef41Sopenharmony_ci break; 28121cb0ef41Sopenharmony_ci } 28131cb0ef41Sopenharmony_ci } 28141cb0ef41Sopenharmony_ci 28151cb0ef41Sopenharmony_ci err = uvwasi_fd_table_insert(uvwasi, 28161cb0ef41Sopenharmony_ci uvwasi->fds, 28171cb0ef41Sopenharmony_ci -1, 28181cb0ef41Sopenharmony_ci uv_connect_sock, 28191cb0ef41Sopenharmony_ci NULL, 28201cb0ef41Sopenharmony_ci NULL, 28211cb0ef41Sopenharmony_ci UVWASI_FILETYPE_SOCKET_STREAM, 28221cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_BASE, 28231cb0ef41Sopenharmony_ci UVWASI__RIGHTS_SOCKET_INHERITING, 28241cb0ef41Sopenharmony_ci 1, 28251cb0ef41Sopenharmony_ci &connected_wrap); 28261cb0ef41Sopenharmony_ci 28271cb0ef41Sopenharmony_ci if (err != UVWASI_ESUCCESS) 28281cb0ef41Sopenharmony_ci goto close_sock_and_error_exit; 28291cb0ef41Sopenharmony_ci 28301cb0ef41Sopenharmony_ci *connect_sock = connected_wrap->id; 28311cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 28321cb0ef41Sopenharmony_ci uv_mutex_unlock(&connected_wrap->mutex); 28331cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 28341cb0ef41Sopenharmony_ci 28351cb0ef41Sopenharmony_ciclose_sock_and_error_exit: 28361cb0ef41Sopenharmony_ci uvwasi__free(uvwasi, uv_connect_sock); 28371cb0ef41Sopenharmony_ci uv_mutex_unlock(&wrap->mutex); 28381cb0ef41Sopenharmony_ci return err; 28391cb0ef41Sopenharmony_ci} 28401cb0ef41Sopenharmony_ci 28411cb0ef41Sopenharmony_ci 28421cb0ef41Sopenharmony_ciconst char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code) { 28431cb0ef41Sopenharmony_ci switch (code) { 28441cb0ef41Sopenharmony_ci#define V(errcode) case errcode: return #errcode; 28451cb0ef41Sopenharmony_ci V(UVWASI_E2BIG) 28461cb0ef41Sopenharmony_ci V(UVWASI_EACCES) 28471cb0ef41Sopenharmony_ci V(UVWASI_EADDRINUSE) 28481cb0ef41Sopenharmony_ci V(UVWASI_EADDRNOTAVAIL) 28491cb0ef41Sopenharmony_ci V(UVWASI_EAFNOSUPPORT) 28501cb0ef41Sopenharmony_ci V(UVWASI_EAGAIN) 28511cb0ef41Sopenharmony_ci V(UVWASI_EALREADY) 28521cb0ef41Sopenharmony_ci V(UVWASI_EBADF) 28531cb0ef41Sopenharmony_ci V(UVWASI_EBADMSG) 28541cb0ef41Sopenharmony_ci V(UVWASI_EBUSY) 28551cb0ef41Sopenharmony_ci V(UVWASI_ECANCELED) 28561cb0ef41Sopenharmony_ci V(UVWASI_ECHILD) 28571cb0ef41Sopenharmony_ci V(UVWASI_ECONNABORTED) 28581cb0ef41Sopenharmony_ci V(UVWASI_ECONNREFUSED) 28591cb0ef41Sopenharmony_ci V(UVWASI_ECONNRESET) 28601cb0ef41Sopenharmony_ci V(UVWASI_EDEADLK) 28611cb0ef41Sopenharmony_ci V(UVWASI_EDESTADDRREQ) 28621cb0ef41Sopenharmony_ci V(UVWASI_EDOM) 28631cb0ef41Sopenharmony_ci V(UVWASI_EDQUOT) 28641cb0ef41Sopenharmony_ci V(UVWASI_EEXIST) 28651cb0ef41Sopenharmony_ci V(UVWASI_EFAULT) 28661cb0ef41Sopenharmony_ci V(UVWASI_EFBIG) 28671cb0ef41Sopenharmony_ci V(UVWASI_EHOSTUNREACH) 28681cb0ef41Sopenharmony_ci V(UVWASI_EIDRM) 28691cb0ef41Sopenharmony_ci V(UVWASI_EILSEQ) 28701cb0ef41Sopenharmony_ci V(UVWASI_EINPROGRESS) 28711cb0ef41Sopenharmony_ci V(UVWASI_EINTR) 28721cb0ef41Sopenharmony_ci V(UVWASI_EINVAL) 28731cb0ef41Sopenharmony_ci V(UVWASI_EIO) 28741cb0ef41Sopenharmony_ci V(UVWASI_EISCONN) 28751cb0ef41Sopenharmony_ci V(UVWASI_EISDIR) 28761cb0ef41Sopenharmony_ci V(UVWASI_ELOOP) 28771cb0ef41Sopenharmony_ci V(UVWASI_EMFILE) 28781cb0ef41Sopenharmony_ci V(UVWASI_EMLINK) 28791cb0ef41Sopenharmony_ci V(UVWASI_EMSGSIZE) 28801cb0ef41Sopenharmony_ci V(UVWASI_EMULTIHOP) 28811cb0ef41Sopenharmony_ci V(UVWASI_ENAMETOOLONG) 28821cb0ef41Sopenharmony_ci V(UVWASI_ENETDOWN) 28831cb0ef41Sopenharmony_ci V(UVWASI_ENETRESET) 28841cb0ef41Sopenharmony_ci V(UVWASI_ENETUNREACH) 28851cb0ef41Sopenharmony_ci V(UVWASI_ENFILE) 28861cb0ef41Sopenharmony_ci V(UVWASI_ENOBUFS) 28871cb0ef41Sopenharmony_ci V(UVWASI_ENODEV) 28881cb0ef41Sopenharmony_ci V(UVWASI_ENOENT) 28891cb0ef41Sopenharmony_ci V(UVWASI_ENOEXEC) 28901cb0ef41Sopenharmony_ci V(UVWASI_ENOLCK) 28911cb0ef41Sopenharmony_ci V(UVWASI_ENOLINK) 28921cb0ef41Sopenharmony_ci V(UVWASI_ENOMEM) 28931cb0ef41Sopenharmony_ci V(UVWASI_ENOMSG) 28941cb0ef41Sopenharmony_ci V(UVWASI_ENOPROTOOPT) 28951cb0ef41Sopenharmony_ci V(UVWASI_ENOSPC) 28961cb0ef41Sopenharmony_ci V(UVWASI_ENOSYS) 28971cb0ef41Sopenharmony_ci V(UVWASI_ENOTCONN) 28981cb0ef41Sopenharmony_ci V(UVWASI_ENOTDIR) 28991cb0ef41Sopenharmony_ci V(UVWASI_ENOTEMPTY) 29001cb0ef41Sopenharmony_ci V(UVWASI_ENOTRECOVERABLE) 29011cb0ef41Sopenharmony_ci V(UVWASI_ENOTSOCK) 29021cb0ef41Sopenharmony_ci V(UVWASI_ENOTSUP) 29031cb0ef41Sopenharmony_ci V(UVWASI_ENOTTY) 29041cb0ef41Sopenharmony_ci V(UVWASI_ENXIO) 29051cb0ef41Sopenharmony_ci V(UVWASI_EOVERFLOW) 29061cb0ef41Sopenharmony_ci V(UVWASI_EOWNERDEAD) 29071cb0ef41Sopenharmony_ci V(UVWASI_EPERM) 29081cb0ef41Sopenharmony_ci V(UVWASI_EPIPE) 29091cb0ef41Sopenharmony_ci V(UVWASI_EPROTO) 29101cb0ef41Sopenharmony_ci V(UVWASI_EPROTONOSUPPORT) 29111cb0ef41Sopenharmony_ci V(UVWASI_EPROTOTYPE) 29121cb0ef41Sopenharmony_ci V(UVWASI_ERANGE) 29131cb0ef41Sopenharmony_ci V(UVWASI_EROFS) 29141cb0ef41Sopenharmony_ci V(UVWASI_ESPIPE) 29151cb0ef41Sopenharmony_ci V(UVWASI_ESRCH) 29161cb0ef41Sopenharmony_ci V(UVWASI_ESTALE) 29171cb0ef41Sopenharmony_ci V(UVWASI_ETIMEDOUT) 29181cb0ef41Sopenharmony_ci V(UVWASI_ETXTBSY) 29191cb0ef41Sopenharmony_ci V(UVWASI_EXDEV) 29201cb0ef41Sopenharmony_ci V(UVWASI_ENOTCAPABLE) 29211cb0ef41Sopenharmony_ci V(UVWASI_ESUCCESS) 29221cb0ef41Sopenharmony_ci#undef V 29231cb0ef41Sopenharmony_ci default: 29241cb0ef41Sopenharmony_ci return "UVWASI_UNKNOWN_ERROR"; 29251cb0ef41Sopenharmony_ci } 29261cb0ef41Sopenharmony_ci} 2927