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_H 23 #define UV_UNIX_H 24 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <fcntl.h> 28 #include <dirent.h> 29 30 #include <sys/socket.h> 31 #include <netinet/in.h> 32 #include <netinet/tcp.h> 33 #include <arpa/inet.h> 34 #include <netdb.h> /* MAXHOSTNAMELEN on Solaris */ 35 36 #include <termios.h> 37 #include <pwd.h> 38 39 #if !defined(__MVS__) 40 #include <semaphore.h> 41 #include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */ 42 #endif 43 #include <pthread.h> 44 #include <signal.h> 45 46 #include "uv/threadpool.h" 47 48 #if defined(__linux__) 49 # include "uv/linux.h" 50 #elif defined (__MVS__) 51 # include "uv/os390.h" 52 #elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */ 53 # include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */ 54 #elif defined(_AIX) 55 # include "uv/aix.h" 56 #elif defined(__sun) 57 # include "uv/sunos.h" 58 #elif defined(__APPLE__) 59 # include "uv/darwin.h" 60 #elif defined(__DragonFly__) || \ 61 defined(__FreeBSD__) || \ 62 defined(__OpenBSD__) || \ 63 defined(__NetBSD__) 64 # include "uv/bsd.h" 65 #elif defined(__CYGWIN__) || \ 66 defined(__MSYS__) || \ 67 defined(__HAIKU__) || \ 68 defined(__QNX__) || \ 69 defined(__GNU__) 70 # include "uv/posix.h" 71 #endif 72 73 #ifndef NI_MAXHOST 74 # define NI_MAXHOST 1025 75 #endif 76 77 #ifndef NI_MAXSERV 78 # define NI_MAXSERV 32 79 #endif 80 81 #ifndef UV_IO_PRIVATE_PLATFORM_FIELDS 82 # define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ 83 #endif 84 85 struct uv__io_s; 86 struct uv_loop_s; 87 88 typedef void (*uv__io_cb)(struct uv_loop_s* loop, 89 struct uv__io_s* w, 90 unsigned int events); 91 typedef struct uv__io_s uv__io_t; 92 93 struct uv__io_s { 94 uv__io_cb cb; 95 struct uv__queue pending_queue; 96 struct uv__queue watcher_queue; 97 unsigned int pevents; /* Pending event mask i.e. mask at next tick. */ 98 unsigned int events; /* Current event mask. */ 99 int fd; 100 UV_IO_PRIVATE_PLATFORM_FIELDS 101 }; 102 103 #ifndef UV_PLATFORM_SEM_T 104 # define UV_PLATFORM_SEM_T sem_t 105 #endif 106 107 #ifndef UV_PLATFORM_LOOP_FIELDS 108 # define UV_PLATFORM_LOOP_FIELDS /* empty */ 109 #endif 110 111 #ifndef UV_PLATFORM_FS_EVENT_FIELDS 112 # define UV_PLATFORM_FS_EVENT_FIELDS /* empty */ 113 #endif 114 115 #ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS 116 # define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */ 117 #endif 118 119 /* Note: May be cast to struct iovec. See writev(2). */ 120 typedef struct uv_buf_t { 121 char* base; 122 size_t len; 123 } uv_buf_t; 124 125 typedef int uv_file; 126 typedef int uv_os_sock_t; 127 typedef int uv_os_fd_t; 128 typedef pid_t uv_pid_t; 129 130 #define UV_ONCE_INIT PTHREAD_ONCE_INIT 131 132 typedef pthread_once_t uv_once_t; 133 typedef pthread_t uv_thread_t; 134 typedef pthread_mutex_t uv_mutex_t; 135 typedef pthread_rwlock_t uv_rwlock_t; 136 typedef UV_PLATFORM_SEM_T uv_sem_t; 137 typedef pthread_cond_t uv_cond_t; 138 typedef pthread_key_t uv_key_t; 139 140 /* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */ 141 #if defined(_AIX) || \ 142 defined(__OpenBSD__) || \ 143 !defined(PTHREAD_BARRIER_SERIAL_THREAD) 144 /* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */ 145 struct _uv_barrier { 146 uv_mutex_t mutex; 147 uv_cond_t cond; 148 unsigned threshold; 149 unsigned in; 150 unsigned out; 151 }; 152 153 typedef struct { 154 struct _uv_barrier* b; 155 # if defined(PTHREAD_BARRIER_SERIAL_THREAD) 156 /* TODO(bnoordhuis) Remove padding in v2. */ 157 char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)]; 158 # endif 159 } uv_barrier_t; 160 #else 161 typedef pthread_barrier_t uv_barrier_t; 162 #endif 163 164 /* Platform-specific definitions for uv_spawn support. */ 165 typedef gid_t uv_gid_t; 166 typedef uid_t uv_uid_t; 167 168 typedef struct dirent uv__dirent_t; 169 170 #define UV_DIR_PRIVATE_FIELDS \ 171 DIR* dir; 172 173 #if defined(DT_UNKNOWN) 174 # define HAVE_DIRENT_TYPES 175 # if defined(DT_REG) 176 # define UV__DT_FILE DT_REG 177 # else 178 # define UV__DT_FILE -1 179 # endif 180 # if defined(DT_DIR) 181 # define UV__DT_DIR DT_DIR 182 # else 183 # define UV__DT_DIR -2 184 # endif 185 # if defined(DT_LNK) 186 # define UV__DT_LINK DT_LNK 187 # else 188 # define UV__DT_LINK -3 189 # endif 190 # if defined(DT_FIFO) 191 # define UV__DT_FIFO DT_FIFO 192 # else 193 # define UV__DT_FIFO -4 194 # endif 195 # if defined(DT_SOCK) 196 # define UV__DT_SOCKET DT_SOCK 197 # else 198 # define UV__DT_SOCKET -5 199 # endif 200 # if defined(DT_CHR) 201 # define UV__DT_CHAR DT_CHR 202 # else 203 # define UV__DT_CHAR -6 204 # endif 205 # if defined(DT_BLK) 206 # define UV__DT_BLOCK DT_BLK 207 # else 208 # define UV__DT_BLOCK -7 209 # endif 210 #endif 211 212 /* Platform-specific definitions for uv_dlopen support. */ 213 #define UV_DYNAMIC /* empty */ 214 215 typedef struct { 216 void* handle; 217 char* errmsg; 218 } uv_lib_t; 219 220 #define UV_LOOP_PRIVATE_FIELDS \ 221 unsigned long flags; \ 222 int backend_fd; \ 223 struct uv__queue pending_queue; \ 224 struct uv__queue watcher_queue; \ 225 uv__io_t** watchers; \ 226 unsigned int nwatchers; \ 227 unsigned int nfds; \ 228 struct uv__queue wq; \ 229 uv_mutex_t wq_mutex; \ 230 uv_async_t wq_async; \ 231 uv_rwlock_t cloexec_lock; \ 232 uv_handle_t* closing_handles; \ 233 struct uv__queue process_handles; \ 234 struct uv__queue prepare_handles; \ 235 struct uv__queue check_handles; \ 236 struct uv__queue idle_handles; \ 237 struct uv__queue async_handles; \ 238 void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ 239 uv__io_t async_io_watcher; \ 240 int async_wfd; \ 241 struct { \ 242 void* min; \ 243 unsigned int nelts; \ 244 } timer_heap; \ 245 uint64_t timer_counter; \ 246 uint64_t time; \ 247 int signal_pipefd[2]; \ 248 uv__io_t signal_io_watcher; \ 249 uv_signal_t child_watcher; \ 250 int emfile_fd; \ 251 UV_PLATFORM_LOOP_FIELDS \ 252 253 #define UV_REQ_TYPE_PRIVATE /* empty */ 254 255 #define UV_REQ_PRIVATE_FIELDS /* empty */ 256 257 #define UV_PRIVATE_REQ_TYPES /* empty */ 258 259 #define UV_WRITE_PRIVATE_FIELDS \ 260 struct uv__queue queue; \ 261 unsigned int write_index; \ 262 uv_buf_t* bufs; \ 263 unsigned int nbufs; \ 264 int error; \ 265 uv_buf_t bufsml[4]; \ 266 267 #define UV_CONNECT_PRIVATE_FIELDS \ 268 struct uv__queue queue; \ 269 270 #define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */ 271 272 #define UV_UDP_SEND_PRIVATE_FIELDS \ 273 struct uv__queue queue; \ 274 union { \ 275 struct sockaddr addr; \ 276 struct sockaddr_storage storage; \ 277 } u; \ 278 unsigned int nbufs; \ 279 uv_buf_t* bufs; \ 280 ssize_t status; \ 281 uv_udp_send_cb send_cb; \ 282 uv_buf_t bufsml[4]; \ 283 284 #define UV_HANDLE_PRIVATE_FIELDS \ 285 uv_handle_t* next_closing; \ 286 unsigned int flags; \ 287 288 #define UV_STREAM_PRIVATE_FIELDS \ 289 uv_connect_t *connect_req; \ 290 uv_shutdown_t *shutdown_req; \ 291 uv__io_t io_watcher; \ 292 struct uv__queue write_queue; \ 293 struct uv__queue write_completed_queue; \ 294 uv_connection_cb connection_cb; \ 295 int delayed_error; \ 296 int accepted_fd; \ 297 void* queued_fds; \ 298 UV_STREAM_PRIVATE_PLATFORM_FIELDS \ 299 300 #define UV_TCP_PRIVATE_FIELDS /* empty */ 301 302 #define UV_UDP_PRIVATE_FIELDS \ 303 uv_alloc_cb alloc_cb; \ 304 uv_udp_recv_cb recv_cb; \ 305 uv__io_t io_watcher; \ 306 struct uv__queue write_queue; \ 307 struct uv__queue write_completed_queue; \ 308 309 #define UV_PIPE_PRIVATE_FIELDS \ 310 const char* pipe_fname; /* NULL or strdup'ed */ 311 312 #define UV_POLL_PRIVATE_FIELDS \ 313 uv__io_t io_watcher; 314 315 #define UV_PREPARE_PRIVATE_FIELDS \ 316 uv_prepare_cb prepare_cb; \ 317 struct uv__queue queue; \ 318 319 #define UV_CHECK_PRIVATE_FIELDS \ 320 uv_check_cb check_cb; \ 321 struct uv__queue queue; \ 322 323 #define UV_IDLE_PRIVATE_FIELDS \ 324 uv_idle_cb idle_cb; \ 325 struct uv__queue queue; \ 326 327 #define UV_ASYNC_PRIVATE_FIELDS \ 328 uv_async_cb async_cb; \ 329 struct uv__queue queue; \ 330 int pending; \ 331 332 #define UV_TIMER_PRIVATE_FIELDS \ 333 uv_timer_cb timer_cb; \ 334 union { \ 335 void* heap[3]; \ 336 struct uv__queue queue; \ 337 } node; \ 338 uint64_t timeout; \ 339 uint64_t repeat; \ 340 uint64_t start_id; 341 342 #define UV_GETADDRINFO_PRIVATE_FIELDS \ 343 struct uv__work work_req; \ 344 uv_getaddrinfo_cb cb; \ 345 struct addrinfo* hints; \ 346 char* hostname; \ 347 char* service; \ 348 struct addrinfo* addrinfo; \ 349 int retcode; 350 351 #define UV_GETNAMEINFO_PRIVATE_FIELDS \ 352 struct uv__work work_req; \ 353 uv_getnameinfo_cb getnameinfo_cb; \ 354 struct sockaddr_storage storage; \ 355 int flags; \ 356 char host[NI_MAXHOST]; \ 357 char service[NI_MAXSERV]; \ 358 int retcode; 359 360 #define UV_PROCESS_PRIVATE_FIELDS \ 361 struct uv__queue queue; \ 362 int status; \ 363 364 #define UV_FS_PRIVATE_FIELDS \ 365 const char *new_path; \ 366 uv_file file; \ 367 int flags; \ 368 mode_t mode; \ 369 unsigned int nbufs; \ 370 uv_buf_t* bufs; \ 371 off_t off; \ 372 uv_uid_t uid; \ 373 uv_gid_t gid; \ 374 double atime; \ 375 double mtime; \ 376 struct uv__work work_req; \ 377 uv_buf_t bufsml[4]; \ 378 379 #define UV_WORK_PRIVATE_FIELDS \ 380 struct uv__work work_req; 381 382 #define UV_TTY_PRIVATE_FIELDS \ 383 struct termios orig_termios; \ 384 int mode; 385 386 #define UV_SIGNAL_PRIVATE_FIELDS \ 387 /* RB_ENTRY(uv_signal_s) tree_entry; */ \ 388 struct { \ 389 struct uv_signal_s* rbe_left; \ 390 struct uv_signal_s* rbe_right; \ 391 struct uv_signal_s* rbe_parent; \ 392 int rbe_color; \ 393 } tree_entry; \ 394 /* Use two counters here so we don have to fiddle with atomics. */ \ 395 unsigned int caught_signals; \ 396 unsigned int dispatched_signals; 397 398 #define UV_FS_EVENT_PRIVATE_FIELDS \ 399 uv_fs_event_cb cb; \ 400 UV_PLATFORM_FS_EVENT_FIELDS \ 401 402 /* fs open() flags supported on this platform: */ 403 #if defined(O_APPEND) 404 # define UV_FS_O_APPEND O_APPEND 405 #else 406 # define UV_FS_O_APPEND 0 407 #endif 408 #if defined(O_CREAT) 409 # define UV_FS_O_CREAT O_CREAT 410 #else 411 # define UV_FS_O_CREAT 0 412 #endif 413 414 #if defined(__linux__) && defined(__arm__) 415 # define UV_FS_O_DIRECT 0x10000 416 #elif defined(__linux__) && defined(__m68k__) 417 # define UV_FS_O_DIRECT 0x10000 418 #elif defined(__linux__) && defined(__mips__) 419 # define UV_FS_O_DIRECT 0x08000 420 #elif defined(__linux__) && defined(__powerpc__) 421 # define UV_FS_O_DIRECT 0x20000 422 #elif defined(__linux__) && defined(__s390x__) 423 # define UV_FS_O_DIRECT 0x04000 424 #elif defined(__linux__) && defined(__x86_64__) 425 # define UV_FS_O_DIRECT 0x04000 426 #elif defined(__linux__) && defined(__loongarch__) 427 # define UV_FS_O_DIRECT 0x04000 428 #elif defined(O_DIRECT) 429 # define UV_FS_O_DIRECT O_DIRECT 430 #else 431 # define UV_FS_O_DIRECT 0 432 #endif 433 434 #if defined(O_DIRECTORY) 435 # define UV_FS_O_DIRECTORY O_DIRECTORY 436 #else 437 # define UV_FS_O_DIRECTORY 0 438 #endif 439 #if defined(O_DSYNC) 440 # define UV_FS_O_DSYNC O_DSYNC 441 #else 442 # define UV_FS_O_DSYNC 0 443 #endif 444 #if defined(O_EXCL) 445 # define UV_FS_O_EXCL O_EXCL 446 #else 447 # define UV_FS_O_EXCL 0 448 #endif 449 #if defined(O_EXLOCK) 450 # define UV_FS_O_EXLOCK O_EXLOCK 451 #else 452 # define UV_FS_O_EXLOCK 0 453 #endif 454 #if defined(O_NOATIME) 455 # define UV_FS_O_NOATIME O_NOATIME 456 #else 457 # define UV_FS_O_NOATIME 0 458 #endif 459 #if defined(O_NOCTTY) 460 # define UV_FS_O_NOCTTY O_NOCTTY 461 #else 462 # define UV_FS_O_NOCTTY 0 463 #endif 464 #if defined(O_NOFOLLOW) 465 # define UV_FS_O_NOFOLLOW O_NOFOLLOW 466 #else 467 # define UV_FS_O_NOFOLLOW 0 468 #endif 469 #if defined(O_NONBLOCK) 470 # define UV_FS_O_NONBLOCK O_NONBLOCK 471 #else 472 # define UV_FS_O_NONBLOCK 0 473 #endif 474 #if defined(O_RDONLY) 475 # define UV_FS_O_RDONLY O_RDONLY 476 #else 477 # define UV_FS_O_RDONLY 0 478 #endif 479 #if defined(O_RDWR) 480 # define UV_FS_O_RDWR O_RDWR 481 #else 482 # define UV_FS_O_RDWR 0 483 #endif 484 #if defined(O_SYMLINK) 485 # define UV_FS_O_SYMLINK O_SYMLINK 486 #else 487 # define UV_FS_O_SYMLINK 0 488 #endif 489 #if defined(O_SYNC) 490 # define UV_FS_O_SYNC O_SYNC 491 #else 492 # define UV_FS_O_SYNC 0 493 #endif 494 #if defined(O_TRUNC) 495 # define UV_FS_O_TRUNC O_TRUNC 496 #else 497 # define UV_FS_O_TRUNC 0 498 #endif 499 #if defined(O_WRONLY) 500 # define UV_FS_O_WRONLY O_WRONLY 501 #else 502 # define UV_FS_O_WRONLY 0 503 #endif 504 505 /* fs open() flags supported on other platforms: */ 506 #define UV_FS_O_FILEMAP 0 507 #define UV_FS_O_RANDOM 0 508 #define UV_FS_O_SHORT_LIVED 0 509 #define UV_FS_O_SEQUENTIAL 0 510 #define UV_FS_O_TEMPORARY 0 511 512 #endif /* UV_UNIX_H */ 513