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 #if defined(__APPLE__) || defined(__DragonFly__) || \ 39 defined(__FreeBSD__) || defined(__NetBSD__) 40 #include <sys/event.h> 41 #endif 42 43 #define uv__msan_unpoison(p, n) \ 44 do { \ 45 (void) (p); \ 46 (void) (n); \ 47 } while (0) 48 49 #if defined(__has_feature) 50 # if __has_feature(memory_sanitizer) 51 # include <sanitizer/msan_interface.h> 52 # undef uv__msan_unpoison 53 # define uv__msan_unpoison __msan_unpoison 54 # endif 55 #endif 56 57 #if defined(__STRICT_ANSI__) 58 # define inline __inline 59 #endif 60 61 #if defined(__MVS__) 62 # include "os390-syscalls.h" 63 #endif /* __MVS__ */ 64 65 #if defined(__sun) 66 # include <sys/port.h> 67 # include <port.h> 68 #endif /* __sun */ 69 70 #if defined(_AIX) 71 # define reqevents events 72 # define rtnevents revents 73 # include <sys/poll.h> 74 #else 75 # include <poll.h> 76 #endif /* _AIX */ 77 78 #if defined(__APPLE__) 79 # include "darwin-syscalls.h" 80 # if !TARGET_OS_IPHONE 81 # include <AvailabilityMacros.h> 82 # endif 83 #endif 84 85 /* 86 * Define common detection for active Thread Sanitizer 87 * - clang uses __has_feature(thread_sanitizer) 88 * - gcc-7+ uses __SANITIZE_THREAD__ 89 */ 90 #if defined(__has_feature) 91 # if __has_feature(thread_sanitizer) 92 # define __SANITIZE_THREAD__ 1 93 # endif 94 #endif 95 96 #if defined(PATH_MAX) 97 # define UV__PATH_MAX PATH_MAX 98 #else 99 # define UV__PATH_MAX 8192 100 #endif 101 102 union uv__sockaddr { 103 struct sockaddr_in6 in6; 104 struct sockaddr_in in; 105 struct sockaddr addr; 106 }; 107 108 #define ACCESS_ONCE(type, var) \ 109 (*(volatile type*) &(var)) 110 111 #define ROUND_UP(a, b) \ 112 ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a)) 113 114 #define UNREACHABLE() \ 115 do { \ 116 assert(0 && "unreachable code"); \ 117 abort(); \ 118 } \ 119 while (0) 120 121 #define SAVE_ERRNO(block) \ 122 do { \ 123 int _saved_errno = errno; \ 124 do { block; } while (0); \ 125 errno = _saved_errno; \ 126 } \ 127 while (0) 128 129 /* The __clang__ and __INTEL_COMPILER checks are superfluous because they 130 * define __GNUC__. They are here to convey to you, dear reader, that these 131 * macros are enabled when compiling with clang or icc. 132 */ 133 #if defined(__clang__) || \ 134 defined(__GNUC__) || \ 135 defined(__INTEL_COMPILER) 136 # define UV_UNUSED(declaration) __attribute__((unused)) declaration 137 #else 138 # define UV_UNUSED(declaration) declaration 139 #endif 140 141 /* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */ 142 #ifdef POLLRDHUP 143 # define UV__POLLRDHUP POLLRDHUP 144 #else 145 # define UV__POLLRDHUP 0x2000 146 #endif 147 148 #ifdef POLLPRI 149 # define UV__POLLPRI POLLPRI 150 #else 151 # define UV__POLLPRI 0 152 #endif 153 154 #if !defined(O_CLOEXEC) && defined(__FreeBSD__) 155 /* 156 * It may be that we are just missing `__POSIX_VISIBLE >= 200809`. 157 * Try using fixed value const and give up, if it doesn't work 158 */ 159 # define O_CLOEXEC 0x00100000 160 #endif 161 162 typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t; 163 164 /* loop flags */ 165 enum { 166 UV_LOOP_BLOCK_SIGPROF = 0x1, 167 UV_LOOP_REAP_CHILDREN = 0x2, 168 UV_LOOP_ENABLE_IO_URING_SQPOLL = 0x4 169 }; 170 171 /* flags of excluding ifaddr */ 172 enum { 173 UV__EXCLUDE_IFPHYS, 174 UV__EXCLUDE_IFADDR 175 }; 176 177 typedef enum { 178 UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ 179 UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ 180 } uv_clocktype_t; 181 182 struct uv__stream_queued_fds_s { 183 unsigned int size; 184 unsigned int offset; 185 int fds[1]; 186 }; 187 188 #ifdef __linux__ 189 struct uv__statx_timestamp { 190 int64_t tv_sec; 191 uint32_t tv_nsec; 192 int32_t unused0; 193 }; 194 195 struct uv__statx { 196 uint32_t stx_mask; 197 uint32_t stx_blksize; 198 uint64_t stx_attributes; 199 uint32_t stx_nlink; 200 uint32_t stx_uid; 201 uint32_t stx_gid; 202 uint16_t stx_mode; 203 uint16_t unused0; 204 uint64_t stx_ino; 205 uint64_t stx_size; 206 uint64_t stx_blocks; 207 uint64_t stx_attributes_mask; 208 struct uv__statx_timestamp stx_atime; 209 struct uv__statx_timestamp stx_btime; 210 struct uv__statx_timestamp stx_ctime; 211 struct uv__statx_timestamp stx_mtime; 212 uint32_t stx_rdev_major; 213 uint32_t stx_rdev_minor; 214 uint32_t stx_dev_major; 215 uint32_t stx_dev_minor; 216 uint64_t unused1[14]; 217 }; 218 #endif /* __linux__ */ 219 220 #if defined(_AIX) || \ 221 defined(__APPLE__) || \ 222 defined(__DragonFly__) || \ 223 defined(__FreeBSD__) || \ 224 defined(__linux__) || \ 225 defined(__OpenBSD__) || \ 226 defined(__NetBSD__) 227 #define uv__nonblock uv__nonblock_ioctl 228 #define UV__NONBLOCK_IS_IOCTL 1 229 #else 230 #define uv__nonblock uv__nonblock_fcntl 231 #define UV__NONBLOCK_IS_IOCTL 0 232 #endif 233 234 /* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute 235 * when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32 236 * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit. 237 * 238 * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it 239 * commutes with uv__nonblock(). 240 */ 241 #if defined(__linux__) && O_NDELAY != O_NONBLOCK 242 #undef uv__nonblock 243 #define uv__nonblock uv__nonblock_fcntl 244 #endif 245 246 /* core */ 247 int uv__cloexec(int fd, int set); 248 int uv__nonblock_ioctl(int fd, int set); 249 int uv__nonblock_fcntl(int fd, int set); 250 int uv__close(int fd); /* preserves errno */ 251 int uv__close_nocheckstdio(int fd); 252 int uv__close_nocancel(int fd); 253 int uv__socket(int domain, int type, int protocol); 254 int uv__sock_reuseport(int fd); 255 ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); 256 void uv__make_close_pending(uv_handle_t* handle); 257 int uv__getiovmax(void); 258 259 void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); 260 int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events); 261 int uv__io_init_start(uv_loop_t* loop, 262 uv__io_t* w, 263 uv__io_cb cb, 264 int fd, 265 unsigned int events); 266 void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events); 267 void uv__io_close(uv_loop_t* loop, uv__io_t* w); 268 void uv__io_feed(uv_loop_t* loop, uv__io_t* w); 269 int uv__io_active(const uv__io_t* w, unsigned int events); 270 int uv__io_check_fd(uv_loop_t* loop, int fd); 271 void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ 272 int uv__io_fork(uv_loop_t* loop); 273 int uv__fd_exists(uv_loop_t* loop, int fd); 274 275 /* async */ 276 void uv__async_stop(uv_loop_t* loop); 277 int uv__async_fork(uv_loop_t* loop); 278 279 280 /* loop */ 281 void uv__run_idle(uv_loop_t* loop); 282 void uv__run_check(uv_loop_t* loop); 283 void uv__run_prepare(uv_loop_t* loop); 284 285 /* stream */ 286 void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, 287 uv_handle_type type); 288 int uv__stream_open(uv_stream_t*, int fd, int flags); 289 void uv__stream_destroy(uv_stream_t* stream); 290 #if defined(__APPLE__) 291 int uv__stream_try_select(uv_stream_t* stream, int* fd); 292 #endif /* defined(__APPLE__) */ 293 void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); 294 int uv__accept(int sockfd); 295 int uv__dup2_cloexec(int oldfd, int newfd); 296 int uv__open_cloexec(const char* path, int flags); 297 int uv__slurp(const char* filename, char* buf, size_t len); 298 299 /* tcp */ 300 int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); 301 int uv__tcp_nodelay(int fd, int on); 302 int uv__tcp_keepalive(int fd, int on, unsigned int delay); 303 304 /* tty */ 305 void uv__tty_close(uv_tty_t* handle); 306 307 /* pipe */ 308 int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); 309 310 /* signal */ 311 void uv__signal_close(uv_signal_t* handle); 312 void uv__signal_global_once_init(void); 313 void uv__signal_loop_cleanup(uv_loop_t* loop); 314 int uv__signal_loop_fork(uv_loop_t* loop); 315 316 /* platform specific */ 317 uint64_t uv__hrtime(uv_clocktype_t type); 318 int uv__kqueue_init(uv_loop_t* loop); 319 int uv__platform_loop_init(uv_loop_t* loop); 320 void uv__platform_loop_delete(uv_loop_t* loop); 321 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); 322 int uv__process_init(uv_loop_t* loop); 323 324 /* various */ 325 void uv__async_close(uv_async_t* handle); 326 void uv__check_close(uv_check_t* handle); 327 void uv__fs_event_close(uv_fs_event_t* handle); 328 void uv__idle_close(uv_idle_t* handle); 329 void uv__pipe_close(uv_pipe_t* handle); 330 void uv__poll_close(uv_poll_t* handle); 331 void uv__prepare_close(uv_prepare_t* handle); 332 void uv__process_close(uv_process_t* handle); 333 void uv__stream_close(uv_stream_t* handle); 334 void uv__tcp_close(uv_tcp_t* handle); 335 int uv__thread_setname(const char* name); 336 int uv__thread_getname(uv_thread_t* tid, char* name, size_t size); 337 size_t uv__thread_stack_size(void); 338 void uv__udp_close(uv_udp_t* handle); 339 void uv__udp_finish_close(uv_udp_t* handle); 340 FILE* uv__open_file(const char* path); 341 int uv__search_path(const char* prog, char* buf, size_t* buflen); 342 void uv__wait_children(uv_loop_t* loop); 343 344 /* random */ 345 int uv__random_devurandom(void* buf, size_t buflen); 346 int uv__random_getrandom(void* buf, size_t buflen); 347 int uv__random_getentropy(void* buf, size_t buflen); 348 int uv__random_readpath(const char* path, void* buf, size_t buflen); 349 int uv__random_sysctl(void* buf, size_t buflen); 350 351 /* io_uring */ 352 #ifdef __linux__ 353 int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req); 354 int uv__iou_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req); 355 int uv__iou_fs_fsync_or_fdatasync(uv_loop_t* loop, 356 uv_fs_t* req, 357 uint32_t fsync_flags); 358 int uv__iou_fs_link(uv_loop_t* loop, uv_fs_t* req); 359 int uv__iou_fs_mkdir(uv_loop_t* loop, uv_fs_t* req); 360 int uv__iou_fs_open(uv_loop_t* loop, uv_fs_t* req); 361 int uv__iou_fs_read_or_write(uv_loop_t* loop, 362 uv_fs_t* req, 363 int is_read); 364 int uv__iou_fs_rename(uv_loop_t* loop, uv_fs_t* req); 365 int uv__iou_fs_statx(uv_loop_t* loop, 366 uv_fs_t* req, 367 int is_fstat, 368 int is_lstat); 369 int uv__iou_fs_symlink(uv_loop_t* loop, uv_fs_t* req); 370 int uv__iou_fs_unlink(uv_loop_t* loop, uv_fs_t* req); 371 #else 372 #define uv__iou_fs_close(loop, req) 0 373 #define uv__iou_fs_ftruncate(loop, req) 0 374 #define uv__iou_fs_fsync_or_fdatasync(loop, req, fsync_flags) 0 375 #define uv__iou_fs_link(loop, req) 0 376 #define uv__iou_fs_mkdir(loop, req) 0 377 #define uv__iou_fs_open(loop, req) 0 378 #define uv__iou_fs_read_or_write(loop, req, is_read) 0 379 #define uv__iou_fs_rename(loop, req) 0 380 #define uv__iou_fs_statx(loop, req, is_fstat, is_lstat) 0 381 #define uv__iou_fs_symlink(loop, req) 0 382 #define uv__iou_fs_unlink(loop, req) 0 383 #endif 384 385 #if defined(__APPLE__) 386 int uv___stream_fd(const uv_stream_t* handle); 387 #define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle))) 388 #else 389 #define uv__stream_fd(handle) ((handle)->io_watcher.fd) 390 #endif /* defined(__APPLE__) */ 391 392 int uv__make_pipe(int fds[2], int flags); 393 394 #if defined(__APPLE__) 395 396 int uv__fsevents_init(uv_fs_event_t* handle); 397 int uv__fsevents_close(uv_fs_event_t* handle); 398 void uv__fsevents_loop_delete(uv_loop_t* loop); 399 400 #endif /* defined(__APPLE__) */ 401 402 UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { 403 /* Use a fast time source if available. We only need millisecond precision. 404 */ 405 loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; 406 } 407 408 UV_UNUSED(static char* uv__basename_r(const char* path)) { 409 char* s; 410 411 s = strrchr(path, '/'); 412 if (s == NULL) 413 return (char*) path; 414 415 return s + 1; 416 } 417 418 UV_UNUSED(static int uv__fstat(int fd, struct stat* s)) { 419 int rc; 420 421 rc = fstat(fd, s); 422 if (rc >= 0) 423 uv__msan_unpoison(s, sizeof(*s)); 424 425 return rc; 426 } 427 428 UV_UNUSED(static int uv__lstat(const char* path, struct stat* s)) { 429 int rc; 430 431 rc = lstat(path, s); 432 if (rc >= 0) 433 uv__msan_unpoison(s, sizeof(*s)); 434 435 return rc; 436 } 437 438 UV_UNUSED(static int uv__stat(const char* path, struct stat* s)) { 439 int rc; 440 441 rc = stat(path, s); 442 if (rc >= 0) 443 uv__msan_unpoison(s, sizeof(*s)); 444 445 return rc; 446 } 447 448 #if defined(__linux__) 449 void uv__fs_post(uv_loop_t* loop, uv_fs_t* req); 450 ssize_t 451 uv__fs_copy_file_range(int fd_in, 452 off_t* off_in, 453 int fd_out, 454 off_t* off_out, 455 size_t len, 456 unsigned int flags); 457 int uv__statx(int dirfd, 458 const char* path, 459 int flags, 460 unsigned int mask, 461 struct uv__statx* statxbuf); 462 void uv__statx_to_stat(const struct uv__statx* statxbuf, uv_stat_t* buf); 463 ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags); 464 unsigned uv__kernel_version(void); 465 #endif 466 467 typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*); 468 469 int uv__getsockpeername(const uv_handle_t* handle, 470 uv__peersockfunc func, 471 struct sockaddr* name, 472 int* namelen); 473 474 #if defined(__sun) 475 #if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L 476 size_t strnlen(const char* s, size_t maxlen); 477 #endif 478 #endif 479 480 #if defined(__FreeBSD__) 481 ssize_t 482 uv__fs_copy_file_range(int fd_in, 483 off_t* off_in, 484 int fd_out, 485 off_t* off_out, 486 size_t len, 487 unsigned int flags); 488 #endif 489 490 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 1301000) 491 #define UV__CPU_AFFINITY_SUPPORTED 1 492 #else 493 #define UV__CPU_AFFINITY_SUPPORTED 0 494 #endif 495 496 #ifdef __linux__ 497 int uv__get_constrained_cpu(long long* quota); 498 #endif 499 500 #if defined(__sun) && !defined(__illumos__) 501 #ifdef SO_FLOW_NAME 502 /* Since it's impossible to detect the Solaris 11.4 version via OS macros, 503 * so we check the presence of the socket option SO_FLOW_NAME that was first 504 * introduced to Solaris 11.4 and define a custom macro for determining 11.4. 505 */ 506 #define UV__SOLARIS_11_4 (1) 507 #else 508 #define UV__SOLARIS_11_4 (0) 509 #endif 510 #endif 511 512 #if defined(EVFILT_USER) && defined(NOTE_TRIGGER) 513 /* EVFILT_USER is available since OS X 10.6, DragonFlyBSD 4.0, 514 * FreeBSD 8.1, and NetBSD 10.0. 515 * 516 * Note that even though EVFILT_USER is defined on the current system, 517 * it may still fail to work at runtime somehow. In that case, we fall 518 * back to pipe-based signaling. 519 */ 520 #define UV__KQUEUE_EVFILT_USER 1 521 /* Magic number of identifier used for EVFILT_USER during runtime detection. 522 * There are no Google hits for this number when I create it. That way, 523 * people will be directed here if this number gets printed due to some 524 * kqueue error and they google for help. */ 525 #define UV__KQUEUE_EVFILT_USER_IDENT 0x1e7e7711 526 #else 527 #define UV__KQUEUE_EVFILT_USER 0 528 #endif 529 530 #endif /* UV_UNIX_INTERNAL_H_ */ 531