11cb0ef41Sopenharmony_ci#include <sys/stat.h> 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci#ifndef _WIN32 41cb0ef41Sopenharmony_ci# include <sys/types.h> 51cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "uv.h" 81cb0ef41Sopenharmony_ci#include "wasi_types.h" 91cb0ef41Sopenharmony_ci#include "uv_mapping.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) 121cb0ef41Sopenharmony_ci# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 131cb0ef41Sopenharmony_ci#endif 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) 161cb0ef41Sopenharmony_ci# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 171cb0ef41Sopenharmony_ci#endif 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci#if !defined(S_ISCHR) && defined(S_IFMT) && defined(S_IFCHR) 201cb0ef41Sopenharmony_ci# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 211cb0ef41Sopenharmony_ci#endif 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci#if !defined(S_ISLNK) && defined(S_IFMT) && defined(S_IFLNK) 241cb0ef41Sopenharmony_ci# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 251cb0ef41Sopenharmony_ci#endif 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci#if !defined(S_ISFIFO) && defined(S_IFMT) && defined(S_IFIFO) 281cb0ef41Sopenharmony_ci# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 291cb0ef41Sopenharmony_ci#endif 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__translate_uv_error(int err) { 331cb0ef41Sopenharmony_ci switch (err) { 341cb0ef41Sopenharmony_ci case UV_E2BIG: return UVWASI_E2BIG; 351cb0ef41Sopenharmony_ci case UV_EACCES: return UVWASI_EACCES; 361cb0ef41Sopenharmony_ci case UV_EADDRINUSE: return UVWASI_EADDRINUSE; 371cb0ef41Sopenharmony_ci case UV_EADDRNOTAVAIL: return UVWASI_EADDRNOTAVAIL; 381cb0ef41Sopenharmony_ci case UV_EAFNOSUPPORT: return UVWASI_EAFNOSUPPORT; 391cb0ef41Sopenharmony_ci case UV_EAGAIN: return UVWASI_EAGAIN; 401cb0ef41Sopenharmony_ci case UV_EALREADY: return UVWASI_EALREADY; 411cb0ef41Sopenharmony_ci case UV_EBADF: return UVWASI_EBADF; 421cb0ef41Sopenharmony_ci case UV_EBUSY: return UVWASI_EBUSY; 431cb0ef41Sopenharmony_ci case UV_ECANCELED: return UVWASI_ECANCELED; 441cb0ef41Sopenharmony_ci case UV_ECONNABORTED: return UVWASI_ECONNABORTED; 451cb0ef41Sopenharmony_ci case UV_ECONNREFUSED: return UVWASI_ECONNREFUSED; 461cb0ef41Sopenharmony_ci case UV_ECONNRESET: return UVWASI_ECONNRESET; 471cb0ef41Sopenharmony_ci case UV_EDESTADDRREQ: return UVWASI_EDESTADDRREQ; 481cb0ef41Sopenharmony_ci case UV_EEXIST: return UVWASI_EEXIST; 491cb0ef41Sopenharmony_ci case UV_EFAULT: return UVWASI_EFAULT; 501cb0ef41Sopenharmony_ci case UV_EFBIG: return UVWASI_EFBIG; 511cb0ef41Sopenharmony_ci case UV_EHOSTUNREACH: return UVWASI_EHOSTUNREACH; 521cb0ef41Sopenharmony_ci case UV_EINTR: return UVWASI_EINTR; 531cb0ef41Sopenharmony_ci case UV_EINVAL: return UVWASI_EINVAL; 541cb0ef41Sopenharmony_ci case UV_EIO: return UVWASI_EIO; 551cb0ef41Sopenharmony_ci case UV_EISCONN: return UVWASI_EISCONN; 561cb0ef41Sopenharmony_ci case UV_EISDIR: return UVWASI_EISDIR; 571cb0ef41Sopenharmony_ci case UV_ELOOP: return UVWASI_ELOOP; 581cb0ef41Sopenharmony_ci case UV_EMFILE: return UVWASI_EMFILE; 591cb0ef41Sopenharmony_ci case UV_EMLINK: return UVWASI_EMLINK; 601cb0ef41Sopenharmony_ci case UV_EMSGSIZE: return UVWASI_EMSGSIZE; 611cb0ef41Sopenharmony_ci case UV_ENAMETOOLONG: return UVWASI_ENAMETOOLONG; 621cb0ef41Sopenharmony_ci case UV_ENETDOWN: return UVWASI_ENETDOWN; 631cb0ef41Sopenharmony_ci case UV_ENETUNREACH: return UVWASI_ENETUNREACH; 641cb0ef41Sopenharmony_ci case UV_ENFILE: return UVWASI_ENFILE; 651cb0ef41Sopenharmony_ci case UV_ENOBUFS: return UVWASI_ENOBUFS; 661cb0ef41Sopenharmony_ci case UV_ENODEV: return UVWASI_ENODEV; 671cb0ef41Sopenharmony_ci case UV_ENOENT: return UVWASI_ENOENT; 681cb0ef41Sopenharmony_ci case UV_ENOMEM: return UVWASI_ENOMEM; 691cb0ef41Sopenharmony_ci case UV_ENOPROTOOPT: return UVWASI_ENOPROTOOPT; 701cb0ef41Sopenharmony_ci case UV_ENOSPC: return UVWASI_ENOSPC; 711cb0ef41Sopenharmony_ci case UV_ENOSYS: return UVWASI_ENOSYS; 721cb0ef41Sopenharmony_ci case UV_ENOTCONN: return UVWASI_ENOTCONN; 731cb0ef41Sopenharmony_ci case UV_ENOTDIR: return UVWASI_ENOTDIR; 741cb0ef41Sopenharmony_ci /* On at least some AIX machines, ENOTEMPTY and EEXIST are equivalent. */ 751cb0ef41Sopenharmony_ci#if ENOTEMPTY != EEXIST 761cb0ef41Sopenharmony_ci case UV_ENOTEMPTY: return UVWASI_ENOTEMPTY; 771cb0ef41Sopenharmony_ci#endif /* ENOTEMPTY != EEXIST */ 781cb0ef41Sopenharmony_ci case UV_ENOTSOCK: return UVWASI_ENOTSOCK; 791cb0ef41Sopenharmony_ci case UV_ENOTSUP: return UVWASI_ENOTSUP; 801cb0ef41Sopenharmony_ci case UV_ENXIO: return UVWASI_ENXIO; 811cb0ef41Sopenharmony_ci case UV_EPERM: return UVWASI_EPERM; 821cb0ef41Sopenharmony_ci case UV_EPIPE: return UVWASI_EPIPE; 831cb0ef41Sopenharmony_ci case UV_EPROTO: return UVWASI_EPROTO; 841cb0ef41Sopenharmony_ci case UV_EPROTONOSUPPORT: return UVWASI_EPROTONOSUPPORT; 851cb0ef41Sopenharmony_ci case UV_EPROTOTYPE: return UVWASI_EPROTOTYPE; 861cb0ef41Sopenharmony_ci case UV_ERANGE: return UVWASI_ERANGE; 871cb0ef41Sopenharmony_ci case UV_EROFS: return UVWASI_EROFS; 881cb0ef41Sopenharmony_ci case UV_ESPIPE: return UVWASI_ESPIPE; 891cb0ef41Sopenharmony_ci case UV_ESRCH: return UVWASI_ESRCH; 901cb0ef41Sopenharmony_ci case UV_ETIMEDOUT: return UVWASI_ETIMEDOUT; 911cb0ef41Sopenharmony_ci case UV_ETXTBSY: return UVWASI_ETXTBSY; 921cb0ef41Sopenharmony_ci case UV_EXDEV: return UVWASI_EXDEV; 931cb0ef41Sopenharmony_ci case 0: return UVWASI_ESUCCESS; 941cb0ef41Sopenharmony_ci /* The following libuv error codes have no corresponding WASI error code: 951cb0ef41Sopenharmony_ci UV_EAI_ADDRFAMILY, UV_EAI_AGAIN, UV_EAI_BADFLAGS, UV_EAI_BADHINTS, 961cb0ef41Sopenharmony_ci UV_EAI_CANCELED, UV_EAI_FAIL, UV_EAI_FAMILY, UV_EAI_MEMORY, 971cb0ef41Sopenharmony_ci UV_EAI_NODATA, UV_EAI_NONAME, UV_EAI_OVERFLOW, UV_EAI_PROTOCOL, 981cb0ef41Sopenharmony_ci UV_EAI_SERVICE, UV_EAI_SOCKTYPE, UV_ECHARSET, UV_ENONET, UV_EOF, 991cb0ef41Sopenharmony_ci UV_ESHUTDOWN, UV_UNKNOWN 1001cb0ef41Sopenharmony_ci */ 1011cb0ef41Sopenharmony_ci default: 1021cb0ef41Sopenharmony_ci /* libuv errors are < 0 */ 1031cb0ef41Sopenharmony_ci if (err > 0) 1041cb0ef41Sopenharmony_ci return err; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ciint uvwasi__translate_to_uv_signal(uvwasi_signal_t sig) { 1121cb0ef41Sopenharmony_ci switch (sig) { 1131cb0ef41Sopenharmony_ci#ifdef SIGABRT 1141cb0ef41Sopenharmony_ci case UVWASI_SIGABRT: return SIGABRT; 1151cb0ef41Sopenharmony_ci#endif 1161cb0ef41Sopenharmony_ci#ifdef SIGALRM 1171cb0ef41Sopenharmony_ci case UVWASI_SIGALRM: return SIGALRM; 1181cb0ef41Sopenharmony_ci#endif 1191cb0ef41Sopenharmony_ci#ifdef SIGBUS 1201cb0ef41Sopenharmony_ci case UVWASI_SIGBUS: return SIGBUS; 1211cb0ef41Sopenharmony_ci#endif 1221cb0ef41Sopenharmony_ci#ifdef SIGCHLD 1231cb0ef41Sopenharmony_ci case UVWASI_SIGCHLD: return SIGCHLD; 1241cb0ef41Sopenharmony_ci#endif 1251cb0ef41Sopenharmony_ci#ifdef SIGCONT 1261cb0ef41Sopenharmony_ci case UVWASI_SIGCONT: return SIGCONT; 1271cb0ef41Sopenharmony_ci#endif 1281cb0ef41Sopenharmony_ci#ifdef SIGFPE 1291cb0ef41Sopenharmony_ci case UVWASI_SIGFPE: return SIGFPE; 1301cb0ef41Sopenharmony_ci#endif 1311cb0ef41Sopenharmony_ci#ifdef SIGHUP 1321cb0ef41Sopenharmony_ci case UVWASI_SIGHUP: return SIGHUP; 1331cb0ef41Sopenharmony_ci#endif 1341cb0ef41Sopenharmony_ci#ifdef SIGILL 1351cb0ef41Sopenharmony_ci case UVWASI_SIGILL: return SIGILL; 1361cb0ef41Sopenharmony_ci#endif 1371cb0ef41Sopenharmony_ci#ifdef SIGINT 1381cb0ef41Sopenharmony_ci case UVWASI_SIGINT: return SIGINT; 1391cb0ef41Sopenharmony_ci#endif 1401cb0ef41Sopenharmony_ci#ifdef SIGKILL 1411cb0ef41Sopenharmony_ci case UVWASI_SIGKILL: return SIGKILL; 1421cb0ef41Sopenharmony_ci#endif 1431cb0ef41Sopenharmony_ci#ifdef SIGPIPE 1441cb0ef41Sopenharmony_ci case UVWASI_SIGPIPE: return SIGPIPE; 1451cb0ef41Sopenharmony_ci#endif 1461cb0ef41Sopenharmony_ci#ifdef SIGQUIT 1471cb0ef41Sopenharmony_ci case UVWASI_SIGQUIT: return SIGQUIT; 1481cb0ef41Sopenharmony_ci#endif 1491cb0ef41Sopenharmony_ci#ifdef SIGSEGV 1501cb0ef41Sopenharmony_ci case UVWASI_SIGSEGV: return SIGSEGV; 1511cb0ef41Sopenharmony_ci#endif 1521cb0ef41Sopenharmony_ci#ifdef SIGSTOP 1531cb0ef41Sopenharmony_ci case UVWASI_SIGSTOP: return SIGSTOP; 1541cb0ef41Sopenharmony_ci#endif 1551cb0ef41Sopenharmony_ci#ifdef SIGSYS 1561cb0ef41Sopenharmony_ci case UVWASI_SIGSYS: return SIGSYS; 1571cb0ef41Sopenharmony_ci#endif 1581cb0ef41Sopenharmony_ci#ifdef SIGTERM 1591cb0ef41Sopenharmony_ci case UVWASI_SIGTERM: return SIGTERM; 1601cb0ef41Sopenharmony_ci#endif 1611cb0ef41Sopenharmony_ci#ifdef SIGTRAP 1621cb0ef41Sopenharmony_ci case UVWASI_SIGTRAP: return SIGTRAP; 1631cb0ef41Sopenharmony_ci#endif 1641cb0ef41Sopenharmony_ci#ifdef SIGTSTP 1651cb0ef41Sopenharmony_ci case UVWASI_SIGTSTP: return SIGTSTP; 1661cb0ef41Sopenharmony_ci#endif 1671cb0ef41Sopenharmony_ci#ifdef SIGTTIN 1681cb0ef41Sopenharmony_ci case UVWASI_SIGTTIN: return SIGTTIN; 1691cb0ef41Sopenharmony_ci#endif 1701cb0ef41Sopenharmony_ci#ifdef SIGTTOU 1711cb0ef41Sopenharmony_ci case UVWASI_SIGTTOU: return SIGTTOU; 1721cb0ef41Sopenharmony_ci#endif 1731cb0ef41Sopenharmony_ci#ifdef SIGURG 1741cb0ef41Sopenharmony_ci case UVWASI_SIGURG: return SIGURG; 1751cb0ef41Sopenharmony_ci#endif 1761cb0ef41Sopenharmony_ci#ifdef SIGUSR1 1771cb0ef41Sopenharmony_ci case UVWASI_SIGUSR1: return SIGUSR1; 1781cb0ef41Sopenharmony_ci#endif 1791cb0ef41Sopenharmony_ci#ifdef SIGUSR2 1801cb0ef41Sopenharmony_ci case UVWASI_SIGUSR2: return SIGUSR2; 1811cb0ef41Sopenharmony_ci#endif 1821cb0ef41Sopenharmony_ci#ifdef SIGVTALRM 1831cb0ef41Sopenharmony_ci case UVWASI_SIGVTALRM: return SIGVTALRM; 1841cb0ef41Sopenharmony_ci#endif 1851cb0ef41Sopenharmony_ci#ifdef SIGXCPU 1861cb0ef41Sopenharmony_ci case UVWASI_SIGXCPU: return SIGXCPU; 1871cb0ef41Sopenharmony_ci#endif 1881cb0ef41Sopenharmony_ci#ifdef SIGXFSZ 1891cb0ef41Sopenharmony_ci case UVWASI_SIGXFSZ: return SIGXFSZ; 1901cb0ef41Sopenharmony_ci#endif 1911cb0ef41Sopenharmony_ci default: return -1; 1921cb0ef41Sopenharmony_ci } 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ciuvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts) { 1971cb0ef41Sopenharmony_ci /* TODO(cjihrig): Handle overflow. */ 1981cb0ef41Sopenharmony_ci return (uvwasi_timestamp_t) ts->tv_sec * NANOS_PER_SEC + ts->tv_nsec; 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ciuvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat) { 2031cb0ef41Sopenharmony_ci uint64_t mode; 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci mode = stat->st_mode; 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci if (S_ISREG(mode)) 2081cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_REGULAR_FILE; 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci if (S_ISDIR(mode)) 2111cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_DIRECTORY; 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci if (S_ISCHR(mode)) 2141cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_CHARACTER_DEVICE; 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci if (S_ISLNK(mode)) 2171cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_SYMBOLIC_LINK; 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci#ifdef S_ISSOCK 2201cb0ef41Sopenharmony_ci if (S_ISSOCK(mode)) 2211cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_SOCKET_STREAM; 2221cb0ef41Sopenharmony_ci#endif /* S_ISSOCK */ 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci#ifdef S_ISFIFO 2251cb0ef41Sopenharmony_ci if (S_ISFIFO(mode)) 2261cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_SOCKET_STREAM; 2271cb0ef41Sopenharmony_ci#endif /* S_ISFIFO */ 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci#ifdef S_ISBLK 2301cb0ef41Sopenharmony_ci if (S_ISBLK(mode)) 2311cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_BLOCK_DEVICE; 2321cb0ef41Sopenharmony_ci#endif /* S_ISBLK */ 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci return UVWASI_FILETYPE_UNKNOWN; 2351cb0ef41Sopenharmony_ci} 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_civoid uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) { 2391cb0ef41Sopenharmony_ci fs->st_dev = stat->st_dev; 2401cb0ef41Sopenharmony_ci fs->st_ino = stat->st_ino; 2411cb0ef41Sopenharmony_ci fs->st_nlink = stat->st_nlink; 2421cb0ef41Sopenharmony_ci fs->st_size = stat->st_size; 2431cb0ef41Sopenharmony_ci fs->st_filetype = uvwasi__stat_to_filetype(stat); 2441cb0ef41Sopenharmony_ci fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim); 2451cb0ef41Sopenharmony_ci fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim); 2461cb0ef41Sopenharmony_ci fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim); 2471cb0ef41Sopenharmony_ci} 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__get_filetype_by_fd(uv_file fd, uvwasi_filetype_t* type) { 2511cb0ef41Sopenharmony_ci uv_fs_t req; 2521cb0ef41Sopenharmony_ci int r; 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci r = uv_fs_fstat(NULL, &req, fd, NULL); 2551cb0ef41Sopenharmony_ci if (r != 0) { 2561cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci uv_handle_type guess; 2591cb0ef41Sopenharmony_ci /* 2601cb0ef41Sopenharmony_ci Windows can't stat a FILE_TYPE_CHAR, which is guessed 2611cb0ef41Sopenharmony_ci as UV_TTY in "ConsoleMode" or UV_FILE otherwise. 2621cb0ef41Sopenharmony_ci */ 2631cb0ef41Sopenharmony_ci guess = uv_guess_handle(fd); 2641cb0ef41Sopenharmony_ci if (guess == UV_TTY || guess == UV_FILE) { 2651cb0ef41Sopenharmony_ci *type = UVWASI_FILETYPE_CHARACTER_DEVICE; 2661cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 2671cb0ef41Sopenharmony_ci } 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_ci *type = UVWASI_FILETYPE_UNKNOWN; 2701cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 2711cb0ef41Sopenharmony_ci } 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci *type = uvwasi__stat_to_filetype(&req.statbuf); 2741cb0ef41Sopenharmony_ci uv_fs_req_cleanup(&req); 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci if (*type == UVWASI_FILETYPE_SOCKET_STREAM && 2771cb0ef41Sopenharmony_ci uv_guess_handle(fd) == UV_UDP) { 2781cb0ef41Sopenharmony_ci *type = UVWASI_FILETYPE_SOCKET_DGRAM; 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 2821cb0ef41Sopenharmony_ci} 283