1#include <sys/stat.h> 2 3#ifndef _WIN32 4# include <sys/types.h> 5#endif /* _WIN32 */ 6 7#include "uv.h" 8#include "wasi_types.h" 9#include "uv_mapping.h" 10 11#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) 12# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 13#endif 14 15#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) 16# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 17#endif 18 19#if !defined(S_ISCHR) && defined(S_IFMT) && defined(S_IFCHR) 20# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 21#endif 22 23#if !defined(S_ISLNK) && defined(S_IFMT) && defined(S_IFLNK) 24# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 25#endif 26 27#if !defined(S_ISFIFO) && defined(S_IFMT) && defined(S_IFIFO) 28# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 29#endif 30 31 32uvwasi_errno_t uvwasi__translate_uv_error(int err) { 33 switch (err) { 34 case UV_E2BIG: return UVWASI_E2BIG; 35 case UV_EACCES: return UVWASI_EACCES; 36 case UV_EADDRINUSE: return UVWASI_EADDRINUSE; 37 case UV_EADDRNOTAVAIL: return UVWASI_EADDRNOTAVAIL; 38 case UV_EAFNOSUPPORT: return UVWASI_EAFNOSUPPORT; 39 case UV_EAGAIN: return UVWASI_EAGAIN; 40 case UV_EALREADY: return UVWASI_EALREADY; 41 case UV_EBADF: return UVWASI_EBADF; 42 case UV_EBUSY: return UVWASI_EBUSY; 43 case UV_ECANCELED: return UVWASI_ECANCELED; 44 case UV_ECONNABORTED: return UVWASI_ECONNABORTED; 45 case UV_ECONNREFUSED: return UVWASI_ECONNREFUSED; 46 case UV_ECONNRESET: return UVWASI_ECONNRESET; 47 case UV_EDESTADDRREQ: return UVWASI_EDESTADDRREQ; 48 case UV_EEXIST: return UVWASI_EEXIST; 49 case UV_EFAULT: return UVWASI_EFAULT; 50 case UV_EFBIG: return UVWASI_EFBIG; 51 case UV_EHOSTUNREACH: return UVWASI_EHOSTUNREACH; 52 case UV_EINTR: return UVWASI_EINTR; 53 case UV_EINVAL: return UVWASI_EINVAL; 54 case UV_EIO: return UVWASI_EIO; 55 case UV_EISCONN: return UVWASI_EISCONN; 56 case UV_EISDIR: return UVWASI_EISDIR; 57 case UV_ELOOP: return UVWASI_ELOOP; 58 case UV_EMFILE: return UVWASI_EMFILE; 59 case UV_EMLINK: return UVWASI_EMLINK; 60 case UV_EMSGSIZE: return UVWASI_EMSGSIZE; 61 case UV_ENAMETOOLONG: return UVWASI_ENAMETOOLONG; 62 case UV_ENETDOWN: return UVWASI_ENETDOWN; 63 case UV_ENETUNREACH: return UVWASI_ENETUNREACH; 64 case UV_ENFILE: return UVWASI_ENFILE; 65 case UV_ENOBUFS: return UVWASI_ENOBUFS; 66 case UV_ENODEV: return UVWASI_ENODEV; 67 case UV_ENOENT: return UVWASI_ENOENT; 68 case UV_ENOMEM: return UVWASI_ENOMEM; 69 case UV_ENOPROTOOPT: return UVWASI_ENOPROTOOPT; 70 case UV_ENOSPC: return UVWASI_ENOSPC; 71 case UV_ENOSYS: return UVWASI_ENOSYS; 72 case UV_ENOTCONN: return UVWASI_ENOTCONN; 73 case UV_ENOTDIR: return UVWASI_ENOTDIR; 74 /* On at least some AIX machines, ENOTEMPTY and EEXIST are equivalent. */ 75#if ENOTEMPTY != EEXIST 76 case UV_ENOTEMPTY: return UVWASI_ENOTEMPTY; 77#endif /* ENOTEMPTY != EEXIST */ 78 case UV_ENOTSOCK: return UVWASI_ENOTSOCK; 79 case UV_ENOTSUP: return UVWASI_ENOTSUP; 80 case UV_ENXIO: return UVWASI_ENXIO; 81 case UV_EPERM: return UVWASI_EPERM; 82 case UV_EPIPE: return UVWASI_EPIPE; 83 case UV_EPROTO: return UVWASI_EPROTO; 84 case UV_EPROTONOSUPPORT: return UVWASI_EPROTONOSUPPORT; 85 case UV_EPROTOTYPE: return UVWASI_EPROTOTYPE; 86 case UV_ERANGE: return UVWASI_ERANGE; 87 case UV_EROFS: return UVWASI_EROFS; 88 case UV_ESPIPE: return UVWASI_ESPIPE; 89 case UV_ESRCH: return UVWASI_ESRCH; 90 case UV_ETIMEDOUT: return UVWASI_ETIMEDOUT; 91 case UV_ETXTBSY: return UVWASI_ETXTBSY; 92 case UV_EXDEV: return UVWASI_EXDEV; 93 case 0: return UVWASI_ESUCCESS; 94 /* The following libuv error codes have no corresponding WASI error code: 95 UV_EAI_ADDRFAMILY, UV_EAI_AGAIN, UV_EAI_BADFLAGS, UV_EAI_BADHINTS, 96 UV_EAI_CANCELED, UV_EAI_FAIL, UV_EAI_FAMILY, UV_EAI_MEMORY, 97 UV_EAI_NODATA, UV_EAI_NONAME, UV_EAI_OVERFLOW, UV_EAI_PROTOCOL, 98 UV_EAI_SERVICE, UV_EAI_SOCKTYPE, UV_ECHARSET, UV_ENONET, UV_EOF, 99 UV_ESHUTDOWN, UV_UNKNOWN 100 */ 101 default: 102 /* libuv errors are < 0 */ 103 if (err > 0) 104 return err; 105 106 return UVWASI_ENOSYS; 107 } 108} 109 110 111int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig) { 112 switch (sig) { 113#ifdef SIGABRT 114 case UVWASI_SIGABRT: return SIGABRT; 115#endif 116#ifdef SIGALRM 117 case UVWASI_SIGALRM: return SIGALRM; 118#endif 119#ifdef SIGBUS 120 case UVWASI_SIGBUS: return SIGBUS; 121#endif 122#ifdef SIGCHLD 123 case UVWASI_SIGCHLD: return SIGCHLD; 124#endif 125#ifdef SIGCONT 126 case UVWASI_SIGCONT: return SIGCONT; 127#endif 128#ifdef SIGFPE 129 case UVWASI_SIGFPE: return SIGFPE; 130#endif 131#ifdef SIGHUP 132 case UVWASI_SIGHUP: return SIGHUP; 133#endif 134#ifdef SIGILL 135 case UVWASI_SIGILL: return SIGILL; 136#endif 137#ifdef SIGINT 138 case UVWASI_SIGINT: return SIGINT; 139#endif 140#ifdef SIGKILL 141 case UVWASI_SIGKILL: return SIGKILL; 142#endif 143#ifdef SIGPIPE 144 case UVWASI_SIGPIPE: return SIGPIPE; 145#endif 146#ifdef SIGQUIT 147 case UVWASI_SIGQUIT: return SIGQUIT; 148#endif 149#ifdef SIGSEGV 150 case UVWASI_SIGSEGV: return SIGSEGV; 151#endif 152#ifdef SIGSTOP 153 case UVWASI_SIGSTOP: return SIGSTOP; 154#endif 155#ifdef SIGSYS 156 case UVWASI_SIGSYS: return SIGSYS; 157#endif 158#ifdef SIGTERM 159 case UVWASI_SIGTERM: return SIGTERM; 160#endif 161#ifdef SIGTRAP 162 case UVWASI_SIGTRAP: return SIGTRAP; 163#endif 164#ifdef SIGTSTP 165 case UVWASI_SIGTSTP: return SIGTSTP; 166#endif 167#ifdef SIGTTIN 168 case UVWASI_SIGTTIN: return SIGTTIN; 169#endif 170#ifdef SIGTTOU 171 case UVWASI_SIGTTOU: return SIGTTOU; 172#endif 173#ifdef SIGURG 174 case UVWASI_SIGURG: return SIGURG; 175#endif 176#ifdef SIGUSR1 177 case UVWASI_SIGUSR1: return SIGUSR1; 178#endif 179#ifdef SIGUSR2 180 case UVWASI_SIGUSR2: return SIGUSR2; 181#endif 182#ifdef SIGVTALRM 183 case UVWASI_SIGVTALRM: return SIGVTALRM; 184#endif 185#ifdef SIGXCPU 186 case UVWASI_SIGXCPU: return SIGXCPU; 187#endif 188#ifdef SIGXFSZ 189 case UVWASI_SIGXFSZ: return SIGXFSZ; 190#endif 191 default: return -1; 192 } 193} 194 195 196uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts) { 197 /* TODO(cjihrig): Handle overflow. */ 198 return (uvwasi_timestamp_t) ts->tv_sec * NANOS_PER_SEC + ts->tv_nsec; 199} 200 201 202uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat) { 203 uint64_t mode; 204 205 mode = stat->st_mode; 206 207 if (S_ISREG(mode)) 208 return UVWASI_FILETYPE_REGULAR_FILE; 209 210 if (S_ISDIR(mode)) 211 return UVWASI_FILETYPE_DIRECTORY; 212 213 if (S_ISCHR(mode)) 214 return UVWASI_FILETYPE_CHARACTER_DEVICE; 215 216 if (S_ISLNK(mode)) 217 return UVWASI_FILETYPE_SYMBOLIC_LINK; 218 219#ifdef S_ISSOCK 220 if (S_ISSOCK(mode)) 221 return UVWASI_FILETYPE_SOCKET_STREAM; 222#endif /* S_ISSOCK */ 223 224#ifdef S_ISFIFO 225 if (S_ISFIFO(mode)) 226 return UVWASI_FILETYPE_SOCKET_STREAM; 227#endif /* S_ISFIFO */ 228 229#ifdef S_ISBLK 230 if (S_ISBLK(mode)) 231 return UVWASI_FILETYPE_BLOCK_DEVICE; 232#endif /* S_ISBLK */ 233 234 return UVWASI_FILETYPE_UNKNOWN; 235} 236 237 238void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) { 239 fs->st_dev = stat->st_dev; 240 fs->st_ino = stat->st_ino; 241 fs->st_nlink = stat->st_nlink; 242 fs->st_size = stat->st_size; 243 fs->st_filetype = uvwasi__stat_to_filetype(stat); 244 fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim); 245 fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim); 246 fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim); 247} 248 249 250uvwasi_errno_t uvwasi__get_filetype_by_fd(uv_file fd, uvwasi_filetype_t* type) { 251 uv_fs_t req; 252 int r; 253 254 r = uv_fs_fstat(NULL, &req, fd, NULL); 255 if (r != 0) { 256 uv_fs_req_cleanup(&req); 257 258 uv_handle_type guess; 259 /* 260 Windows can't stat a FILE_TYPE_CHAR, which is guessed 261 as UV_TTY in "ConsoleMode" or UV_FILE otherwise. 262 */ 263 guess = uv_guess_handle(fd); 264 if (guess == UV_TTY || guess == UV_FILE) { 265 *type = UVWASI_FILETYPE_CHARACTER_DEVICE; 266 return UVWASI_ESUCCESS; 267 } 268 269 *type = UVWASI_FILETYPE_UNKNOWN; 270 return uvwasi__translate_uv_error(r); 271 } 272 273 *type = uvwasi__stat_to_filetype(&req.statbuf); 274 uv_fs_req_cleanup(&req); 275 276 if (*type == UVWASI_FILETYPE_SOCKET_STREAM && 277 uv_guess_handle(fd) == UV_UDP) { 278 *type = UVWASI_FILETYPE_SOCKET_DGRAM; 279 } 280 281 return UVWASI_ESUCCESS; 282} 283