xref: /third_party/node/deps/uvwasi/src/uvwasi.c (revision 1cb0ef41)
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