comparison third_party/libuv/src/unix/core.c @ 160:948de3f54cea

[ThirdParty] Added libuv
author June Park <parkjune1995@gmail.com>
date Wed, 14 Jan 2026 19:39:52 -0800
parents
children
comparison
equal deleted inserted replaced
159:05cf9467a1c3 160:948de3f54cea
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 * Permission is hereby granted, free of charge, to any person obtaining a copy
3 * of this software and associated documentation files (the "Software"), to
4 * deal in the Software without restriction, including without limitation the
5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6 * sell copies of the Software, and to permit persons to whom the Software is
7 * furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
21 #include "uv.h"
22 #include "internal.h"
23 #include "strtok.h"
24
25 #include <stddef.h> /* NULL */
26 #include <stdio.h> /* printf */
27 #include <stdlib.h>
28 #include <string.h> /* strerror */
29 #include <errno.h>
30 #include <assert.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h> /* O_CLOEXEC */
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #include <limits.h> /* INT_MAX, PATH_MAX, IOV_MAX */
41 #include <sys/uio.h> /* writev */
42 #include <sys/resource.h> /* getrusage */
43 #include <pwd.h>
44 #include <grp.h>
45 #include <sys/utsname.h>
46 #include <sys/time.h>
47 #include <time.h> /* clock_gettime */
48
49 #ifdef __sun
50 # include <sys/filio.h>
51 # include <sys/wait.h>
52 #endif
53
54 #if defined(__APPLE__)
55 # include <mach/mach.h>
56 # include <mach/thread_info.h>
57 # include <sys/filio.h>
58 # include <sys/sysctl.h>
59 #endif /* defined(__APPLE__) */
60
61
62 #if defined(__APPLE__) && !TARGET_OS_IPHONE
63 # include <crt_externs.h>
64 # include <mach-o/dyld.h> /* _NSGetExecutablePath */
65 # define environ (*_NSGetEnviron())
66 #else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
67 extern char** environ;
68 #endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */
69
70
71 #if defined(__DragonFly__) || \
72 defined(__FreeBSD__) || \
73 defined(__NetBSD__) || \
74 defined(__OpenBSD__)
75 # include <sys/sysctl.h>
76 # include <sys/filio.h>
77 # include <sys/wait.h>
78 # include <sys/param.h>
79 # if defined(__FreeBSD__)
80 # include <sys/cpuset.h>
81 # define uv__accept4 accept4
82 # endif
83 # if defined(__NetBSD__)
84 # define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d))
85 # endif
86 #endif
87
88 #if defined(__MVS__)
89 # include <sys/ioctl.h>
90 # include "zos-sys-info.h"
91 #endif
92
93 #if defined(__linux__)
94 # include <sched.h>
95 # include <sys/syscall.h>
96 # define gettid() syscall(SYS_gettid)
97 # define uv__accept4 accept4
98 #endif
99
100 #if defined(__FreeBSD__)
101 # include <sys/param.h>
102 # include <sys/cpuset.h>
103 #endif
104
105 #if defined(__NetBSD__)
106 # include <sched.h>
107 #endif
108
109 #if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
110 # include <sanitizer/linux_syscall_hooks.h>
111 #endif
112
113 static void uv__run_pending(uv_loop_t* loop);
114
115 /* Verify that uv_buf_t is ABI-compatible with struct iovec. */
116 STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
117 STATIC_ASSERT(sizeof(((uv_buf_t*) 0)->base) ==
118 sizeof(((struct iovec*) 0)->iov_base));
119 STATIC_ASSERT(sizeof(((uv_buf_t*) 0)->len) ==
120 sizeof(((struct iovec*) 0)->iov_len));
121 STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base));
122 STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len));
123
124
125 /* https://github.com/libuv/libuv/issues/1674 */
126 int uv_clock_gettime(uv_clock_id clock_id, uv_timespec64_t* ts) {
127 struct timespec t;
128 int r;
129
130 if (ts == NULL)
131 return UV_EFAULT;
132
133 switch (clock_id) {
134 default:
135 return UV_EINVAL;
136 case UV_CLOCK_MONOTONIC:
137 r = clock_gettime(CLOCK_MONOTONIC, &t);
138 break;
139 case UV_CLOCK_REALTIME:
140 r = clock_gettime(CLOCK_REALTIME, &t);
141 break;
142 }
143
144 if (r)
145 return UV__ERR(errno);
146
147 ts->tv_sec = t.tv_sec;
148 ts->tv_nsec = t.tv_nsec;
149
150 return 0;
151 }
152
153
154 uint64_t uv_hrtime(void) {
155 return uv__hrtime(UV_CLOCK_PRECISE);
156 }
157
158
159 void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
160 assert(!uv__is_closing(handle));
161
162 handle->flags |= UV_HANDLE_CLOSING;
163 handle->close_cb = close_cb;
164
165 switch (handle->type) {
166 case UV_NAMED_PIPE:
167 uv__pipe_close((uv_pipe_t*)handle);
168 break;
169
170 case UV_TTY:
171 uv__tty_close((uv_tty_t*)handle);
172 break;
173
174 case UV_TCP:
175 uv__tcp_close((uv_tcp_t*)handle);
176 break;
177
178 case UV_UDP:
179 uv__udp_close((uv_udp_t*)handle);
180 break;
181
182 case UV_PREPARE:
183 uv__prepare_close((uv_prepare_t*)handle);
184 break;
185
186 case UV_CHECK:
187 uv__check_close((uv_check_t*)handle);
188 break;
189
190 case UV_IDLE:
191 uv__idle_close((uv_idle_t*)handle);
192 break;
193
194 case UV_ASYNC:
195 uv__async_close((uv_async_t*)handle);
196 break;
197
198 case UV_TIMER:
199 uv__timer_close((uv_timer_t*)handle);
200 break;
201
202 case UV_PROCESS:
203 uv__process_close((uv_process_t*)handle);
204 break;
205
206 case UV_FS_EVENT:
207 uv__fs_event_close((uv_fs_event_t*)handle);
208 #if defined(__sun) || defined(__MVS__)
209 /*
210 * On Solaris, illumos, and z/OS we will not be able to dissociate the
211 * watcher for an event which is pending delivery, so we cannot always call
212 * uv__make_close_pending() straight away. The backend will call the
213 * function once the event has cleared.
214 */
215 return;
216 #endif
217 break;
218
219 case UV_POLL:
220 uv__poll_close((uv_poll_t*)handle);
221 break;
222
223 case UV_FS_POLL:
224 uv__fs_poll_close((uv_fs_poll_t*)handle);
225 /* Poll handles use file system requests, and one of them may still be
226 * running. The poll code will call uv__make_close_pending() for us. */
227 return;
228
229 case UV_SIGNAL:
230 uv__signal_close((uv_signal_t*) handle);
231 break;
232
233 default:
234 assert(0);
235 }
236
237 uv__make_close_pending(handle);
238 }
239
240 int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
241 int r;
242 int fd;
243 socklen_t len;
244
245 if (handle == NULL || value == NULL)
246 return UV_EINVAL;
247
248 if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
249 fd = uv__stream_fd((uv_stream_t*) handle);
250 else if (handle->type == UV_UDP)
251 fd = ((uv_udp_t *) handle)->io_watcher.fd;
252 else
253 return UV_ENOTSUP;
254
255 len = sizeof(*value);
256
257 if (*value == 0)
258 r = getsockopt(fd, SOL_SOCKET, optname, value, &len);
259 else
260 r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
261
262 if (r < 0)
263 return UV__ERR(errno);
264
265 return 0;
266 }
267
268 void uv__make_close_pending(uv_handle_t* handle) {
269 assert(handle->flags & UV_HANDLE_CLOSING);
270 assert(!(handle->flags & UV_HANDLE_CLOSED));
271 handle->next_closing = handle->loop->closing_handles;
272 handle->loop->closing_handles = handle;
273 }
274
275 int uv__getiovmax(void) {
276 #if defined(IOV_MAX)
277 return IOV_MAX;
278 #elif defined(_SC_IOV_MAX)
279 static _Atomic int iovmax_cached = -1;
280 int iovmax;
281
282 iovmax = atomic_load_explicit(&iovmax_cached, memory_order_relaxed);
283 if (iovmax != -1)
284 return iovmax;
285
286 /* On some embedded devices (arm-linux-uclibc based ip camera),
287 * sysconf(_SC_IOV_MAX) can not get the correct value. The return
288 * value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
289 */
290 iovmax = sysconf(_SC_IOV_MAX);
291 if (iovmax == -1)
292 iovmax = 1;
293
294 atomic_store_explicit(&iovmax_cached, iovmax, memory_order_relaxed);
295
296 return iovmax;
297 #else
298 return 1024;
299 #endif
300 }
301
302
303 static void uv__finish_close(uv_handle_t* handle) {
304 uv_signal_t* sh;
305
306 /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
307 * possible for it to be active in the sense that uv__is_active() returns
308 * true.
309 *
310 * A good example is when the user calls uv_shutdown(), immediately followed
311 * by uv_close(). The handle is considered active at this point because the
312 * completion of the shutdown req is still pending.
313 */
314 assert(handle->flags & UV_HANDLE_CLOSING);
315 assert(!(handle->flags & UV_HANDLE_CLOSED));
316 handle->flags |= UV_HANDLE_CLOSED;
317
318 switch (handle->type) {
319 case UV_PREPARE:
320 case UV_CHECK:
321 case UV_IDLE:
322 case UV_ASYNC:
323 case UV_TIMER:
324 case UV_PROCESS:
325 case UV_FS_EVENT:
326 case UV_FS_POLL:
327 case UV_POLL:
328 break;
329
330 case UV_SIGNAL:
331 /* If there are any caught signals "trapped" in the signal pipe,
332 * we can't call the close callback yet. Reinserting the handle
333 * into the closing queue makes the event loop spin but that's
334 * okay because we only need to deliver the pending events.
335 */
336 sh = (uv_signal_t*) handle;
337 if (sh->caught_signals > sh->dispatched_signals) {
338 handle->flags ^= UV_HANDLE_CLOSED;
339 uv__make_close_pending(handle); /* Back into the queue. */
340 return;
341 }
342 break;
343
344 case UV_NAMED_PIPE:
345 case UV_TCP:
346 case UV_TTY:
347 uv__stream_destroy((uv_stream_t*)handle);
348 break;
349
350 case UV_UDP:
351 uv__udp_finish_close((uv_udp_t*)handle);
352 break;
353
354 default:
355 assert(0);
356 break;
357 }
358
359 uv__handle_unref(handle);
360 uv__queue_remove(&handle->handle_queue);
361
362 if (handle->close_cb) {
363 handle->close_cb(handle);
364 }
365 }
366
367
368 static void uv__run_closing_handles(uv_loop_t* loop) {
369 uv_handle_t* p;
370 uv_handle_t* q;
371
372 p = loop->closing_handles;
373 loop->closing_handles = NULL;
374
375 while (p) {
376 q = p->next_closing;
377 uv__finish_close(p);
378 p = q;
379 }
380 }
381
382
383 int uv_is_closing(const uv_handle_t* handle) {
384 return uv__is_closing(handle);
385 }
386
387
388 int uv_backend_fd(const uv_loop_t* loop) {
389 return loop->backend_fd;
390 }
391
392
393 static int uv__loop_alive(const uv_loop_t* loop) {
394 return uv__has_active_handles(loop) ||
395 uv__has_active_reqs(loop) ||
396 !uv__queue_empty(&loop->pending_queue) ||
397 loop->closing_handles != NULL;
398 }
399
400
401 static int uv__backend_timeout(const uv_loop_t* loop) {
402 if (loop->stop_flag == 0 &&
403 /* uv__loop_alive(loop) && */
404 (uv__has_active_handles(loop) || uv__has_active_reqs(loop)) &&
405 uv__queue_empty(&loop->pending_queue) &&
406 uv__queue_empty(&loop->idle_handles) &&
407 (loop->flags & UV_LOOP_REAP_CHILDREN) == 0 &&
408 loop->closing_handles == NULL)
409 return uv__next_timeout(loop);
410 return 0;
411 }
412
413
414 int uv_backend_timeout(const uv_loop_t* loop) {
415 if (uv__queue_empty(&loop->watcher_queue))
416 return uv__backend_timeout(loop);
417 /* Need to call uv_run to update the backend fd state. */
418 return 0;
419 }
420
421
422 int uv_loop_alive(const uv_loop_t* loop) {
423 return uv__loop_alive(loop);
424 }
425
426
427 int uv_run(uv_loop_t* loop, uv_run_mode mode) {
428 int timeout;
429 int r;
430 int can_sleep;
431
432 r = uv__loop_alive(loop);
433 if (!r)
434 uv__update_time(loop);
435
436 /* Maintain backwards compatibility by processing timers before entering the
437 * while loop for UV_RUN_DEFAULT. Otherwise timers only need to be executed
438 * once, which should be done after polling in order to maintain proper
439 * execution order of the conceptual event loop. */
440 if (mode == UV_RUN_DEFAULT && r != 0 && loop->stop_flag == 0) {
441 uv__update_time(loop);
442 uv__run_timers(loop);
443 }
444
445 while (r != 0 && loop->stop_flag == 0) {
446 can_sleep =
447 uv__queue_empty(&loop->pending_queue) &&
448 uv__queue_empty(&loop->idle_handles);
449
450 uv__run_pending(loop);
451 uv__run_idle(loop);
452 uv__run_prepare(loop);
453
454 timeout = 0;
455 if ((mode == UV_RUN_ONCE && can_sleep) || mode == UV_RUN_DEFAULT)
456 timeout = uv__backend_timeout(loop);
457
458 uv__metrics_inc_loop_count(loop);
459
460 uv__io_poll(loop, timeout);
461
462 /* Process immediate callbacks (e.g. write_cb) a small fixed number of
463 * times to avoid loop starvation.*/
464 for (r = 0; r < 8 && !uv__queue_empty(&loop->pending_queue); r++)
465 uv__run_pending(loop);
466
467 /* Run one final update on the provider_idle_time in case uv__io_poll
468 * returned because the timeout expired, but no events were received. This
469 * call will be ignored if the provider_entry_time was either never set (if
470 * the timeout == 0) or was already updated b/c an event was received.
471 */
472 uv__metrics_update_idle_time(loop);
473
474 uv__run_check(loop);
475 uv__run_closing_handles(loop);
476
477 uv__update_time(loop);
478 uv__run_timers(loop);
479
480 r = uv__loop_alive(loop);
481 if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
482 break;
483 }
484
485 /* The if statement lets gcc compile it to a conditional store. Avoids
486 * dirtying a cache line.
487 */
488 if (loop->stop_flag != 0)
489 loop->stop_flag = 0;
490
491 return r;
492 }
493
494
495 void uv_update_time(uv_loop_t* loop) {
496 uv__update_time(loop);
497 }
498
499
500 int uv_is_active(const uv_handle_t* handle) {
501 return uv__is_active(handle);
502 }
503
504
505 /* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
506 int uv__socket(int domain, int type, int protocol) {
507 int sockfd;
508 int err;
509
510 #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
511 sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
512 if (sockfd != -1)
513 return sockfd;
514
515 if (errno != EINVAL)
516 return UV__ERR(errno);
517 #endif
518
519 sockfd = socket(domain, type, protocol);
520 if (sockfd == -1)
521 return UV__ERR(errno);
522
523 err = uv__nonblock(sockfd, 1);
524 if (err == 0)
525 err = uv__cloexec(sockfd, 1);
526
527 if (err) {
528 uv__close(sockfd);
529 return err;
530 }
531
532 #if defined(SO_NOSIGPIPE)
533 {
534 int on = 1;
535 setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
536 }
537 #endif
538
539 return sockfd;
540 }
541
542 /* get a file pointer to a file in read-only and close-on-exec mode */
543 FILE* uv__open_file(const char* path) {
544 int fd;
545 FILE* fp;
546
547 fd = uv__open_cloexec(path, O_RDONLY);
548 if (fd < 0)
549 return NULL;
550
551 fp = fdopen(fd, "r");
552 if (fp == NULL)
553 uv__close(fd);
554
555 return fp;
556 }
557
558
559 int uv__accept(int sockfd) {
560 int peerfd;
561 int err;
562
563 (void) &err;
564 assert(sockfd >= 0);
565
566 do
567 #ifdef uv__accept4
568 peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
569 #else
570 peerfd = accept(sockfd, NULL, NULL);
571 #endif
572 while (peerfd == -1 && errno == EINTR);
573
574 if (peerfd == -1)
575 return UV__ERR(errno);
576
577 #ifndef uv__accept4
578 err = uv__cloexec(peerfd, 1);
579 if (err == 0)
580 err = uv__nonblock(peerfd, 1);
581
582 if (err != 0) {
583 uv__close(peerfd);
584 return err;
585 }
586 #endif
587
588 return peerfd;
589 }
590
591
592 /* close() on macos has the "interesting" quirk that it fails with EINTR
593 * without closing the file descriptor when a thread is in the cancel state.
594 * That's why libuv calls close$NOCANCEL() instead.
595 *
596 * glibc on linux has a similar issue: close() is a cancellation point and
597 * will unwind the thread when it's in the cancel state. Work around that
598 * by making the system call directly. Musl libc is unaffected.
599 */
600 int uv__close_nocancel(int fd) {
601 #if defined(__APPLE__)
602 #pragma GCC diagnostic push
603 #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
604 #if defined(__LP64__) || TARGET_OS_IPHONE
605 extern int close$NOCANCEL(int);
606 return close$NOCANCEL(fd);
607 #else
608 extern int close$NOCANCEL$UNIX2003(int);
609 return close$NOCANCEL$UNIX2003(fd);
610 #endif
611 #pragma GCC diagnostic pop
612 #elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
613 long rc;
614 __sanitizer_syscall_pre_close(fd);
615 rc = syscall(SYS_close, fd);
616 __sanitizer_syscall_post_close(rc, fd);
617 return rc;
618 #elif defined(__linux__) && !defined(__SANITIZE_THREAD__)
619 return syscall(SYS_close, fd);
620 #else
621 return close(fd);
622 #endif
623 }
624
625
626 int uv__close_nocheckstdio(int fd) {
627 int saved_errno;
628 int rc;
629
630 assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */
631
632 saved_errno = errno;
633 rc = uv__close_nocancel(fd);
634 if (rc == -1) {
635 rc = UV__ERR(errno);
636 if (rc == UV_EINTR || rc == UV__ERR(EINPROGRESS))
637 rc = 0; /* The close is in progress, not an error. */
638 errno = saved_errno;
639 }
640
641 return rc;
642 }
643
644
645 int uv__close(int fd) {
646 assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
647 #if defined(__MVS__)
648 SAVE_ERRNO(epoll_file_close(fd));
649 #endif
650 return uv__close_nocheckstdio(fd);
651 }
652
653 #if UV__NONBLOCK_IS_IOCTL
654 int uv__nonblock_ioctl(int fd, int set) {
655 int r;
656
657 do
658 r = ioctl(fd, FIONBIO, &set);
659 while (r == -1 && errno == EINTR);
660
661 if (r)
662 return UV__ERR(errno);
663
664 return 0;
665 }
666 #endif
667
668
669 int uv__nonblock_fcntl(int fd, int set) {
670 int flags;
671 int r;
672
673 do
674 r = fcntl(fd, F_GETFL);
675 while (r == -1 && errno == EINTR);
676
677 if (r == -1)
678 return UV__ERR(errno);
679
680 /* Bail out now if already set/clear. */
681 if (!!(r & O_NONBLOCK) == !!set)
682 return 0;
683
684 if (set)
685 flags = r | O_NONBLOCK;
686 else
687 flags = r & ~O_NONBLOCK;
688
689 do
690 r = fcntl(fd, F_SETFL, flags);
691 while (r == -1 && errno == EINTR);
692
693 if (r)
694 return UV__ERR(errno);
695
696 return 0;
697 }
698
699
700 int uv__cloexec(int fd, int set) {
701 int flags;
702 int r;
703
704 flags = 0;
705 if (set)
706 flags = FD_CLOEXEC;
707
708 do
709 r = fcntl(fd, F_SETFD, flags);
710 while (r == -1 && errno == EINTR);
711
712 if (r)
713 return UV__ERR(errno);
714
715 return 0;
716 }
717
718
719 ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
720 #if defined(__ANDROID__) || \
721 defined(__DragonFly__) || \
722 defined(__FreeBSD__) || \
723 defined(__NetBSD__) || \
724 defined(__OpenBSD__) || \
725 defined(__linux__)
726 ssize_t rc;
727 rc = recvmsg(fd, msg, flags | MSG_CMSG_CLOEXEC);
728 if (rc == -1)
729 return UV__ERR(errno);
730 return rc;
731 #else
732 struct cmsghdr* cmsg;
733 int* pfd;
734 int* end;
735 ssize_t rc;
736 rc = recvmsg(fd, msg, flags);
737 if (rc == -1)
738 return UV__ERR(errno);
739 if (msg->msg_controllen == 0)
740 return rc;
741 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
742 if (cmsg->cmsg_type == SCM_RIGHTS)
743 for (pfd = (int*) CMSG_DATA(cmsg),
744 end = (int*) ((char*) cmsg + cmsg->cmsg_len);
745 pfd < end;
746 pfd += 1)
747 uv__cloexec(*pfd, 1);
748 return rc;
749 #endif
750 }
751
752
753 int uv_cwd(char* buffer, size_t* size) {
754 char scratch[1 + UV__PATH_MAX];
755
756 if (buffer == NULL || size == NULL || *size == 0)
757 return UV_EINVAL;
758
759 /* Try to read directly into the user's buffer first... */
760 if (getcwd(buffer, *size) != NULL)
761 goto fixup;
762
763 if (errno != ERANGE)
764 return UV__ERR(errno);
765
766 /* ...or into scratch space if the user's buffer is too small
767 * so we can report how much space to provide on the next try.
768 */
769 if (getcwd(scratch, sizeof(scratch)) == NULL)
770 return UV__ERR(errno);
771
772 buffer = scratch;
773
774 fixup:
775
776 *size = strlen(buffer);
777
778 if (*size > 1 && buffer[*size - 1] == '/') {
779 *size -= 1;
780 buffer[*size] = '\0';
781 }
782
783 if (buffer == scratch) {
784 *size += 1;
785 return UV_ENOBUFS;
786 }
787
788 return 0;
789 }
790
791
792 int uv_chdir(const char* dir) {
793 if (chdir(dir))
794 return UV__ERR(errno);
795
796 return 0;
797 }
798
799
800 void uv_disable_stdio_inheritance(void) {
801 int fd;
802
803 /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the
804 * first 16 file descriptors. After that, bail out after the first error.
805 */
806 for (fd = 0; ; fd++)
807 if (uv__cloexec(fd, 1) && fd > 15)
808 break;
809 }
810
811
812 int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
813 int fd_out;
814
815 switch (handle->type) {
816 case UV_TCP:
817 case UV_NAMED_PIPE:
818 case UV_TTY:
819 fd_out = uv__stream_fd((uv_stream_t*) handle);
820 break;
821
822 case UV_UDP:
823 fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
824 break;
825
826 case UV_POLL:
827 fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
828 break;
829
830 default:
831 return UV_EINVAL;
832 }
833
834 if (uv__is_closing(handle) || fd_out == -1)
835 return UV_EBADF;
836
837 *fd = fd_out;
838 return 0;
839 }
840
841
842 static void uv__run_pending(uv_loop_t* loop) {
843 struct uv__queue* q;
844 struct uv__queue pq;
845 uv__io_t* w;
846
847 uv__queue_move(&loop->pending_queue, &pq);
848
849 while (!uv__queue_empty(&pq)) {
850 q = uv__queue_head(&pq);
851 uv__queue_remove(q);
852 uv__queue_init(q);
853 w = uv__queue_data(q, uv__io_t, pending_queue);
854 w->cb(loop, w, POLLOUT);
855 }
856 }
857
858
859 static unsigned int next_power_of_two(unsigned int val) {
860 val -= 1;
861 val |= val >> 1;
862 val |= val >> 2;
863 val |= val >> 4;
864 val |= val >> 8;
865 val |= val >> 16;
866 val += 1;
867 return val;
868 }
869
870 static int maybe_resize(uv_loop_t* loop, unsigned int len) {
871 uv__io_t** watchers;
872 void* fake_watcher_list;
873 void* fake_watcher_count;
874 unsigned int nwatchers;
875 unsigned int i;
876
877 if (len <= loop->nwatchers)
878 return 0;
879
880 /* Preserve fake watcher list and count at the end of the watchers */
881 if (loop->watchers != NULL) {
882 fake_watcher_list = loop->watchers[loop->nwatchers];
883 fake_watcher_count = loop->watchers[loop->nwatchers + 1];
884 } else {
885 fake_watcher_list = NULL;
886 fake_watcher_count = NULL;
887 }
888
889 nwatchers = next_power_of_two(len + 2) - 2;
890 watchers = uv__reallocf(loop->watchers,
891 (nwatchers + 2) * sizeof(loop->watchers[0]));
892
893 if (watchers == NULL)
894 return UV_ENOMEM;
895 for (i = loop->nwatchers; i < nwatchers; i++)
896 watchers[i] = NULL;
897 watchers[nwatchers] = fake_watcher_list;
898 watchers[nwatchers + 1] = fake_watcher_count;
899
900 loop->watchers = watchers;
901 loop->nwatchers = nwatchers;
902 return 0;
903 }
904
905
906 void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
907 assert(fd >= -1);
908 uv__queue_init(&w->pending_queue);
909 uv__queue_init(&w->watcher_queue);
910 w->cb = cb;
911 w->fd = fd;
912 w->events = 0;
913 w->pevents = 0;
914 }
915
916
917 int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
918 int err;
919
920 assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
921 assert(0 != events);
922 assert(w->fd >= 0);
923 assert(w->fd < INT_MAX);
924
925 w->pevents |= events;
926 err = maybe_resize(loop, w->fd + 1);
927 if (err)
928 return err;
929
930 #if !defined(__sun)
931 /* The event ports backend needs to rearm all file descriptors on each and
932 * every tick of the event loop but the other backends allow us to
933 * short-circuit here if the event mask is unchanged.
934 */
935 if (w->events == w->pevents)
936 return 0;
937 #endif
938
939 if (uv__queue_empty(&w->watcher_queue))
940 uv__queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
941
942 if (loop->watchers[w->fd] == NULL) {
943 loop->watchers[w->fd] = w;
944 loop->nfds++;
945 }
946
947 return 0;
948 }
949
950
951 int uv__io_init_start(uv_loop_t* loop,
952 uv__io_t* w,
953 uv__io_cb cb,
954 int fd,
955 unsigned int events) {
956 int err;
957
958 assert(cb != NULL);
959 assert(fd > -1);
960 uv__io_init(w, cb, fd);
961 err = uv__io_start(loop, w, events);
962 if (err)
963 uv__io_init(w, NULL, -1);
964 return err;
965 }
966
967
968 void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
969 assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
970 assert(0 != events);
971
972 if (w->fd == -1)
973 return;
974
975 assert(w->fd >= 0);
976
977 /* Happens when uv__io_stop() is called on a handle that was never started. */
978 if ((unsigned) w->fd >= loop->nwatchers)
979 return;
980
981 w->pevents &= ~events;
982
983 if (w->pevents == 0) {
984 uv__queue_remove(&w->watcher_queue);
985 uv__queue_init(&w->watcher_queue);
986 w->events = 0;
987
988 if (w == loop->watchers[w->fd]) {
989 assert(loop->nfds > 0);
990 loop->watchers[w->fd] = NULL;
991 loop->nfds--;
992 }
993 }
994 else if (uv__queue_empty(&w->watcher_queue))
995 uv__queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);
996 }
997
998
999 void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
1000 uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
1001 uv__queue_remove(&w->pending_queue);
1002
1003 /* Remove stale events for this file descriptor */
1004 if (w->fd != -1)
1005 uv__platform_invalidate_fd(loop, w->fd);
1006 }
1007
1008
1009 void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
1010 if (uv__queue_empty(&w->pending_queue))
1011 uv__queue_insert_tail(&loop->pending_queue, &w->pending_queue);
1012 }
1013
1014
1015 int uv__io_active(const uv__io_t* w, unsigned int events) {
1016 assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
1017 assert(0 != events);
1018 return 0 != (w->pevents & events);
1019 }
1020
1021
1022 int uv__fd_exists(uv_loop_t* loop, int fd) {
1023 return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
1024 }
1025
1026
1027 static int uv__getrusage(int who, uv_rusage_t* rusage) {
1028 struct rusage usage;
1029
1030 if (getrusage(who, &usage))
1031 return UV__ERR(errno);
1032
1033 rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
1034 rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
1035
1036 rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
1037 rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
1038
1039 #if !defined(__MVS__) && !defined(__HAIKU__)
1040 rusage->ru_maxrss = usage.ru_maxrss;
1041 rusage->ru_ixrss = usage.ru_ixrss;
1042 rusage->ru_idrss = usage.ru_idrss;
1043 rusage->ru_isrss = usage.ru_isrss;
1044 rusage->ru_minflt = usage.ru_minflt;
1045 rusage->ru_majflt = usage.ru_majflt;
1046 rusage->ru_nswap = usage.ru_nswap;
1047 rusage->ru_inblock = usage.ru_inblock;
1048 rusage->ru_oublock = usage.ru_oublock;
1049 rusage->ru_msgsnd = usage.ru_msgsnd;
1050 rusage->ru_msgrcv = usage.ru_msgrcv;
1051 rusage->ru_nsignals = usage.ru_nsignals;
1052 rusage->ru_nvcsw = usage.ru_nvcsw;
1053 rusage->ru_nivcsw = usage.ru_nivcsw;
1054 #endif
1055
1056 /* Most platforms report ru_maxrss in kilobytes; macOS and Solaris are
1057 * the outliers because of course they are.
1058 */
1059 #if defined(__APPLE__)
1060 rusage->ru_maxrss /= 1024; /* macOS and iOS report bytes. */
1061 #elif defined(__sun)
1062 rusage->ru_maxrss *= getpagesize() / 1024; /* Solaris reports pages. */
1063 #endif
1064
1065 return 0;
1066 }
1067
1068
1069 int uv_getrusage(uv_rusage_t* rusage) {
1070 return uv__getrusage(RUSAGE_SELF, rusage);
1071 }
1072
1073
1074 int uv_getrusage_thread(uv_rusage_t* rusage) {
1075 #if defined(__APPLE__)
1076 mach_msg_type_number_t count;
1077 thread_basic_info_data_t info;
1078 kern_return_t kr;
1079 thread_t thread;
1080
1081 thread = mach_thread_self();
1082 count = THREAD_BASIC_INFO_COUNT;
1083 kr = thread_info(thread,
1084 THREAD_BASIC_INFO,
1085 (thread_info_t)&info,
1086 &count);
1087
1088 if (kr != KERN_SUCCESS) {
1089 mach_port_deallocate(mach_task_self(), thread);
1090 return UV_EINVAL;
1091 }
1092
1093 memset(rusage, 0, sizeof(*rusage));
1094
1095 rusage->ru_utime.tv_sec = info.user_time.seconds;
1096 rusage->ru_utime.tv_usec = info.user_time.microseconds;
1097 rusage->ru_stime.tv_sec = info.system_time.seconds;
1098 rusage->ru_stime.tv_usec = info.system_time.microseconds;
1099
1100 mach_port_deallocate(mach_task_self(), thread);
1101
1102 return 0;
1103
1104 #elif defined(RUSAGE_LWP)
1105 return uv__getrusage(RUSAGE_LWP, rusage);
1106 #elif defined(RUSAGE_THREAD)
1107 return uv__getrusage(RUSAGE_THREAD, rusage);
1108 #endif /* defined(__APPLE__) */
1109 return UV_ENOTSUP;
1110 }
1111
1112
1113 int uv__open_cloexec(const char* path, int flags) {
1114 #if defined(O_CLOEXEC)
1115 int fd;
1116
1117 fd = open(path, flags | O_CLOEXEC);
1118 if (fd == -1)
1119 return UV__ERR(errno);
1120
1121 return fd;
1122 #else /* O_CLOEXEC */
1123 int err;
1124 int fd;
1125
1126 fd = open(path, flags);
1127 if (fd == -1)
1128 return UV__ERR(errno);
1129
1130 err = uv__cloexec(fd, 1);
1131 if (err) {
1132 uv__close(fd);
1133 return err;
1134 }
1135
1136 return fd;
1137 #endif /* O_CLOEXEC */
1138 }
1139
1140
1141 int uv__slurp(const char* filename, char* buf, size_t len) {
1142 ssize_t n;
1143 int fd;
1144
1145 assert(len > 0);
1146
1147 fd = uv__open_cloexec(filename, O_RDONLY);
1148 if (fd < 0)
1149 return fd;
1150
1151 do
1152 n = read(fd, buf, len - 1);
1153 while (n == -1 && errno == EINTR);
1154
1155 if (uv__close_nocheckstdio(fd))
1156 abort();
1157
1158 if (n < 0)
1159 return UV__ERR(errno);
1160
1161 buf[n] = '\0';
1162
1163 return 0;
1164 }
1165
1166
1167 int uv__dup2_cloexec(int oldfd, int newfd) {
1168 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
1169 int r;
1170
1171 r = dup3(oldfd, newfd, O_CLOEXEC);
1172 if (r == -1)
1173 return UV__ERR(errno);
1174
1175 return r;
1176 #else
1177 int err;
1178 int r;
1179
1180 r = dup2(oldfd, newfd); /* Never retry. */
1181 if (r == -1)
1182 return UV__ERR(errno);
1183
1184 err = uv__cloexec(newfd, 1);
1185 if (err != 0) {
1186 uv__close(newfd);
1187 return err;
1188 }
1189
1190 return r;
1191 #endif
1192 }
1193
1194
1195 int uv_os_homedir(char* buffer, size_t* size) {
1196 uv_passwd_t pwd;
1197 size_t len;
1198 int r;
1199
1200 /* Check if the HOME environment variable is set first. The task of
1201 performing input validation on buffer and size is taken care of by
1202 uv_os_getenv(). */
1203 r = uv_os_getenv("HOME", buffer, size);
1204
1205 if (r != UV_ENOENT)
1206 return r;
1207
1208 /* HOME is not set, so call uv_os_get_passwd() */
1209 r = uv_os_get_passwd(&pwd);
1210
1211 if (r != 0) {
1212 return r;
1213 }
1214
1215 len = strlen(pwd.homedir);
1216
1217 if (len >= *size) {
1218 *size = len + 1;
1219 uv_os_free_passwd(&pwd);
1220 return UV_ENOBUFS;
1221 }
1222
1223 memcpy(buffer, pwd.homedir, len + 1);
1224 *size = len;
1225 uv_os_free_passwd(&pwd);
1226
1227 return 0;
1228 }
1229
1230
1231 int uv_os_tmpdir(char* buffer, size_t* size) {
1232 const char* buf;
1233 size_t len;
1234
1235 if (buffer == NULL || size == NULL || *size == 0)
1236 return UV_EINVAL;
1237
1238 #define CHECK_ENV_VAR(name) \
1239 do { \
1240 buf = getenv(name); \
1241 if (buf != NULL) \
1242 goto return_buffer; \
1243 } \
1244 while (0)
1245
1246 /* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */
1247 CHECK_ENV_VAR("TMPDIR");
1248 CHECK_ENV_VAR("TMP");
1249 CHECK_ENV_VAR("TEMP");
1250 CHECK_ENV_VAR("TEMPDIR");
1251
1252 #undef CHECK_ENV_VAR
1253
1254 /* No temp environment variables defined */
1255 #if defined(__ANDROID__)
1256 buf = "/data/local/tmp";
1257 #else
1258 buf = "/tmp";
1259 #endif
1260
1261 return_buffer:
1262 len = strlen(buf);
1263
1264 if (len >= *size) {
1265 *size = len + 1;
1266 return UV_ENOBUFS;
1267 }
1268
1269 /* The returned directory should not have a trailing slash. */
1270 if (len > 1 && buf[len - 1] == '/') {
1271 len--;
1272 }
1273
1274 memcpy(buffer, buf, len + 1);
1275 buffer[len] = '\0';
1276 *size = len;
1277
1278 return 0;
1279 }
1280
1281
1282 static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) {
1283 struct passwd pw;
1284 struct passwd* result;
1285 char* buf;
1286 size_t bufsize;
1287 size_t name_size;
1288 size_t homedir_size;
1289 size_t shell_size;
1290 int r;
1291
1292 if (pwd == NULL)
1293 return UV_EINVAL;
1294
1295 /* Calling sysconf(_SC_GETPW_R_SIZE_MAX) would get the suggested size, but it
1296 * is frequently 1024 or 4096, so we can just use that directly. The pwent
1297 * will not usually be large. */
1298 for (bufsize = 2000;; bufsize *= 2) {
1299 buf = uv__malloc(bufsize);
1300
1301 if (buf == NULL)
1302 return UV_ENOMEM;
1303
1304 do
1305 r = getpwuid_r(uid, &pw, buf, bufsize, &result);
1306 while (r == EINTR);
1307
1308 if (r != 0 || result == NULL)
1309 uv__free(buf);
1310
1311 if (r != ERANGE)
1312 break;
1313 }
1314
1315 if (r != 0)
1316 return UV__ERR(r);
1317
1318 if (result == NULL)
1319 return UV_ENOENT;
1320
1321 /* Allocate memory for the username, shell, and home directory */
1322 name_size = strlen(pw.pw_name) + 1;
1323 homedir_size = strlen(pw.pw_dir) + 1;
1324 shell_size = strlen(pw.pw_shell) + 1;
1325 pwd->username = uv__malloc(name_size + homedir_size + shell_size);
1326
1327 if (pwd->username == NULL) {
1328 uv__free(buf);
1329 return UV_ENOMEM;
1330 }
1331
1332 /* Copy the username */
1333 memcpy(pwd->username, pw.pw_name, name_size);
1334
1335 /* Copy the home directory */
1336 pwd->homedir = pwd->username + name_size;
1337 memcpy(pwd->homedir, pw.pw_dir, homedir_size);
1338
1339 /* Copy the shell */
1340 pwd->shell = pwd->homedir + homedir_size;
1341 memcpy(pwd->shell, pw.pw_shell, shell_size);
1342
1343 /* Copy the uid and gid */
1344 pwd->uid = pw.pw_uid;
1345 pwd->gid = pw.pw_gid;
1346
1347 uv__free(buf);
1348
1349 return 0;
1350 }
1351
1352
1353 int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) {
1354 #if defined(__ANDROID__) && __ANDROID_API__ < 24
1355 /* This function getgrgid_r() was added in Android N (level 24) */
1356 return UV_ENOSYS;
1357 #else
1358 struct group gp;
1359 struct group* result;
1360 char* buf;
1361 char* gr_mem;
1362 size_t bufsize;
1363 size_t name_size;
1364 long members;
1365 size_t mem_size;
1366 int r;
1367
1368 if (grp == NULL)
1369 return UV_EINVAL;
1370
1371 /* Calling sysconf(_SC_GETGR_R_SIZE_MAX) would get the suggested size, but it
1372 * is frequently 1024 or 4096, so we can just use that directly. The pwent
1373 * will not usually be large. */
1374 for (bufsize = 2000;; bufsize *= 2) {
1375 buf = uv__malloc(bufsize);
1376
1377 if (buf == NULL)
1378 return UV_ENOMEM;
1379
1380 do
1381 r = getgrgid_r(gid, &gp, buf, bufsize, &result);
1382 while (r == EINTR);
1383
1384 if (r != 0 || result == NULL)
1385 uv__free(buf);
1386
1387 if (r != ERANGE)
1388 break;
1389 }
1390
1391 if (r != 0)
1392 return UV__ERR(r);
1393
1394 if (result == NULL)
1395 return UV_ENOENT;
1396
1397 /* Allocate memory for the groupname and members. */
1398 name_size = strlen(gp.gr_name) + 1;
1399 members = 0;
1400 mem_size = sizeof(char*);
1401 for (r = 0; gp.gr_mem[r] != NULL; r++) {
1402 mem_size += strlen(gp.gr_mem[r]) + 1 + sizeof(char*);
1403 members++;
1404 }
1405
1406 gr_mem = uv__malloc(name_size + mem_size);
1407 if (gr_mem == NULL) {
1408 uv__free(buf);
1409 return UV_ENOMEM;
1410 }
1411
1412 /* Copy the members */
1413 grp->members = (char**) gr_mem;
1414 grp->members[members] = NULL;
1415 gr_mem = (char*) &grp->members[members + 1];
1416 for (r = 0; r < members; r++) {
1417 grp->members[r] = gr_mem;
1418 strcpy(gr_mem, gp.gr_mem[r]);
1419 gr_mem += strlen(gr_mem) + 1;
1420 }
1421 assert(gr_mem == (char*)grp->members + mem_size);
1422
1423 /* Copy the groupname */
1424 grp->groupname = gr_mem;
1425 memcpy(grp->groupname, gp.gr_name, name_size);
1426 gr_mem += name_size;
1427
1428 /* Copy the gid */
1429 grp->gid = gp.gr_gid;
1430
1431 uv__free(buf);
1432
1433 return 0;
1434 #endif
1435 }
1436
1437
1438 int uv_os_get_passwd(uv_passwd_t* pwd) {
1439 return uv__getpwuid_r(pwd, geteuid());
1440 }
1441
1442
1443 int uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid) {
1444 return uv__getpwuid_r(pwd, uid);
1445 }
1446
1447
1448 int uv_translate_sys_error(int sys_errno) {
1449 /* If < 0 then it's already a libuv error. */
1450 return sys_errno <= 0 ? sys_errno : -sys_errno;
1451 }
1452
1453
1454 int uv_os_environ(uv_env_item_t** envitems, int* count) {
1455 int i, j, cnt;
1456 uv_env_item_t* envitem;
1457
1458 *envitems = NULL;
1459 *count = 0;
1460
1461 for (i = 0; environ[i] != NULL; i++);
1462
1463 *envitems = uv__calloc(i, sizeof(**envitems));
1464
1465 if (*envitems == NULL)
1466 return UV_ENOMEM;
1467
1468 for (j = 0, cnt = 0; j < i; j++) {
1469 char* buf;
1470 char* ptr;
1471
1472 if (environ[j] == NULL)
1473 break;
1474
1475 buf = uv__strdup(environ[j]);
1476 if (buf == NULL)
1477 goto fail;
1478
1479 ptr = strchr(buf, '=');
1480 if (ptr == NULL) {
1481 uv__free(buf);
1482 continue;
1483 }
1484
1485 *ptr = '\0';
1486
1487 envitem = &(*envitems)[cnt];
1488 envitem->name = buf;
1489 envitem->value = ptr + 1;
1490
1491 cnt++;
1492 }
1493
1494 *count = cnt;
1495 return 0;
1496
1497 fail:
1498 for (i = 0; i < cnt; i++) {
1499 envitem = &(*envitems)[cnt];
1500 uv__free(envitem->name);
1501 }
1502 uv__free(*envitems);
1503
1504 *envitems = NULL;
1505 *count = 0;
1506 return UV_ENOMEM;
1507 }
1508
1509
1510 int uv_os_getenv(const char* name, char* buffer, size_t* size) {
1511 char* var;
1512 size_t len;
1513
1514 if (name == NULL || buffer == NULL || size == NULL || *size == 0)
1515 return UV_EINVAL;
1516
1517 var = getenv(name);
1518
1519 if (var == NULL)
1520 return UV_ENOENT;
1521
1522 len = strlen(var);
1523
1524 if (len >= *size) {
1525 *size = len + 1;
1526 return UV_ENOBUFS;
1527 }
1528
1529 memcpy(buffer, var, len + 1);
1530 *size = len;
1531
1532 return 0;
1533 }
1534
1535
1536 int uv_os_setenv(const char* name, const char* value) {
1537 if (name == NULL || value == NULL)
1538 return UV_EINVAL;
1539
1540 if (setenv(name, value, 1) != 0)
1541 return UV__ERR(errno);
1542
1543 return 0;
1544 }
1545
1546
1547 int uv_os_unsetenv(const char* name) {
1548 if (name == NULL)
1549 return UV_EINVAL;
1550
1551 if (unsetenv(name) != 0)
1552 return UV__ERR(errno);
1553
1554 return 0;
1555 }
1556
1557
1558 int uv_os_gethostname(char* buffer, size_t* size) {
1559 /*
1560 On some platforms, if the input buffer is not large enough, gethostname()
1561 succeeds, but truncates the result. libuv can detect this and return ENOBUFS
1562 instead by creating a large enough buffer and comparing the hostname length
1563 to the size input.
1564 */
1565 char buf[UV_MAXHOSTNAMESIZE];
1566 size_t len;
1567
1568 if (buffer == NULL || size == NULL || *size == 0)
1569 return UV_EINVAL;
1570
1571 if (gethostname(buf, sizeof(buf)) != 0)
1572 return UV__ERR(errno);
1573
1574 buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
1575 len = strlen(buf);
1576
1577 if (len >= *size) {
1578 *size = len + 1;
1579 return UV_ENOBUFS;
1580 }
1581
1582 memcpy(buffer, buf, len + 1);
1583 *size = len;
1584 return 0;
1585 }
1586
1587
1588 uv_os_fd_t uv_get_osfhandle(int fd) {
1589 return fd;
1590 }
1591
1592 int uv_open_osfhandle(uv_os_fd_t os_fd) {
1593 return os_fd;
1594 }
1595
1596 uv_pid_t uv_os_getpid(void) {
1597 return getpid();
1598 }
1599
1600
1601 uv_pid_t uv_os_getppid(void) {
1602 return getppid();
1603 }
1604
1605 int uv_cpumask_size(void) {
1606 #if UV__CPU_AFFINITY_SUPPORTED
1607 return CPU_SETSIZE;
1608 #else
1609 return UV_ENOTSUP;
1610 #endif
1611 }
1612
1613 int uv_os_getpriority(uv_pid_t pid, int* priority) {
1614 int r;
1615
1616 if (priority == NULL)
1617 return UV_EINVAL;
1618
1619 errno = 0;
1620 r = getpriority(PRIO_PROCESS, (int) pid);
1621
1622 if (r == -1 && errno != 0)
1623 return UV__ERR(errno);
1624
1625 *priority = r;
1626 return 0;
1627 }
1628
1629
1630 int uv_os_setpriority(uv_pid_t pid, int priority) {
1631 if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
1632 return UV_EINVAL;
1633
1634 if (setpriority(PRIO_PROCESS, (int) pid, priority) != 0)
1635 return UV__ERR(errno);
1636
1637 return 0;
1638 }
1639
1640 /**
1641 * If the function succeeds, the return value is 0.
1642 * If the function fails, the return value is non-zero.
1643 * for Linux, when schedule policy is SCHED_OTHER (default), priority is 0.
1644 * So the output parameter priority is actually the nice value.
1645 */
1646 int uv_thread_getpriority(uv_thread_t tid, int* priority) {
1647 int r;
1648 int policy;
1649 struct sched_param param;
1650 #ifdef __linux__
1651 pid_t pid = gettid();
1652 #endif
1653
1654 if (priority == NULL)
1655 return UV_EINVAL;
1656
1657 r = pthread_getschedparam(tid, &policy, &param);
1658 if (r != 0)
1659 return UV__ERR(errno);
1660
1661 #ifdef __linux__
1662 if (SCHED_OTHER == policy && pthread_equal(tid, pthread_self())) {
1663 errno = 0;
1664 r = getpriority(PRIO_PROCESS, pid);
1665 if (r == -1 && errno != 0)
1666 return UV__ERR(errno);
1667 *priority = r;
1668 return 0;
1669 }
1670 #endif
1671
1672 *priority = param.sched_priority;
1673 return 0;
1674 }
1675
1676 #ifdef __linux__
1677 static int set_nice_for_calling_thread(int priority) {
1678 int r;
1679 int nice;
1680
1681 if (priority < UV_THREAD_PRIORITY_LOWEST || priority > UV_THREAD_PRIORITY_HIGHEST)
1682 return UV_EINVAL;
1683
1684 pid_t pid = gettid();
1685 nice = 0 - priority * 2;
1686 r = setpriority(PRIO_PROCESS, pid, nice);
1687 if (r != 0)
1688 return UV__ERR(errno);
1689 return 0;
1690 }
1691 #endif
1692
1693 /**
1694 * If the function succeeds, the return value is 0.
1695 * If the function fails, the return value is non-zero.
1696 */
1697 int uv_thread_setpriority(uv_thread_t tid, int priority) {
1698 #if !defined(__GNU__)
1699 int r;
1700 int min;
1701 int max;
1702 int range;
1703 int prio;
1704 int policy;
1705 struct sched_param param;
1706
1707 if (priority < UV_THREAD_PRIORITY_LOWEST || priority > UV_THREAD_PRIORITY_HIGHEST)
1708 return UV_EINVAL;
1709
1710 r = pthread_getschedparam(tid, &policy, &param);
1711 if (r != 0)
1712 return UV__ERR(errno);
1713
1714 #ifdef __linux__
1715 /**
1716 * for Linux, when schedule policy is SCHED_OTHER (default), priority must be 0,
1717 * we should set the nice value in this case.
1718 */
1719 if (SCHED_OTHER == policy && pthread_equal(tid, pthread_self()))
1720 return set_nice_for_calling_thread(priority);
1721 #endif
1722
1723 #ifdef __PASE__
1724 min = 1;
1725 max = 127;
1726 #else
1727 min = sched_get_priority_min(policy);
1728 max = sched_get_priority_max(policy);
1729 #endif
1730
1731 if (min == -1 || max == -1)
1732 return UV__ERR(errno);
1733
1734 range = max - min;
1735
1736 switch (priority) {
1737 case UV_THREAD_PRIORITY_HIGHEST:
1738 prio = max;
1739 break;
1740 case UV_THREAD_PRIORITY_ABOVE_NORMAL:
1741 prio = min + range * 3 / 4;
1742 break;
1743 case UV_THREAD_PRIORITY_NORMAL:
1744 prio = min + range / 2;
1745 break;
1746 case UV_THREAD_PRIORITY_BELOW_NORMAL:
1747 prio = min + range / 4;
1748 break;
1749 case UV_THREAD_PRIORITY_LOWEST:
1750 prio = min;
1751 break;
1752 default:
1753 return 0;
1754 }
1755
1756 if (param.sched_priority != prio) {
1757 param.sched_priority = prio;
1758 r = pthread_setschedparam(tid, policy, &param);
1759 if (r != 0)
1760 return UV__ERR(errno);
1761 }
1762
1763 return 0;
1764 #else /* !defined(__GNU__) */
1765 /* Simulate success on systems where thread priority is not implemented. */
1766 return 0;
1767 #endif /* !defined(__GNU__) */
1768 }
1769
1770 int uv_os_uname(uv_utsname_t* buffer) {
1771 struct utsname buf;
1772 int r;
1773
1774 if (buffer == NULL)
1775 return UV_EINVAL;
1776
1777 if (uname(&buf) == -1) {
1778 r = UV__ERR(errno);
1779 goto error;
1780 }
1781
1782 r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
1783 if (r == UV_E2BIG)
1784 goto error;
1785
1786 #ifdef _AIX
1787 r = snprintf(buffer->release,
1788 sizeof(buffer->release),
1789 "%s.%s",
1790 buf.version,
1791 buf.release);
1792 if (r >= sizeof(buffer->release)) {
1793 r = UV_E2BIG;
1794 goto error;
1795 }
1796 #else
1797 r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release));
1798 if (r == UV_E2BIG)
1799 goto error;
1800 #endif
1801
1802 r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version));
1803 if (r == UV_E2BIG)
1804 goto error;
1805
1806 #if defined(_AIX) || defined(__PASE__)
1807 r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine));
1808 #else
1809 r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
1810 #endif
1811
1812 if (r == UV_E2BIG)
1813 goto error;
1814
1815 return 0;
1816
1817 error:
1818 buffer->sysname[0] = '\0';
1819 buffer->release[0] = '\0';
1820 buffer->version[0] = '\0';
1821 buffer->machine[0] = '\0';
1822 return r;
1823 }
1824
1825 int uv__getsockpeername(const uv_handle_t* handle,
1826 uv__peersockfunc func,
1827 struct sockaddr* name,
1828 int* namelen) {
1829 socklen_t socklen;
1830 uv_os_fd_t fd;
1831 int r;
1832
1833 r = uv_fileno(handle, &fd);
1834 if (r < 0)
1835 return r;
1836
1837 /* sizeof(socklen_t) != sizeof(int) on some systems. */
1838 socklen = (socklen_t) *namelen;
1839
1840 if (func(fd, name, &socklen))
1841 return UV__ERR(errno);
1842
1843 *namelen = (int) socklen;
1844 return 0;
1845 }
1846
1847 int uv_gettimeofday(uv_timeval64_t* tv) {
1848 struct timeval time;
1849
1850 if (tv == NULL)
1851 return UV_EINVAL;
1852
1853 if (gettimeofday(&time, NULL) != 0)
1854 return UV__ERR(errno);
1855
1856 tv->tv_sec = (int64_t) time.tv_sec;
1857 tv->tv_usec = (int32_t) time.tv_usec;
1858 return 0;
1859 }
1860
1861 void uv_sleep(unsigned int msec) {
1862 struct timespec timeout;
1863 int rc;
1864
1865 timeout.tv_sec = msec / 1000;
1866 timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
1867
1868 do
1869 rc = nanosleep(&timeout, &timeout);
1870 while (rc == -1 && errno == EINTR);
1871
1872 assert(rc == 0);
1873 }
1874
1875 int uv__search_path(const char* prog, char* buf, size_t* buflen) {
1876 char abspath[UV__PATH_MAX];
1877 size_t abspath_size;
1878 char trypath[UV__PATH_MAX];
1879 char* cloned_path;
1880 char* path_env;
1881 char* token;
1882 char* itr;
1883
1884 if (buf == NULL || buflen == NULL || *buflen == 0)
1885 return UV_EINVAL;
1886
1887 /*
1888 * Possibilities for prog:
1889 * i) an absolute path such as: /home/user/myprojects/nodejs/node
1890 * ii) a relative path such as: ./node or ../myprojects/nodejs/node
1891 * iii) a bare filename such as "node", after exporting PATH variable
1892 * to its location.
1893 */
1894
1895 /* Case i) and ii) absolute or relative paths */
1896 if (strchr(prog, '/') != NULL) {
1897 if (realpath(prog, abspath) != abspath)
1898 return UV__ERR(errno);
1899
1900 abspath_size = strlen(abspath);
1901
1902 *buflen -= 1;
1903 if (*buflen > abspath_size)
1904 *buflen = abspath_size;
1905
1906 memcpy(buf, abspath, *buflen);
1907 buf[*buflen] = '\0';
1908
1909 return 0;
1910 }
1911
1912 /* Case iii). Search PATH environment variable */
1913 cloned_path = NULL;
1914 token = NULL;
1915 path_env = getenv("PATH");
1916
1917 if (path_env == NULL)
1918 return UV_EINVAL;
1919
1920 cloned_path = uv__strdup(path_env);
1921 if (cloned_path == NULL)
1922 return UV_ENOMEM;
1923
1924 token = uv__strtok(cloned_path, ":", &itr);
1925 while (token != NULL) {
1926 snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, prog);
1927 if (realpath(trypath, abspath) == abspath) {
1928 /* Check the match is executable */
1929 if (access(abspath, X_OK) == 0) {
1930 abspath_size = strlen(abspath);
1931
1932 *buflen -= 1;
1933 if (*buflen > abspath_size)
1934 *buflen = abspath_size;
1935
1936 memcpy(buf, abspath, *buflen);
1937 buf[*buflen] = '\0';
1938
1939 uv__free(cloned_path);
1940 return 0;
1941 }
1942 }
1943 token = uv__strtok(NULL, ":", &itr);
1944 }
1945 uv__free(cloned_path);
1946
1947 /* Out of tokens (path entries), and no match found */
1948 return UV_EINVAL;
1949 }
1950
1951 #if defined(__linux__) || defined (__FreeBSD__)
1952 # define uv__cpu_count(cpuset) CPU_COUNT(cpuset)
1953 #elif defined(__NetBSD__)
1954 static int uv__cpu_count(cpuset_t* set) {
1955 int rc;
1956 cpuid_t i;
1957
1958 rc = 0;
1959 for (i = 0;; i++) {
1960 int r = cpuset_isset(i, set);
1961 if (r < 0)
1962 break;
1963 if (r)
1964 rc++;
1965 }
1966
1967 return rc;
1968 }
1969 #endif /* __NetBSD__ */
1970
1971 unsigned int uv_available_parallelism(void) {
1972 long rc = -1;
1973
1974 #ifdef __linux__
1975 cpu_set_t set;
1976
1977 memset(&set, 0, sizeof(set));
1978
1979 /* sysconf(_SC_NPROCESSORS_ONLN) in musl calls sched_getaffinity() but in
1980 * glibc it's... complicated... so for consistency try sched_getaffinity()
1981 * before falling back to sysconf(_SC_NPROCESSORS_ONLN).
1982 */
1983 if (0 == sched_getaffinity(0, sizeof(set), &set))
1984 rc = uv__cpu_count(&set);
1985 #elif defined(__MVS__)
1986 rc = __get_num_online_cpus();
1987 if (rc < 1)
1988 rc = 1;
1989
1990 return (unsigned) rc;
1991 #elif defined(__FreeBSD__)
1992 cpuset_t set;
1993
1994 memset(&set, 0, sizeof(set));
1995
1996 if (0 == cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set))
1997 rc = uv__cpu_count(&set);
1998 #elif defined(__NetBSD__)
1999 cpuset_t* set = cpuset_create();
2000 if (set != NULL) {
2001 if (0 == sched_getaffinity_np(getpid(), sizeof(set), &set))
2002 rc = uv__cpu_count(&set);
2003 cpuset_destroy(set);
2004 }
2005 #elif defined(__APPLE__)
2006 int nprocs;
2007 size_t i;
2008 size_t len = sizeof(nprocs);
2009 static const char *mib[] = {
2010 "hw.activecpu",
2011 "hw.logicalcpu",
2012 "hw.ncpu"
2013 };
2014
2015 for (i = 0; i < ARRAY_SIZE(mib); i++) {
2016 if (0 == sysctlbyname(mib[i], &nprocs, &len, NULL, 0) &&
2017 len == sizeof(nprocs) &&
2018 nprocs > 0) {
2019 rc = nprocs;
2020 break;
2021 }
2022 }
2023 #elif defined(__OpenBSD__)
2024 int nprocs;
2025 size_t i;
2026 size_t len = sizeof(nprocs);
2027 static int mib[][2] = {
2028 # ifdef HW_NCPUONLINE
2029 { CTL_HW, HW_NCPUONLINE },
2030 # endif
2031 { CTL_HW, HW_NCPU }
2032 };
2033
2034 for (i = 0; i < ARRAY_SIZE(mib); i++) {
2035 if (0 == sysctl(mib[i], ARRAY_SIZE(mib[i]), &nprocs, &len, NULL, 0) &&
2036 len == sizeof(nprocs) &&
2037 nprocs > 0) {
2038 rc = nprocs;
2039 break;
2040 }
2041 }
2042 #endif /* __linux__ */
2043
2044 if (rc < 0)
2045 rc = sysconf(_SC_NPROCESSORS_ONLN);
2046
2047 #ifdef __linux__
2048 {
2049 long long quota = 0;
2050
2051 if (uv__get_constrained_cpu(&quota) == 0)
2052 if (quota > 0 && quota < rc)
2053 rc = quota;
2054 }
2055 #endif /* __linux__ */
2056
2057 if (rc < 1)
2058 rc = 1;
2059
2060 return (unsigned) rc;
2061 }
2062
2063 int uv__sock_reuseport(int fd) {
2064 int on = 1;
2065 #if defined(__FreeBSD__) && __FreeBSD__ >= 12 && defined(SO_REUSEPORT_LB)
2066 /* FreeBSD 12 introduced a new socket option named SO_REUSEPORT_LB
2067 * with the capability of load balancing, it's the substitution of
2068 * the SO_REUSEPORTs on Linux and DragonFlyBSD. */
2069 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &on, sizeof(on)))
2070 return UV__ERR(errno);
2071 #elif (defined(__linux__) || \
2072 defined(_AIX73) || \
2073 (defined(__DragonFly__) && __DragonFly_version >= 300600) || \
2074 (defined(UV__SOLARIS_11_4) && UV__SOLARIS_11_4)) && \
2075 defined(SO_REUSEPORT)
2076 /* On Linux 3.9+, the SO_REUSEPORT implementation distributes connections
2077 * evenly across all of the threads (or processes) that are blocked in
2078 * accept() on the same port. As with TCP, SO_REUSEPORT distributes datagrams
2079 * evenly across all of the receiving threads (or process).
2080 *
2081 * DragonFlyBSD 3.6.0 extended SO_REUSEPORT to distribute workload to
2082 * available sockets, which made it the equivalent of Linux's SO_REUSEPORT.
2083 *
2084 * AIX 7.2.5 added the feature that would add the capability to distribute
2085 * incoming connections or datagrams across all listening ports for SO_REUSEPORT.
2086 *
2087 * Solaris 11 supported SO_REUSEPORT, but it's implemented only for
2088 * binding to the same address and port, without load balancing.
2089 * Solaris 11.4 extended SO_REUSEPORT with the capability of load balancing.
2090 */
2091 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)))
2092 return UV__ERR(errno);
2093 #else
2094 (void) (fd);
2095 (void) (on);
2096 /* SO_REUSEPORTs do not have the capability of load balancing on platforms
2097 * other than those mentioned above. The semantics are completely different,
2098 * therefore we shouldn't enable it, but fail this operation to indicate that
2099 * UV_[TCP/UDP]_REUSEPORT is not supported on these platforms. */
2100 return UV_ENOTSUP;
2101 #endif
2102
2103 return 0;
2104 }