1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 */ 21 22#ifndef UV_UNIX_INTERNAL_H_ 23#define UV_UNIX_INTERNAL_H_ 24 25#include "uv-common.h" 26 27#include <assert.h> 28#include <limits.h> /* _POSIX_PATH_MAX, PATH_MAX */ 29#include <stdint.h> 30#include <stdlib.h> /* abort */ 31#include <string.h> /* strrchr */ 32#include <fcntl.h> /* O_CLOEXEC and O_NONBLOCK, if supported. */ 33#include <stdio.h> 34#include <errno.h> 35#include <sys/socket.h> 36#include <sys/stat.h> 37#include <sys/types.h> 38 39#ifdef USE_FFRT 40#include <sys/epoll.h> 41#endif 42 43#define UV_LOOP_MAGIC 0x100B100BU 44#define uv__msan_unpoison(p, n) \ 45 do { \ 46 (void) (p); \ 47 (void) (n); \ 48 } while (0) 49 50#if defined(__has_feature) 51# if __has_feature(memory_sanitizer) 52# include <sanitizer/msan_interface.h> 53# undef uv__msan_unpoison 54# define uv__msan_unpoison __msan_unpoison 55# endif 56#endif 57 58#if defined(__STRICT_ANSI__) 59# define inline __inline 60#endif 61 62#if defined(__MVS__) 63# include "os390-syscalls.h" 64#endif /* __MVS__ */ 65 66#if defined(__sun) 67# include <sys/port.h> 68# include <port.h> 69#endif /* __sun */ 70 71#if defined(_AIX) 72# define reqevents events 73# define rtnevents revents 74# include <sys/poll.h> 75#else 76# include <poll.h> 77#endif /* _AIX */ 78 79#if defined(__APPLE__) && !TARGET_OS_IPHONE 80# include <AvailabilityMacros.h> 81#endif 82 83/* 84 * Define common detection for active Thread Sanitizer 85 * - clang uses __has_feature(thread_sanitizer) 86 * - gcc-7+ uses __SANITIZE_THREAD__ 87 */ 88#if defined(__has_feature) 89# if __has_feature(thread_sanitizer) 90# define __SANITIZE_THREAD__ 1 91# endif 92#endif 93 94#if defined(PATH_MAX) 95# define UV__PATH_MAX PATH_MAX 96#else 97# define UV__PATH_MAX 8192 98#endif 99 100union uv__sockaddr { 101 struct sockaddr_in6 in6; 102 struct sockaddr_in in; 103 struct sockaddr addr; 104}; 105 106#define ACCESS_ONCE(type, var) \ 107 (*(volatile type*) &(var)) 108 109#define ROUND_UP(a, b) \ 110 ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a)) 111 112#define UNREACHABLE() \ 113 do { \ 114 assert(0 && "unreachable code"); \ 115 abort(); \ 116 } \ 117 while (0) 118 119#define SAVE_ERRNO(block) \ 120 do { \ 121 int _saved_errno = errno; \ 122 do { block; } while (0); \ 123 errno = _saved_errno; \ 124 } \ 125 while (0) 126 127/* The __clang__ and __INTEL_COMPILER checks are superfluous because they 128 * define __GNUC__. They are here to convey to you, dear reader, that these 129 * macros are enabled when compiling with clang or icc. 130 */ 131#if defined(__clang__) || \ 132 defined(__GNUC__) || \ 133 defined(__INTEL_COMPILER) 134# define UV_UNUSED(declaration) __attribute__((unused)) declaration 135#else 136# define UV_UNUSED(declaration) declaration 137#endif 138 139/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */ 140#ifdef POLLRDHUP 141# define UV__POLLRDHUP POLLRDHUP 142#else 143# define UV__POLLRDHUP 0x2000 144#endif 145 146#ifdef POLLPRI 147# define UV__POLLPRI POLLPRI 148#else 149# define UV__POLLPRI 0 150#endif 151 152#if !defined(O_CLOEXEC) && defined(__FreeBSD__) 153/* 154 * It may be that we are just missing `__POSIX_VISIBLE >= 200809`. 155 * Try using fixed value const and give up, if it doesn't work 156 */ 157# define O_CLOEXEC 0x00100000 158#endif 159 160typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t; 161 162/* loop flags */ 163enum { 164 UV_LOOP_BLOCK_SIGPROF = 0x1, 165 UV_LOOP_REAP_CHILDREN = 0x2 166}; 167 168/* flags of excluding ifaddr */ 169enum { 170 UV__EXCLUDE_IFPHYS, 171 UV__EXCLUDE_IFADDR 172}; 173 174typedef enum { 175 UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ 176 UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ 177} uv_clocktype_t; 178 179struct uv__stream_queued_fds_s { 180 unsigned int size; 181 unsigned int offset; 182 int fds[1]; 183}; 184 185#ifdef __linux__ 186struct uv__statx_timestamp { 187 int64_t tv_sec; 188 uint32_t tv_nsec; 189 int32_t unused0; 190}; 191 192struct uv__statx { 193 uint32_t stx_mask; 194 uint32_t stx_blksize; 195 uint64_t stx_attributes; 196 uint32_t stx_nlink; 197 uint32_t stx_uid; 198 uint32_t stx_gid; 199 uint16_t stx_mode; 200 uint16_t unused0; 201 uint64_t stx_ino; 202 uint64_t stx_size; 203 uint64_t stx_blocks; 204 uint64_t stx_attributes_mask; 205 struct uv__statx_timestamp stx_atime; 206 struct uv__statx_timestamp stx_btime; 207 struct uv__statx_timestamp stx_ctime; 208 struct uv__statx_timestamp stx_mtime; 209 uint32_t stx_rdev_major; 210 uint32_t stx_rdev_minor; 211 uint32_t stx_dev_major; 212 uint32_t stx_dev_minor; 213 uint64_t unused1[14]; 214}; 215#endif /* __linux__ */ 216 217#if defined(_AIX) || \ 218 defined(__APPLE__) || \ 219 defined(__DragonFly__) || \ 220 defined(__FreeBSD__) || \ 221 defined(__linux__) || \ 222 defined(__OpenBSD__) || \ 223 defined(__NetBSD__) 224#define uv__nonblock uv__nonblock_ioctl 225#define UV__NONBLOCK_IS_IOCTL 1 226#else 227#define uv__nonblock uv__nonblock_fcntl 228#define UV__NONBLOCK_IS_IOCTL 0 229#endif 230 231/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute 232 * when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32 233 * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit. 234 * 235 * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it 236 * commutes with uv__nonblock(). 237 */ 238#if defined(__linux__) && O_NDELAY != O_NONBLOCK 239#undef uv__nonblock 240#define uv__nonblock uv__nonblock_fcntl 241#endif 242 243/* core */ 244int uv__cloexec(int fd, int set); 245int uv__nonblock_ioctl(int fd, int set); 246int uv__nonblock_fcntl(int fd, int set); 247int uv__close(int fd); /* preserves errno */ 248int uv__close_nocheckstdio(int fd); 249int uv__close_nocancel(int fd); 250int uv__socket(int domain, int type, int protocol); 251ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); 252void uv__make_close_pending(uv_handle_t* handle); 253int uv__getiovmax(void); 254 255void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); 256void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events); 257void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events); 258void uv__io_close(uv_loop_t* loop, uv__io_t* w); 259void uv__io_feed(uv_loop_t* loop, uv__io_t* w); 260int uv__io_active(const uv__io_t* w, unsigned int events); 261int uv__io_check_fd(uv_loop_t* loop, int fd); 262void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ 263int uv__io_fork(uv_loop_t* loop); 264int uv__fd_exists(uv_loop_t* loop, int fd); 265 266/* async */ 267void uv__async_stop(uv_loop_t* loop); 268int uv__async_fork(uv_loop_t* loop); 269 270#ifdef USE_FFRT 271/* epoll */ 272int uv__epoll_ctl(int epoll_fd, int op, int fd, struct epoll_event* event); 273#endif 274 275/* loop */ 276void uv__run_idle(uv_loop_t* loop); 277void uv__run_check(uv_loop_t* loop); 278void uv__run_prepare(uv_loop_t* loop); 279 280/* stream */ 281void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, 282 uv_handle_type type); 283int uv__stream_open(uv_stream_t*, int fd, int flags); 284void uv__stream_destroy(uv_stream_t* stream); 285#if defined(__APPLE__) 286int uv__stream_try_select(uv_stream_t* stream, int* fd); 287#endif /* defined(__APPLE__) */ 288void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); 289int uv__accept(int sockfd); 290int uv__dup2_cloexec(int oldfd, int newfd); 291int uv__open_cloexec(const char* path, int flags); 292int uv__slurp(const char* filename, char* buf, size_t len); 293 294/* tcp */ 295int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); 296int uv__tcp_nodelay(int fd, int on); 297int uv__tcp_keepalive(int fd, int on, unsigned int delay); 298 299/* pipe */ 300int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); 301 302/* signal */ 303void uv__signal_close(uv_signal_t* handle); 304void uv__signal_global_once_init(void); 305void uv__signal_loop_cleanup(uv_loop_t* loop); 306int uv__signal_loop_fork(uv_loop_t* loop); 307 308/* platform specific */ 309uint64_t uv__hrtime(uv_clocktype_t type); 310int uv__kqueue_init(uv_loop_t* loop); 311int uv__platform_loop_init(uv_loop_t* loop); 312void uv__platform_loop_delete(uv_loop_t* loop); 313void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); 314int uv__process_init(uv_loop_t* loop); 315 316/* various */ 317void uv__async_close(uv_async_t* handle); 318void uv__check_close(uv_check_t* handle); 319void uv__fs_event_close(uv_fs_event_t* handle); 320void uv__idle_close(uv_idle_t* handle); 321void uv__pipe_close(uv_pipe_t* handle); 322void uv__poll_close(uv_poll_t* handle); 323void uv__prepare_close(uv_prepare_t* handle); 324void uv__process_close(uv_process_t* handle); 325void uv__stream_close(uv_stream_t* handle); 326void uv__tcp_close(uv_tcp_t* handle); 327size_t uv__thread_stack_size(void); 328void uv__udp_close(uv_udp_t* handle); 329void uv__udp_finish_close(uv_udp_t* handle); 330FILE* uv__open_file(const char* path); 331int uv__search_path(const char* prog, char* buf, size_t* buflen); 332void uv__wait_children(uv_loop_t* loop); 333 334/* random */ 335int uv__random_devurandom(void* buf, size_t buflen); 336int uv__random_getrandom(void* buf, size_t buflen); 337int uv__random_getentropy(void* buf, size_t buflen); 338int uv__random_readpath(const char* path, void* buf, size_t buflen); 339int uv__random_sysctl(void* buf, size_t buflen); 340 341/* io_uring */ 342#ifdef __linux__ 343int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req); 344int uv__iou_fs_fsync_or_fdatasync(uv_loop_t* loop, 345 uv_fs_t* req, 346 uint32_t fsync_flags); 347int uv__iou_fs_link(uv_loop_t* loop, uv_fs_t* req); 348int uv__iou_fs_mkdir(uv_loop_t* loop, uv_fs_t* req); 349int uv__iou_fs_open(uv_loop_t* loop, uv_fs_t* req); 350int uv__iou_fs_read_or_write(uv_loop_t* loop, 351 uv_fs_t* req, 352 int is_read); 353int uv__iou_fs_rename(uv_loop_t* loop, uv_fs_t* req); 354int uv__iou_fs_statx(uv_loop_t* loop, 355 uv_fs_t* req, 356 int is_fstat, 357 int is_lstat); 358int uv__iou_fs_symlink(uv_loop_t* loop, uv_fs_t* req); 359int uv__iou_fs_unlink(uv_loop_t* loop, uv_fs_t* req); 360#else 361#define uv__iou_fs_close(loop, req) 0 362#define uv__iou_fs_fsync_or_fdatasync(loop, req, fsync_flags) 0 363#define uv__iou_fs_link(loop, req) 0 364#define uv__iou_fs_mkdir(loop, req) 0 365#define uv__iou_fs_open(loop, req) 0 366#define uv__iou_fs_read_or_write(loop, req, is_read) 0 367#define uv__iou_fs_rename(loop, req) 0 368#define uv__iou_fs_statx(loop, req, is_fstat, is_lstat) 0 369#define uv__iou_fs_symlink(loop, req) 0 370#define uv__iou_fs_unlink(loop, req) 0 371#endif 372 373#if defined(__APPLE__) 374int uv___stream_fd(const uv_stream_t* handle); 375#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle))) 376#else 377#define uv__stream_fd(handle) ((handle)->io_watcher.fd) 378#endif /* defined(__APPLE__) */ 379 380int uv__make_pipe(int fds[2], int flags); 381 382#if defined(__APPLE__) 383 384int uv__fsevents_init(uv_fs_event_t* handle); 385int uv__fsevents_close(uv_fs_event_t* handle); 386void uv__fsevents_loop_delete(uv_loop_t* loop); 387 388#endif /* defined(__APPLE__) */ 389 390UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { 391 /* Use a fast time source if available. We only need millisecond precision. 392 */ 393 loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; 394} 395 396UV_UNUSED(static char* uv__basename_r(const char* path)) { 397 char* s; 398 399 s = strrchr(path, '/'); 400 if (s == NULL) 401 return (char*) path; 402 403 return s + 1; 404} 405 406UV_UNUSED(static int uv__fstat(int fd, struct stat* s)) { 407 int rc; 408 409 rc = fstat(fd, s); 410 if (rc >= 0) 411 uv__msan_unpoison(s, sizeof(*s)); 412 413 return rc; 414} 415 416UV_UNUSED(static int uv__lstat(const char* path, struct stat* s)) { 417 int rc; 418 419 rc = lstat(path, s); 420 if (rc >= 0) 421 uv__msan_unpoison(s, sizeof(*s)); 422 423 return rc; 424} 425 426UV_UNUSED(static int uv__stat(const char* path, struct stat* s)) { 427 int rc; 428 429 rc = stat(path, s); 430 if (rc >= 0) 431 uv__msan_unpoison(s, sizeof(*s)); 432 433 return rc; 434} 435 436#if defined(__linux__) 437void uv__fs_post(uv_loop_t* loop, uv_fs_t* req); 438ssize_t 439uv__fs_copy_file_range(int fd_in, 440 off_t* off_in, 441 int fd_out, 442 off_t* off_out, 443 size_t len, 444 unsigned int flags); 445int uv__statx(int dirfd, 446 const char* path, 447 int flags, 448 unsigned int mask, 449 struct uv__statx* statxbuf); 450void uv__statx_to_stat(const struct uv__statx* statxbuf, uv_stat_t* buf); 451ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags); 452unsigned uv__kernel_version(void); 453#endif 454 455typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*); 456 457int uv__getsockpeername(const uv_handle_t* handle, 458 uv__peersockfunc func, 459 struct sockaddr* name, 460 int* namelen); 461 462#if defined(__sun) 463#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L 464size_t strnlen(const char* s, size_t maxlen); 465#endif 466#endif 467 468#if defined(__FreeBSD__) 469ssize_t 470uv__fs_copy_file_range(int fd_in, 471 off_t* off_in, 472 int fd_out, 473 off_t* off_out, 474 size_t len, 475 unsigned int flags); 476#endif 477 478#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 1301000) 479#define UV__CPU_AFFINITY_SUPPORTED 1 480#else 481#define UV__CPU_AFFINITY_SUPPORTED 0 482#endif 483 484UV_UNUSED(static unsigned int self_increase(unsigned int* ptr)) { 485 return __sync_fetch_and_add(ptr, 1); 486} 487 488UV_UNUSED(static unsigned int self_decrease(unsigned int* ptr)) { 489 return __sync_fetch_and_sub(ptr, 1); 490} 491#endif /* UV_UNIX_INTERNAL_H_ */ 492