Blame src/unix/core.c

Packit Service 7c31a4
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Packit Service 7c31a4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
Packit Service 7c31a4
 * of this software and associated documentation files (the "Software"), to
Packit Service 7c31a4
 * deal in the Software without restriction, including without limitation the
Packit Service 7c31a4
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
Packit Service 7c31a4
 * sell copies of the Software, and to permit persons to whom the Software is
Packit Service 7c31a4
 * furnished to do so, subject to the following conditions:
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * The above copyright notice and this permission notice shall be included in
Packit Service 7c31a4
 * all copies or substantial portions of the Software.
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 7c31a4
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 7c31a4
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Packit Service 7c31a4
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit Service 7c31a4
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit Service 7c31a4
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
Packit Service 7c31a4
 * IN THE SOFTWARE.
Packit Service 7c31a4
 */
Packit Service 7c31a4
Packit Service 7c31a4
#include "uv.h"
Packit Service 7c31a4
#include "internal.h"
Packit Service 7c31a4
Packit Service 7c31a4
#include <stddef.h> /* NULL */
Packit Service 7c31a4
#include <stdio.h> /* printf */
Packit Service 7c31a4
#include <stdlib.h>
Packit Service 7c31a4
#include <string.h> /* strerror */
Packit Service 7c31a4
#include <errno.h>
Packit Service 7c31a4
#include <assert.h>
Packit Service 7c31a4
#include <unistd.h>
Packit Service 7c31a4
#include <sys/types.h>
Packit Service 7c31a4
#include <sys/stat.h>
Packit Service 7c31a4
#include <fcntl.h>  /* O_CLOEXEC */
Packit Service 7c31a4
#include <sys/ioctl.h>
Packit Service 7c31a4
#include <sys/socket.h>
Packit Service 7c31a4
#include <sys/un.h>
Packit Service 7c31a4
#include <netinet/in.h>
Packit Service 7c31a4
#include <arpa/inet.h>
Packit Service 7c31a4
#include <limits.h> /* INT_MAX, PATH_MAX, IOV_MAX */
Packit Service 7c31a4
#include <sys/uio.h> /* writev */
Packit Service 7c31a4
#include <sys/resource.h> /* getrusage */
Packit Service 7c31a4
#include <pwd.h>
Packit Service 7c31a4
#include <sys/utsname.h>
Packit Service 7c31a4
#include <sys/time.h>
Packit Service 7c31a4
Packit Service 7c31a4
#ifdef __sun
Packit Service 7c31a4
# include <sys/filio.h>
Packit Service 7c31a4
# include <sys/types.h>
Packit Service 7c31a4
# include <sys/wait.h>
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(__APPLE__)
Packit Service 7c31a4
# include <sys/filio.h>
Packit Service 7c31a4
# endif /* defined(__APPLE__) */
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(__APPLE__) && !TARGET_OS_IPHONE
Packit Service 7c31a4
# include <crt_externs.h>
Packit Service 7c31a4
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
Packit Service 7c31a4
# define environ (*_NSGetEnviron())
Packit Service 7c31a4
#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
Packit Service 7c31a4
extern char** environ;
Packit Service 7c31a4
#endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(__DragonFly__)      || \
Packit Service 7c31a4
    defined(__FreeBSD__)        || \
Packit Service 7c31a4
    defined(__FreeBSD_kernel__) || \
Packit Service 7c31a4
    defined(__NetBSD__)         || \
Packit Service 7c31a4
    defined(__OpenBSD__)
Packit Service 7c31a4
# include <sys/sysctl.h>
Packit Service 7c31a4
# include <sys/filio.h>
Packit Service 7c31a4
# include <sys/wait.h>
Packit Service 7c31a4
# if defined(__FreeBSD__)
Packit Service 7c31a4
#  define uv__accept4 accept4
Packit Service 7c31a4
# endif
Packit Service 7c31a4
# if defined(__NetBSD__)
Packit Service 7c31a4
#  define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d))
Packit Service 7c31a4
# endif
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(__MVS__)
Packit Service 7c31a4
#include <sys/ioctl.h>
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(__linux__)
Packit Service 7c31a4
# include <sys/syscall.h>
Packit Service 7c31a4
# define uv__accept4 accept4
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
static int uv__run_pending(uv_loop_t* loop);
Packit Service 7c31a4
Packit Service 7c31a4
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
Packit Service 7c31a4
STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
Packit Service 7c31a4
STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) ==
Packit Service 7c31a4
              sizeof(((struct iovec*) 0)->iov_base));
Packit Service 7c31a4
STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) ==
Packit Service 7c31a4
              sizeof(((struct iovec*) 0)->iov_len));
Packit Service 7c31a4
STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base));
Packit Service 7c31a4
STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len));
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uint64_t uv_hrtime(void) {
Packit Service 7c31a4
  return uv__hrtime(UV_CLOCK_PRECISE);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
Packit Service 7c31a4
  assert(!uv__is_closing(handle));
Packit Service 7c31a4
Packit Service 7c31a4
  handle->flags |= UV_HANDLE_CLOSING;
Packit Service 7c31a4
  handle->close_cb = close_cb;
Packit Service 7c31a4
Packit Service 7c31a4
  switch (handle->type) {
Packit Service 7c31a4
  case UV_NAMED_PIPE:
Packit Service 7c31a4
    uv__pipe_close((uv_pipe_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_TTY:
Packit Service 7c31a4
    uv__stream_close((uv_stream_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_TCP:
Packit Service 7c31a4
    uv__tcp_close((uv_tcp_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_UDP:
Packit Service 7c31a4
    uv__udp_close((uv_udp_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_PREPARE:
Packit Service 7c31a4
    uv__prepare_close((uv_prepare_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_CHECK:
Packit Service 7c31a4
    uv__check_close((uv_check_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_IDLE:
Packit Service 7c31a4
    uv__idle_close((uv_idle_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_ASYNC:
Packit Service 7c31a4
    uv__async_close((uv_async_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_TIMER:
Packit Service 7c31a4
    uv__timer_close((uv_timer_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_PROCESS:
Packit Service 7c31a4
    uv__process_close((uv_process_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_FS_EVENT:
Packit Service 7c31a4
    uv__fs_event_close((uv_fs_event_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_POLL:
Packit Service 7c31a4
    uv__poll_close((uv_poll_t*)handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_FS_POLL:
Packit Service 7c31a4
    uv__fs_poll_close((uv_fs_poll_t*)handle);
Packit Service 7c31a4
    /* Poll handles use file system requests, and one of them may still be
Packit Service 7c31a4
     * running. The poll code will call uv__make_close_pending() for us. */
Packit Service 7c31a4
    return;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_SIGNAL:
Packit Service 7c31a4
    uv__signal_close((uv_signal_t*) handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  default:
Packit Service 7c31a4
    assert(0);
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  uv__make_close_pending(handle);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
  socklen_t len;
Packit Service 7c31a4
Packit Service 7c31a4
  if (handle == NULL || value == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
Packit Service 7c31a4
    fd = uv__stream_fd((uv_stream_t*) handle);
Packit Service 7c31a4
  else if (handle->type == UV_UDP)
Packit Service 7c31a4
    fd = ((uv_udp_t *) handle)->io_watcher.fd;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    return UV_ENOTSUP;
Packit Service 7c31a4
Packit Service 7c31a4
  len = sizeof(*value);
Packit Service 7c31a4
Packit Service 7c31a4
  if (*value == 0)
Packit Service 7c31a4
    r = getsockopt(fd, SOL_SOCKET, optname, value, &len;;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r < 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
void uv__make_close_pending(uv_handle_t* handle) {
Packit Service 7c31a4
  assert(handle->flags & UV_HANDLE_CLOSING);
Packit Service 7c31a4
  assert(!(handle->flags & UV_HANDLE_CLOSED));
Packit Service 7c31a4
  handle->next_closing = handle->loop->closing_handles;
Packit Service 7c31a4
  handle->loop->closing_handles = handle;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv__getiovmax(void) {
Packit Service 7c31a4
#if defined(IOV_MAX)
Packit Service 7c31a4
  return IOV_MAX;
Packit Service 7c31a4
#elif defined(_SC_IOV_MAX)
Packit Service e2ebee
  static int iovmax_cached = -1;
Packit Service e2ebee
  int iovmax;
Packit Service e2ebee
Packit Service e2ebee
  iovmax = uv__load_relaxed(&iovmax_cached);
Packit Service e2ebee
  if (iovmax != -1)
Packit Service e2ebee
    return iovmax;
Packit Service e2ebee
Packit Service e2ebee
  /* On some embedded devices (arm-linux-uclibc based ip camera),
Packit Service e2ebee
   * sysconf(_SC_IOV_MAX) can not get the correct value. The return
Packit Service e2ebee
   * value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
Packit Service e2ebee
   */
Packit Service e2ebee
  iovmax = sysconf(_SC_IOV_MAX);
Packit Service e2ebee
  if (iovmax == -1)
Packit Service e2ebee
    iovmax = 1;
Packit Service e2ebee
Packit Service e2ebee
  uv__store_relaxed(&iovmax_cached, iovmax);
Packit Service e2ebee
Packit Service 7c31a4
  return iovmax;
Packit Service 7c31a4
#else
Packit Service 7c31a4
  return 1024;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static void uv__finish_close(uv_handle_t* handle) {
Packit Service 7c31a4
  uv_signal_t* sh;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
Packit Service 7c31a4
   * possible for it to be active in the sense that uv__is_active() returns
Packit Service 7c31a4
   * true.
Packit Service 7c31a4
   *
Packit Service 7c31a4
   * A good example is when the user calls uv_shutdown(), immediately followed
Packit Service 7c31a4
   * by uv_close(). The handle is considered active at this point because the
Packit Service 7c31a4
   * completion of the shutdown req is still pending.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  assert(handle->flags & UV_HANDLE_CLOSING);
Packit Service 7c31a4
  assert(!(handle->flags & UV_HANDLE_CLOSED));
Packit Service 7c31a4
  handle->flags |= UV_HANDLE_CLOSED;
Packit Service 7c31a4
Packit Service 7c31a4
  switch (handle->type) {
Packit Service 7c31a4
    case UV_PREPARE:
Packit Service 7c31a4
    case UV_CHECK:
Packit Service 7c31a4
    case UV_IDLE:
Packit Service 7c31a4
    case UV_ASYNC:
Packit Service 7c31a4
    case UV_TIMER:
Packit Service 7c31a4
    case UV_PROCESS:
Packit Service 7c31a4
    case UV_FS_EVENT:
Packit Service 7c31a4
    case UV_FS_POLL:
Packit Service 7c31a4
    case UV_POLL:
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    case UV_SIGNAL:
Packit Service 7c31a4
      /* If there are any caught signals "trapped" in the signal pipe,
Packit Service 7c31a4
       * we can't call the close callback yet. Reinserting the handle
Packit Service 7c31a4
       * into the closing queue makes the event loop spin but that's
Packit Service 7c31a4
       * okay because we only need to deliver the pending events.
Packit Service 7c31a4
       */
Packit Service 7c31a4
      sh = (uv_signal_t*) handle;
Packit Service 7c31a4
      if (sh->caught_signals > sh->dispatched_signals) {
Packit Service 7c31a4
        handle->flags ^= UV_HANDLE_CLOSED;
Packit Service 7c31a4
        uv__make_close_pending(handle);  /* Back into the queue. */
Packit Service 7c31a4
        return;
Packit Service 7c31a4
      }
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    case UV_NAMED_PIPE:
Packit Service 7c31a4
    case UV_TCP:
Packit Service 7c31a4
    case UV_TTY:
Packit Service 7c31a4
      uv__stream_destroy((uv_stream_t*)handle);
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    case UV_UDP:
Packit Service 7c31a4
      uv__udp_finish_close((uv_udp_t*)handle);
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    default:
Packit Service 7c31a4
      assert(0);
Packit Service 7c31a4
      break;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  uv__handle_unref(handle);
Packit Service 7c31a4
  QUEUE_REMOVE(&handle->handle_queue);
Packit Service 7c31a4
Packit Service 7c31a4
  if (handle->close_cb) {
Packit Service 7c31a4
    handle->close_cb(handle);
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static void uv__run_closing_handles(uv_loop_t* loop) {
Packit Service 7c31a4
  uv_handle_t* p;
Packit Service 7c31a4
  uv_handle_t* q;
Packit Service 7c31a4
Packit Service 7c31a4
  p = loop->closing_handles;
Packit Service 7c31a4
  loop->closing_handles = NULL;
Packit Service 7c31a4
Packit Service 7c31a4
  while (p) {
Packit Service 7c31a4
    q = p->next_closing;
Packit Service 7c31a4
    uv__finish_close(p);
Packit Service 7c31a4
    p = q;
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_is_closing(const uv_handle_t* handle) {
Packit Service 7c31a4
  return uv__is_closing(handle);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_backend_fd(const uv_loop_t* loop) {
Packit Service 7c31a4
  return loop->backend_fd;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_backend_timeout(const uv_loop_t* loop) {
Packit Service 7c31a4
  if (loop->stop_flag != 0)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (!QUEUE_EMPTY(&loop->idle_handles))
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (!QUEUE_EMPTY(&loop->pending_queue))
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (loop->closing_handles)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  return uv__next_timeout(loop);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static int uv__loop_alive(const uv_loop_t* loop) {
Packit Service 7c31a4
  return uv__has_active_handles(loop) ||
Packit Service 7c31a4
         uv__has_active_reqs(loop) ||
Packit Service 7c31a4
         loop->closing_handles != NULL;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_loop_alive(const uv_loop_t* loop) {
Packit Service 7c31a4
    return uv__loop_alive(loop);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
Packit Service 7c31a4
  int timeout;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
  int ran_pending;
Packit Service 7c31a4
Packit Service 7c31a4
  r = uv__loop_alive(loop);
Packit Service 7c31a4
  if (!r)
Packit Service 7c31a4
    uv__update_time(loop);
Packit Service 7c31a4
Packit Service 7c31a4
  while (r != 0 && loop->stop_flag == 0) {
Packit Service 7c31a4
    uv__update_time(loop);
Packit Service 7c31a4
    uv__run_timers(loop);
Packit Service 7c31a4
    ran_pending = uv__run_pending(loop);
Packit Service 7c31a4
    uv__run_idle(loop);
Packit Service 7c31a4
    uv__run_prepare(loop);
Packit Service 7c31a4
Packit Service 7c31a4
    timeout = 0;
Packit Service 7c31a4
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
Packit Service 7c31a4
      timeout = uv_backend_timeout(loop);
Packit Service 7c31a4
Packit Service 7c31a4
    uv__io_poll(loop, timeout);
Packit Service e2ebee
Packit Service e2ebee
    /* Run one final update on the provider_idle_time in case uv__io_poll
Packit Service e2ebee
     * returned because the timeout expired, but no events were received. This
Packit Service e2ebee
     * call will be ignored if the provider_entry_time was either never set (if
Packit Service e2ebee
     * the timeout == 0) or was already updated b/c an event was received.
Packit Service e2ebee
     */
Packit Service e2ebee
    uv__metrics_update_idle_time(loop);
Packit Service e2ebee
Packit Service 7c31a4
    uv__run_check(loop);
Packit Service 7c31a4
    uv__run_closing_handles(loop);
Packit Service 7c31a4
Packit Service 7c31a4
    if (mode == UV_RUN_ONCE) {
Packit Service 7c31a4
      /* UV_RUN_ONCE implies forward progress: at least one callback must have
Packit Service 7c31a4
       * been invoked when it returns. uv__io_poll() can return without doing
Packit Service 7c31a4
       * I/O (meaning: no callbacks) when its timeout expires - which means we
Packit Service 7c31a4
       * have pending timers that satisfy the forward progress constraint.
Packit Service 7c31a4
       *
Packit Service 7c31a4
       * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
Packit Service 7c31a4
       * the check.
Packit Service 7c31a4
       */
Packit Service 7c31a4
      uv__update_time(loop);
Packit Service 7c31a4
      uv__run_timers(loop);
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    r = uv__loop_alive(loop);
Packit Service 7c31a4
    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
Packit Service 7c31a4
      break;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* The if statement lets gcc compile it to a conditional store. Avoids
Packit Service 7c31a4
   * dirtying a cache line.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  if (loop->stop_flag != 0)
Packit Service 7c31a4
    loop->stop_flag = 0;
Packit Service 7c31a4
Packit Service 7c31a4
  return r;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_update_time(uv_loop_t* loop) {
Packit Service 7c31a4
  uv__update_time(loop);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_is_active(const uv_handle_t* handle) {
Packit Service 7c31a4
  return uv__is_active(handle);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
Packit Service 7c31a4
int uv__socket(int domain, int type, int protocol) {
Packit Service 7c31a4
  int sockfd;
Packit Service 7c31a4
  int err;
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
Packit Service 7c31a4
  sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
Packit Service 7c31a4
  if (sockfd != -1)
Packit Service 7c31a4
    return sockfd;
Packit Service 7c31a4
Packit Service 7c31a4
  if (errno != EINVAL)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  sockfd = socket(domain, type, protocol);
Packit Service 7c31a4
  if (sockfd == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  err = uv__nonblock(sockfd, 1);
Packit Service 7c31a4
  if (err == 0)
Packit Service 7c31a4
    err = uv__cloexec(sockfd, 1);
Packit Service 7c31a4
Packit Service 7c31a4
  if (err) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return err;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(SO_NOSIGPIPE)
Packit Service 7c31a4
  {
Packit Service 7c31a4
    int on = 1;
Packit Service 7c31a4
    setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
Packit Service 7c31a4
  }
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  return sockfd;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
/* get a file pointer to a file in read-only and close-on-exec mode */
Packit Service 7c31a4
FILE* uv__open_file(const char* path) {
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
  FILE* fp;
Packit Service 7c31a4
Packit Service 7c31a4
  fd = uv__open_cloexec(path, O_RDONLY);
Packit Service 7c31a4
  if (fd < 0)
Packit Service 7c31a4
    return NULL;
Packit Service 7c31a4
Packit Service 7c31a4
   fp = fdopen(fd, "r");
Packit Service 7c31a4
   if (fp == NULL)
Packit Service 7c31a4
     uv__close(fd);
Packit Service 7c31a4
Packit Service 7c31a4
   return fp;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__accept(int sockfd) {
Packit Service 7c31a4
  int peerfd;
Packit Service 7c31a4
  int err;
Packit Service 7c31a4
Packit Service 7c31a4
  (void) &err;
Packit Service 7c31a4
  assert(sockfd >= 0);
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
#ifdef uv__accept4
Packit Service 7c31a4
    peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
Packit Service 7c31a4
#else
Packit Service 7c31a4
    peerfd = accept(sockfd, NULL, NULL);
Packit Service 7c31a4
#endif
Packit Service 7c31a4
  while (peerfd == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (peerfd == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
#ifndef uv__accept4
Packit Service 7c31a4
  err = uv__cloexec(peerfd, 1);
Packit Service 7c31a4
  if (err == 0)
Packit Service 7c31a4
    err = uv__nonblock(peerfd, 1);
Packit Service 7c31a4
Packit Service 7c31a4
  if (err != 0) {
Packit Service 7c31a4
    uv__close(peerfd);
Packit Service 7c31a4
    return err;
Packit Service 7c31a4
  }
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  return peerfd;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
/* close() on macos has the "interesting" quirk that it fails with EINTR
Packit Service 7c31a4
 * without closing the file descriptor when a thread is in the cancel state.
Packit Service 7c31a4
 * That's why libuv calls close$NOCANCEL() instead.
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * glibc on linux has a similar issue: close() is a cancellation point and
Packit Service 7c31a4
 * will unwind the thread when it's in the cancel state. Work around that
Packit Service 7c31a4
 * by making the system call directly. Musl libc is unaffected.
Packit Service 7c31a4
 */
Packit Service 7c31a4
int uv__close_nocancel(int fd) {
Packit Service 7c31a4
#if defined(__APPLE__)
Packit Service 7c31a4
#pragma GCC diagnostic push
Packit Service 7c31a4
#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
Packit Service 7c31a4
#if defined(__LP64__) || TARGET_OS_IPHONE
Packit Service 7c31a4
  extern int close$NOCANCEL(int);
Packit Service 7c31a4
  return close$NOCANCEL(fd);
Packit Service 7c31a4
#else
Packit Service 7c31a4
  extern int close$NOCANCEL$UNIX2003(int);
Packit Service 7c31a4
  return close$NOCANCEL$UNIX2003(fd);
Packit Service 7c31a4
#endif
Packit Service 7c31a4
#pragma GCC diagnostic pop
Packit Service 7c31a4
#elif defined(__linux__)
Packit Service 7c31a4
  return syscall(SYS_close, fd);
Packit Service 7c31a4
#else
Packit Service 7c31a4
  return close(fd);
Packit Service 7c31a4
#endif
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__close_nocheckstdio(int fd) {
Packit Service 7c31a4
  int saved_errno;
Packit Service 7c31a4
  int rc;
Packit Service 7c31a4
Packit Service 7c31a4
  assert(fd > -1);  /* Catch uninitialized io_watcher.fd bugs. */
Packit Service 7c31a4
Packit Service 7c31a4
  saved_errno = errno;
Packit Service 7c31a4
  rc = uv__close_nocancel(fd);
Packit Service 7c31a4
  if (rc == -1) {
Packit Service 7c31a4
    rc = UV__ERR(errno);
Packit Service 7c31a4
    if (rc == UV_EINTR || rc == UV__ERR(EINPROGRESS))
Packit Service 7c31a4
      rc = 0;    /* The close is in progress, not an error. */
Packit Service 7c31a4
    errno = saved_errno;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return rc;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__close(int fd) {
Packit Service 7c31a4
  assert(fd > STDERR_FILENO);  /* Catch stdio close bugs. */
Packit Service 7c31a4
#if defined(__MVS__)
Packit Service 7c31a4
  SAVE_ERRNO(epoll_file_close(fd));
Packit Service 7c31a4
#endif
Packit Service 7c31a4
  return uv__close_nocheckstdio(fd);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__nonblock_ioctl(int fd, int set) {
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = ioctl(fd, FIONBIO, &set);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
Packit Service 7c31a4
int uv__cloexec_ioctl(int fd, int set) {
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = ioctl(fd, set ? FIOCLEX : FIONCLEX);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__nonblock_fcntl(int fd, int set) {
Packit Service 7c31a4
  int flags;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = fcntl(fd, F_GETFL);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Bail out now if already set/clear. */
Packit Service 7c31a4
  if (!!(r & O_NONBLOCK) == !!set)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (set)
Packit Service 7c31a4
    flags = r | O_NONBLOCK;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    flags = r & ~O_NONBLOCK;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = fcntl(fd, F_SETFL, flags);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__cloexec_fcntl(int fd, int set) {
Packit Service 7c31a4
  int flags;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = fcntl(fd, F_GETFD);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Bail out now if already set/clear. */
Packit Service 7c31a4
  if (!!(r & FD_CLOEXEC) == !!set)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (set)
Packit Service 7c31a4
    flags = r | FD_CLOEXEC;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    flags = r & ~FD_CLOEXEC;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    r = fcntl(fd, F_SETFD, flags);
Packit Service 7c31a4
  while (r == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
Packit Service 7c31a4
  struct cmsghdr* cmsg;
Packit Service 7c31a4
  ssize_t rc;
Packit Service 7c31a4
  int* pfd;
Packit Service 7c31a4
  int* end;
Packit Service 7c31a4
#if defined(__linux__)
Packit Service 7c31a4
  static int no_msg_cmsg_cloexec;
Packit Service e2ebee
  if (0 == uv__load_relaxed(&no_msg_cmsg_cloexec)) {
Packit Service 7c31a4
    rc = recvmsg(fd, msg, flags | 0x40000000);  /* MSG_CMSG_CLOEXEC */
Packit Service 7c31a4
    if (rc != -1)
Packit Service 7c31a4
      return rc;
Packit Service 7c31a4
    if (errno != EINVAL)
Packit Service 7c31a4
      return UV__ERR(errno);
Packit Service 7c31a4
    rc = recvmsg(fd, msg, flags);
Packit Service 7c31a4
    if (rc == -1)
Packit Service 7c31a4
      return UV__ERR(errno);
Packit Service e2ebee
    uv__store_relaxed(&no_msg_cmsg_cloexec, 1);
Packit Service 7c31a4
  } else {
Packit Service 7c31a4
    rc = recvmsg(fd, msg, flags);
Packit Service 7c31a4
  }
Packit Service 7c31a4
#else
Packit Service 7c31a4
  rc = recvmsg(fd, msg, flags);
Packit Service 7c31a4
#endif
Packit Service 7c31a4
  if (rc == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
  if (msg->msg_controllen == 0)
Packit Service 7c31a4
    return rc;
Packit Service 7c31a4
  for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
Packit Service 7c31a4
    if (cmsg->cmsg_type == SCM_RIGHTS)
Packit Service 7c31a4
      for (pfd = (int*) CMSG_DATA(cmsg),
Packit Service 7c31a4
           end = (int*) ((char*) cmsg + cmsg->cmsg_len);
Packit Service 7c31a4
           pfd < end;
Packit Service 7c31a4
           pfd += 1)
Packit Service 7c31a4
        uv__cloexec(*pfd, 1);
Packit Service 7c31a4
  return rc;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_cwd(char* buffer, size_t* size) {
Packit Service 7c31a4
  char scratch[1 + UV__PATH_MAX];
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == NULL || size == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Try to read directly into the user's buffer first... */
Packit Service 7c31a4
  if (getcwd(buffer, *size) != NULL)
Packit Service 7c31a4
    goto fixup;
Packit Service 7c31a4
Packit Service 7c31a4
  if (errno != ERANGE)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  /* ...or into scratch space if the user's buffer is too small
Packit Service 7c31a4
   * so we can report how much space to provide on the next try.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  if (getcwd(scratch, sizeof(scratch)) == NULL)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  buffer = scratch;
Packit Service 7c31a4
Packit Service 7c31a4
fixup:
Packit Service 7c31a4
Packit Service 7c31a4
  *size = strlen(buffer);
Packit Service 7c31a4
Packit Service 7c31a4
  if (*size > 1 && buffer[*size - 1] == '/') {
Packit Service 7c31a4
    *size -= 1;
Packit Service 7c31a4
    buffer[*size] = '\0';
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == scratch) {
Packit Service 7c31a4
    *size += 1;
Packit Service 7c31a4
    return UV_ENOBUFS;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_chdir(const char* dir) {
Packit Service 7c31a4
  if (chdir(dir))
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_disable_stdio_inheritance(void) {
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the
Packit Service 7c31a4
   * first 16 file descriptors. After that, bail out after the first error.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  for (fd = 0; ; fd++)
Packit Service 7c31a4
    if (uv__cloexec(fd, 1) && fd > 15)
Packit Service 7c31a4
      break;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
Packit Service 7c31a4
  int fd_out;
Packit Service 7c31a4
Packit Service 7c31a4
  switch (handle->type) {
Packit Service 7c31a4
  case UV_TCP:
Packit Service 7c31a4
  case UV_NAMED_PIPE:
Packit Service 7c31a4
  case UV_TTY:
Packit Service 7c31a4
    fd_out = uv__stream_fd((uv_stream_t*) handle);
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_UDP:
Packit Service 7c31a4
    fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  case UV_POLL:
Packit Service 7c31a4
    fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
Packit Service 7c31a4
    break;
Packit Service 7c31a4
Packit Service 7c31a4
  default:
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  if (uv__is_closing(handle) || fd_out == -1)
Packit Service 7c31a4
    return UV_EBADF;
Packit Service 7c31a4
Packit Service 7c31a4
  *fd = fd_out;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static int uv__run_pending(uv_loop_t* loop) {
Packit Service 7c31a4
  QUEUE* q;
Packit Service 7c31a4
  QUEUE pq;
Packit Service 7c31a4
  uv__io_t* w;
Packit Service 7c31a4
Packit Service 7c31a4
  if (QUEUE_EMPTY(&loop->pending_queue))
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  QUEUE_MOVE(&loop->pending_queue, &pq;;
Packit Service 7c31a4
Packit Service 7c31a4
  while (!QUEUE_EMPTY(&pq)) {
Packit Service 7c31a4
    q = QUEUE_HEAD(&pq;;
Packit Service 7c31a4
    QUEUE_REMOVE(q);
Packit Service 7c31a4
    QUEUE_INIT(q);
Packit Service 7c31a4
    w = QUEUE_DATA(q, uv__io_t, pending_queue);
Packit Service 7c31a4
    w->cb(loop, w, POLLOUT);
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return 1;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static unsigned int next_power_of_two(unsigned int val) {
Packit Service 7c31a4
  val -= 1;
Packit Service 7c31a4
  val |= val >> 1;
Packit Service 7c31a4
  val |= val >> 2;
Packit Service 7c31a4
  val |= val >> 4;
Packit Service 7c31a4
  val |= val >> 8;
Packit Service 7c31a4
  val |= val >> 16;
Packit Service 7c31a4
  val += 1;
Packit Service 7c31a4
  return val;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
static void maybe_resize(uv_loop_t* loop, unsigned int len) {
Packit Service 7c31a4
  uv__io_t** watchers;
Packit Service 7c31a4
  void* fake_watcher_list;
Packit Service 7c31a4
  void* fake_watcher_count;
Packit Service 7c31a4
  unsigned int nwatchers;
Packit Service 7c31a4
  unsigned int i;
Packit Service 7c31a4
Packit Service 7c31a4
  if (len <= loop->nwatchers)
Packit Service 7c31a4
    return;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Preserve fake watcher list and count at the end of the watchers */
Packit Service 7c31a4
  if (loop->watchers != NULL) {
Packit Service 7c31a4
    fake_watcher_list = loop->watchers[loop->nwatchers];
Packit Service 7c31a4
    fake_watcher_count = loop->watchers[loop->nwatchers + 1];
Packit Service 7c31a4
  } else {
Packit Service 7c31a4
    fake_watcher_list = NULL;
Packit Service 7c31a4
    fake_watcher_count = NULL;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  nwatchers = next_power_of_two(len + 2) - 2;
Packit Service 7c31a4
  watchers = uv__reallocf(loop->watchers,
Packit Service 7c31a4
                          (nwatchers + 2) * sizeof(loop->watchers[0]));
Packit Service 7c31a4
Packit Service 7c31a4
  if (watchers == NULL)
Packit Service 7c31a4
    abort();
Packit Service 7c31a4
  for (i = loop->nwatchers; i < nwatchers; i++)
Packit Service 7c31a4
    watchers[i] = NULL;
Packit Service 7c31a4
  watchers[nwatchers] = fake_watcher_list;
Packit Service 7c31a4
  watchers[nwatchers + 1] = fake_watcher_count;
Packit Service 7c31a4
Packit Service 7c31a4
  loop->watchers = watchers;
Packit Service 7c31a4
  loop->nwatchers = nwatchers;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
Packit Service 7c31a4
  assert(cb != NULL);
Packit Service 7c31a4
  assert(fd >= -1);
Packit Service 7c31a4
  QUEUE_INIT(&w->pending_queue);
Packit Service 7c31a4
  QUEUE_INIT(&w->watcher_queue);
Packit Service 7c31a4
  w->cb = cb;
Packit Service 7c31a4
  w->fd = fd;
Packit Service 7c31a4
  w->events = 0;
Packit Service 7c31a4
  w->pevents = 0;
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(UV_HAVE_KQUEUE)
Packit Service 7c31a4
  w->rcount = 0;
Packit Service 7c31a4
  w->wcount = 0;
Packit Service 7c31a4
#endif /* defined(UV_HAVE_KQUEUE) */
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
Packit Service 7c31a4
  assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
Packit Service 7c31a4
  assert(0 != events);
Packit Service 7c31a4
  assert(w->fd >= 0);
Packit Service 7c31a4
  assert(w->fd < INT_MAX);
Packit Service 7c31a4
Packit Service 7c31a4
  w->pevents |= events;
Packit Service 7c31a4
  maybe_resize(loop, w->fd + 1);
Packit Service 7c31a4
Packit Service 7c31a4
#if !defined(__sun)
Packit Service 7c31a4
  /* The event ports backend needs to rearm all file descriptors on each and
Packit Service 7c31a4
   * every tick of the event loop but the other backends allow us to
Packit Service 7c31a4
   * short-circuit here if the event mask is unchanged.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  if (w->events == w->pevents)
Packit Service 7c31a4
    return;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  if (QUEUE_EMPTY(&w->watcher_queue))
Packit Service 7c31a4
    QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
Packit Service 7c31a4
Packit Service 7c31a4
  if (loop->watchers[w->fd] == NULL) {
Packit Service 7c31a4
    loop->watchers[w->fd] = w;
Packit Service 7c31a4
    loop->nfds++;
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
Packit Service 7c31a4
  assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
Packit Service 7c31a4
  assert(0 != events);
Packit Service 7c31a4
Packit Service 7c31a4
  if (w->fd == -1)
Packit Service 7c31a4
    return;
Packit Service 7c31a4
Packit Service 7c31a4
  assert(w->fd >= 0);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Happens when uv__io_stop() is called on a handle that was never started. */
Packit Service 7c31a4
  if ((unsigned) w->fd >= loop->nwatchers)
Packit Service 7c31a4
    return;
Packit Service 7c31a4
Packit Service 7c31a4
  w->pevents &= ~events;
Packit Service 7c31a4
Packit Service 7c31a4
  if (w->pevents == 0) {
Packit Service 7c31a4
    QUEUE_REMOVE(&w->watcher_queue);
Packit Service 7c31a4
    QUEUE_INIT(&w->watcher_queue);
Packit Service 7c31a4
Packit Service 7c31a4
    if (loop->watchers[w->fd] != NULL) {
Packit Service 7c31a4
      assert(loop->watchers[w->fd] == w);
Packit Service 7c31a4
      assert(loop->nfds > 0);
Packit Service 7c31a4
      loop->watchers[w->fd] = NULL;
Packit Service 7c31a4
      loop->nfds--;
Packit Service 7c31a4
      w->events = 0;
Packit Service 7c31a4
    }
Packit Service 7c31a4
  }
Packit Service 7c31a4
  else if (QUEUE_EMPTY(&w->watcher_queue))
Packit Service 7c31a4
    QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
Packit Service 7c31a4
  uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
Packit Service 7c31a4
  QUEUE_REMOVE(&w->pending_queue);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Remove stale events for this file descriptor */
Packit Service 7c31a4
  if (w->fd != -1)
Packit Service 7c31a4
    uv__platform_invalidate_fd(loop, w->fd);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
Packit Service 7c31a4
  if (QUEUE_EMPTY(&w->pending_queue))
Packit Service 7c31a4
    QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__io_active(const uv__io_t* w, unsigned int events) {
Packit Service 7c31a4
  assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
Packit Service 7c31a4
  assert(0 != events);
Packit Service 7c31a4
  return 0 != (w->pevents & events);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__fd_exists(uv_loop_t* loop, int fd) {
Packit Service 7c31a4
  return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_getrusage(uv_rusage_t* rusage) {
Packit Service 7c31a4
  struct rusage usage;
Packit Service 7c31a4
Packit Service 7c31a4
  if (getrusage(RUSAGE_SELF, &usage))
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
Packit Service 7c31a4
  rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
Packit Service 7c31a4
Packit Service 7c31a4
  rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
Packit Service 7c31a4
  rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
Packit Service 7c31a4
Packit Service 7c31a4
#if !defined(__MVS__) && !defined(__HAIKU__)
Packit Service 7c31a4
  rusage->ru_maxrss = usage.ru_maxrss;
Packit Service 7c31a4
  rusage->ru_ixrss = usage.ru_ixrss;
Packit Service 7c31a4
  rusage->ru_idrss = usage.ru_idrss;
Packit Service 7c31a4
  rusage->ru_isrss = usage.ru_isrss;
Packit Service 7c31a4
  rusage->ru_minflt = usage.ru_minflt;
Packit Service 7c31a4
  rusage->ru_majflt = usage.ru_majflt;
Packit Service 7c31a4
  rusage->ru_nswap = usage.ru_nswap;
Packit Service 7c31a4
  rusage->ru_inblock = usage.ru_inblock;
Packit Service 7c31a4
  rusage->ru_oublock = usage.ru_oublock;
Packit Service 7c31a4
  rusage->ru_msgsnd = usage.ru_msgsnd;
Packit Service 7c31a4
  rusage->ru_msgrcv = usage.ru_msgrcv;
Packit Service 7c31a4
  rusage->ru_nsignals = usage.ru_nsignals;
Packit Service 7c31a4
  rusage->ru_nvcsw = usage.ru_nvcsw;
Packit Service 7c31a4
  rusage->ru_nivcsw = usage.ru_nivcsw;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__open_cloexec(const char* path, int flags) {
Packit Service 7c31a4
#if defined(O_CLOEXEC)
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
Packit Service 7c31a4
  fd = open(path, flags | O_CLOEXEC);
Packit Service 7c31a4
  if (fd == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return fd;
Packit Service 7c31a4
#else  /* O_CLOEXEC */
Packit Service 7c31a4
  int err;
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
Packit Service 7c31a4
  fd = open(path, flags);
Packit Service 7c31a4
  if (fd == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  err = uv__cloexec(fd, 1);
Packit Service 7c31a4
  if (err) {
Packit Service 7c31a4
    uv__close(fd);
Packit Service 7c31a4
    return err;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return fd;
Packit Service 7c31a4
#endif  /* O_CLOEXEC */
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__dup2_cloexec(int oldfd, int newfd) {
Packit Service 7c31a4
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  r = dup3(oldfd, newfd, O_CLOEXEC);
Packit Service 7c31a4
  if (r == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return r;
Packit Service 7c31a4
#else
Packit Service 7c31a4
  int err;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  r = dup2(oldfd, newfd);  /* Never retry. */
Packit Service 7c31a4
  if (r == -1)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  err = uv__cloexec(newfd, 1);
Packit Service 7c31a4
  if (err != 0) {
Packit Service 7c31a4
    uv__close(newfd);
Packit Service 7c31a4
    return err;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return r;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_homedir(char* buffer, size_t* size) {
Packit Service 7c31a4
  uv_passwd_t pwd;
Packit Service 7c31a4
  size_t len;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Check if the HOME environment variable is set first. The task of
Packit Service 7c31a4
     performing input validation on buffer and size is taken care of by
Packit Service 7c31a4
     uv_os_getenv(). */
Packit Service 7c31a4
  r = uv_os_getenv("HOME", buffer, size);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r != UV_ENOENT)
Packit Service 7c31a4
    return r;
Packit Service 7c31a4
Packit Service 7c31a4
  /* HOME is not set, so call uv__getpwuid_r() */
Packit Service 7c31a4
  r = uv__getpwuid_r(&pwd);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r != 0) {
Packit Service 7c31a4
    return r;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  len = strlen(pwd.homedir);
Packit Service 7c31a4
Packit Service 7c31a4
  if (len >= *size) {
Packit Service 7c31a4
    *size = len + 1;
Packit Service 7c31a4
    uv_os_free_passwd(&pwd);
Packit Service 7c31a4
    return UV_ENOBUFS;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  memcpy(buffer, pwd.homedir, len + 1);
Packit Service 7c31a4
  *size = len;
Packit Service 7c31a4
  uv_os_free_passwd(&pwd);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_tmpdir(char* buffer, size_t* size) {
Packit Service 7c31a4
  const char* buf;
Packit Service 7c31a4
  size_t len;
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == NULL || size == NULL || *size == 0)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
#define CHECK_ENV_VAR(name)                                                   \
Packit Service 7c31a4
  do {                                                                        \
Packit Service 7c31a4
    buf = getenv(name);                                                       \
Packit Service 7c31a4
    if (buf != NULL)                                                          \
Packit Service 7c31a4
      goto return_buffer;                                                     \
Packit Service 7c31a4
  }                                                                           \
Packit Service 7c31a4
  while (0)
Packit Service 7c31a4
Packit Service 7c31a4
  /* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */
Packit Service 7c31a4
  CHECK_ENV_VAR("TMPDIR");
Packit Service 7c31a4
  CHECK_ENV_VAR("TMP");
Packit Service 7c31a4
  CHECK_ENV_VAR("TEMP");
Packit Service 7c31a4
  CHECK_ENV_VAR("TEMPDIR");
Packit Service 7c31a4
Packit Service 7c31a4
#undef CHECK_ENV_VAR
Packit Service 7c31a4
Packit Service 7c31a4
  /* No temp environment variables defined */
Packit Service 7c31a4
  #if defined(__ANDROID__)
Packit Service 7c31a4
    buf = "/data/local/tmp";
Packit Service 7c31a4
  #else
Packit Service 7c31a4
    buf = "/tmp";
Packit Service 7c31a4
  #endif
Packit Service 7c31a4
Packit Service 7c31a4
return_buffer:
Packit Service 7c31a4
  len = strlen(buf);
Packit Service 7c31a4
Packit Service 7c31a4
  if (len >= *size) {
Packit Service 7c31a4
    *size = len + 1;
Packit Service 7c31a4
    return UV_ENOBUFS;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* The returned directory should not have a trailing slash. */
Packit Service 7c31a4
  if (len > 1 && buf[len - 1] == '/') {
Packit Service 7c31a4
    len--;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  memcpy(buffer, buf, len + 1);
Packit Service 7c31a4
  buffer[len] = '\0';
Packit Service 7c31a4
  *size = len;
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__getpwuid_r(uv_passwd_t* pwd) {
Packit Service 7c31a4
  struct passwd pw;
Packit Service 7c31a4
  struct passwd* result;
Packit Service 7c31a4
  char* buf;
Packit Service 7c31a4
  uid_t uid;
Packit Service 7c31a4
  size_t bufsize;
Packit Service 7c31a4
  size_t name_size;
Packit Service 7c31a4
  size_t homedir_size;
Packit Service 7c31a4
  size_t shell_size;
Packit Service 7c31a4
  long initsize;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  if (pwd == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
Packit Service 7c31a4
Packit Service 7c31a4
  if (initsize <= 0)
Packit Service 7c31a4
    bufsize = 4096;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    bufsize = (size_t) initsize;
Packit Service 7c31a4
Packit Service 7c31a4
  uid = geteuid();
Packit Service 7c31a4
  buf = NULL;
Packit Service 7c31a4
Packit Service 7c31a4
  for (;;) {
Packit Service 7c31a4
    uv__free(buf);
Packit Service 7c31a4
    buf = uv__malloc(bufsize);
Packit Service 7c31a4
Packit Service 7c31a4
    if (buf == NULL)
Packit Service 7c31a4
      return UV_ENOMEM;
Packit Service 7c31a4
Packit Service 7c31a4
    r = getpwuid_r(uid, &pw, buf, bufsize, &result);
Packit Service 7c31a4
Packit Service 7c31a4
    if (r != ERANGE)
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    bufsize *= 2;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  if (r != 0) {
Packit Service 7c31a4
    uv__free(buf);
Packit Service 7c31a4
    return -r;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  if (result == NULL) {
Packit Service 7c31a4
    uv__free(buf);
Packit Service 7c31a4
    return UV_ENOENT;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* Allocate memory for the username, shell, and home directory */
Packit Service 7c31a4
  name_size = strlen(pw.pw_name) + 1;
Packit Service 7c31a4
  homedir_size = strlen(pw.pw_dir) + 1;
Packit Service 7c31a4
  shell_size = strlen(pw.pw_shell) + 1;
Packit Service 7c31a4
  pwd->username = uv__malloc(name_size + homedir_size + shell_size);
Packit Service 7c31a4
Packit Service 7c31a4
  if (pwd->username == NULL) {
Packit Service 7c31a4
    uv__free(buf);
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* Copy the username */
Packit Service 7c31a4
  memcpy(pwd->username, pw.pw_name, name_size);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Copy the home directory */
Packit Service 7c31a4
  pwd->homedir = pwd->username + name_size;
Packit Service 7c31a4
  memcpy(pwd->homedir, pw.pw_dir, homedir_size);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Copy the shell */
Packit Service 7c31a4
  pwd->shell = pwd->homedir + homedir_size;
Packit Service 7c31a4
  memcpy(pwd->shell, pw.pw_shell, shell_size);
Packit Service 7c31a4
Packit Service 7c31a4
  /* Copy the uid and gid */
Packit Service 7c31a4
  pwd->uid = pw.pw_uid;
Packit Service 7c31a4
  pwd->gid = pw.pw_gid;
Packit Service 7c31a4
Packit Service 7c31a4
  uv__free(buf);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_os_free_passwd(uv_passwd_t* pwd) {
Packit Service 7c31a4
  if (pwd == NULL)
Packit Service 7c31a4
    return;
Packit Service 7c31a4
Packit Service 7c31a4
  /*
Packit Service 7c31a4
    The memory for name, shell, and homedir are allocated in a single
Packit Service 7c31a4
    uv__malloc() call. The base of the pointer is stored in pwd->username, so
Packit Service 7c31a4
    that is the field that needs to be freed.
Packit Service 7c31a4
  */
Packit Service 7c31a4
  uv__free(pwd->username);
Packit Service 7c31a4
  pwd->username = NULL;
Packit Service 7c31a4
  pwd->shell = NULL;
Packit Service 7c31a4
  pwd->homedir = NULL;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_get_passwd(uv_passwd_t* pwd) {
Packit Service 7c31a4
  return uv__getpwuid_r(pwd);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_translate_sys_error(int sys_errno) {
Packit Service 7c31a4
  /* If < 0 then it's already a libuv error. */
Packit Service 7c31a4
  return sys_errno <= 0 ? sys_errno : -sys_errno;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_environ(uv_env_item_t** envitems, int* count) {
Packit Service 7c31a4
  int i, j, cnt;
Packit Service 7c31a4
  uv_env_item_t* envitem;
Packit Service 7c31a4
Packit Service 7c31a4
  *envitems = NULL;
Packit Service 7c31a4
  *count = 0;
Packit Service 7c31a4
Packit Service 7c31a4
  for (i = 0; environ[i] != NULL; i++);
Packit Service 7c31a4
Packit Service 7c31a4
  *envitems = uv__calloc(i, sizeof(**envitems));
Packit Service 7c31a4
Packit Service 7c31a4
  if (*envitems == NULL)
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
Packit Service 7c31a4
  for (j = 0, cnt = 0; j < i; j++) {
Packit Service 7c31a4
    char* buf;
Packit Service 7c31a4
    char* ptr;
Packit Service 7c31a4
Packit Service 7c31a4
    if (environ[j] == NULL)
Packit Service 7c31a4
      break;
Packit Service 7c31a4
Packit Service 7c31a4
    buf = uv__strdup(environ[j]);
Packit Service 7c31a4
    if (buf == NULL)
Packit Service 7c31a4
      goto fail;
Packit Service 7c31a4
Packit Service 7c31a4
    ptr = strchr(buf, '=');
Packit Service 7c31a4
    if (ptr == NULL) {
Packit Service 7c31a4
      uv__free(buf);
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    *ptr = '\0';
Packit Service 7c31a4
Packit Service 7c31a4
    envitem = &(*envitems)[cnt];
Packit Service 7c31a4
    envitem->name = buf;
Packit Service 7c31a4
    envitem->value = ptr + 1;
Packit Service 7c31a4
Packit Service 7c31a4
    cnt++;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  *count = cnt;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
Packit Service 7c31a4
fail:
Packit Service 7c31a4
  for (i = 0; i < cnt; i++) {
Packit Service 7c31a4
    envitem = &(*envitems)[cnt];
Packit Service 7c31a4
    uv__free(envitem->name);
Packit Service 7c31a4
  }
Packit Service 7c31a4
  uv__free(*envitems);
Packit Service 7c31a4
Packit Service 7c31a4
  *envitems = NULL;
Packit Service 7c31a4
  *count = 0;
Packit Service 7c31a4
  return UV_ENOMEM;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
Packit Service 7c31a4
  char* var;
Packit Service 7c31a4
  size_t len;
Packit Service 7c31a4
Packit Service 7c31a4
  if (name == NULL || buffer == NULL || size == NULL || *size == 0)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  var = getenv(name);
Packit Service 7c31a4
Packit Service 7c31a4
  if (var == NULL)
Packit Service 7c31a4
    return UV_ENOENT;
Packit Service 7c31a4
Packit Service 7c31a4
  len = strlen(var);
Packit Service 7c31a4
Packit Service 7c31a4
  if (len >= *size) {
Packit Service 7c31a4
    *size = len + 1;
Packit Service 7c31a4
    return UV_ENOBUFS;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  memcpy(buffer, var, len + 1);
Packit Service 7c31a4
  *size = len;
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_setenv(const char* name, const char* value) {
Packit Service 7c31a4
  if (name == NULL || value == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (setenv(name, value, 1) != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_unsetenv(const char* name) {
Packit Service 7c31a4
  if (name == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (unsetenv(name) != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_gethostname(char* buffer, size_t* size) {
Packit Service 7c31a4
  /*
Packit Service 7c31a4
    On some platforms, if the input buffer is not large enough, gethostname()
Packit Service 7c31a4
    succeeds, but truncates the result. libuv can detect this and return ENOBUFS
Packit Service 7c31a4
    instead by creating a large enough buffer and comparing the hostname length
Packit Service 7c31a4
    to the size input.
Packit Service 7c31a4
  */
Packit Service 7c31a4
  char buf[UV_MAXHOSTNAMESIZE];
Packit Service 7c31a4
  size_t len;
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == NULL || size == NULL || *size == 0)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (gethostname(buf, sizeof(buf)) != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
Packit Service 7c31a4
  len = strlen(buf);
Packit Service 7c31a4
Packit Service 7c31a4
  if (len >= *size) {
Packit Service 7c31a4
    *size = len + 1;
Packit Service 7c31a4
    return UV_ENOBUFS;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  memcpy(buffer, buf, len + 1);
Packit Service 7c31a4
  *size = len;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uv_os_fd_t uv_get_osfhandle(int fd) {
Packit Service 7c31a4
  return fd;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv_open_osfhandle(uv_os_fd_t os_fd) {
Packit Service 7c31a4
  return os_fd;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
uv_pid_t uv_os_getpid(void) {
Packit Service 7c31a4
  return getpid();
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uv_pid_t uv_os_getppid(void) {
Packit Service 7c31a4
  return getppid();
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_getpriority(uv_pid_t pid, int* priority) {
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  if (priority == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  errno = 0;
Packit Service 7c31a4
  r = getpriority(PRIO_PROCESS, (int) pid);
Packit Service 7c31a4
Packit Service 7c31a4
  if (r == -1 && errno != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  *priority = r;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_setpriority(uv_pid_t pid, int priority) {
Packit Service 7c31a4
  if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (setpriority(PRIO_PROCESS, (int) pid, priority) != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_os_uname(uv_utsname_t* buffer) {
Packit Service 7c31a4
  struct utsname buf;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (uname(&buf) == -1) {
Packit Service 7c31a4
    r = UV__ERR(errno);
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
Packit Service 7c31a4
  if (r == UV_E2BIG)
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
Packit Service 7c31a4
#ifdef _AIX
Packit Service 7c31a4
  r = snprintf(buffer->release,
Packit Service 7c31a4
               sizeof(buffer->release),
Packit Service 7c31a4
               "%s.%s",
Packit Service 7c31a4
               buf.version,
Packit Service 7c31a4
               buf.release);
Packit Service 7c31a4
  if (r >= sizeof(buffer->release)) {
Packit Service 7c31a4
    r = UV_E2BIG;
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
  }
Packit Service 7c31a4
#else
Packit Service 7c31a4
  r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release));
Packit Service 7c31a4
  if (r == UV_E2BIG)
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version));
Packit Service 7c31a4
  if (r == UV_E2BIG)
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
Packit Service 7c31a4
#if defined(_AIX) || defined(__PASE__)
Packit Service 7c31a4
  r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine));
Packit Service 7c31a4
#else
Packit Service 7c31a4
  r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  if (r == UV_E2BIG)
Packit Service 7c31a4
    goto error;
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
Packit Service 7c31a4
error:
Packit Service 7c31a4
  buffer->sysname[0] = '\0';
Packit Service 7c31a4
  buffer->release[0] = '\0';
Packit Service 7c31a4
  buffer->version[0] = '\0';
Packit Service 7c31a4
  buffer->machine[0] = '\0';
Packit Service 7c31a4
  return r;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv__getsockpeername(const uv_handle_t* handle,
Packit Service 7c31a4
                        uv__peersockfunc func,
Packit Service 7c31a4
                        struct sockaddr* name,
Packit Service 7c31a4
                        int* namelen) {
Packit Service 7c31a4
  socklen_t socklen;
Packit Service 7c31a4
  uv_os_fd_t fd;
Packit Service 7c31a4
  int r;
Packit Service 7c31a4
Packit Service 7c31a4
  r = uv_fileno(handle, &fd;;
Packit Service 7c31a4
  if (r < 0)
Packit Service 7c31a4
    return r;
Packit Service 7c31a4
Packit Service 7c31a4
  /* sizeof(socklen_t) != sizeof(int) on some systems. */
Packit Service 7c31a4
  socklen = (socklen_t) *namelen;
Packit Service 7c31a4
Packit Service 7c31a4
  if (func(fd, name, &socklen))
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  *namelen = (int) socklen;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv_gettimeofday(uv_timeval64_t* tv) {
Packit Service 7c31a4
  struct timeval time;
Packit Service 7c31a4
Packit Service 7c31a4
  if (tv == NULL)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  if (gettimeofday(&time, NULL) != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  tv->tv_sec = (int64_t) time.tv_sec;
Packit Service 7c31a4
  tv->tv_usec = (int32_t) time.tv_usec;
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
void uv_sleep(unsigned int msec) {
Packit Service 7c31a4
  struct timespec timeout;
Packit Service 7c31a4
  int rc;
Packit Service 7c31a4
Packit Service 7c31a4
  timeout.tv_sec = msec / 1000;
Packit Service 7c31a4
  timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    rc = nanosleep(&timeout, &timeout);
Packit Service 7c31a4
  while (rc == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  assert(rc == 0);
Packit Service 7c31a4
}
Packit Service e2ebee
Packit Service e2ebee
int uv__search_path(const char* prog, char* buf, size_t* buflen) {
Packit Service e2ebee
  char abspath[UV__PATH_MAX];
Packit Service e2ebee
  size_t abspath_size;
Packit Service e2ebee
  char trypath[UV__PATH_MAX];
Packit Service e2ebee
  char* cloned_path;
Packit Service e2ebee
  char* path_env;
Packit Service e2ebee
  char* token;
Packit Service e2ebee
Packit Service e2ebee
  if (buf == NULL || buflen == NULL || *buflen == 0)
Packit Service e2ebee
    return UV_EINVAL;
Packit Service e2ebee
Packit Service e2ebee
  /*
Packit Service e2ebee
   * Possibilities for prog:
Packit Service e2ebee
   * i) an absolute path such as: /home/user/myprojects/nodejs/node
Packit Service e2ebee
   * ii) a relative path such as: ./node or ../myprojects/nodejs/node
Packit Service e2ebee
   * iii) a bare filename such as "node", after exporting PATH variable
Packit Service e2ebee
   *     to its location.
Packit Service e2ebee
   */
Packit Service e2ebee
Packit Service e2ebee
  /* Case i) and ii) absolute or relative paths */
Packit Service e2ebee
  if (strchr(prog, '/') != NULL) {
Packit Service e2ebee
    if (realpath(prog, abspath) != abspath)
Packit Service e2ebee
      return UV__ERR(errno);
Packit Service e2ebee
Packit Service e2ebee
    abspath_size = strlen(abspath);
Packit Service e2ebee
Packit Service e2ebee
    *buflen -= 1;
Packit Service e2ebee
    if (*buflen > abspath_size)
Packit Service e2ebee
      *buflen = abspath_size;
Packit Service e2ebee
Packit Service e2ebee
    memcpy(buf, abspath, *buflen);
Packit Service e2ebee
    buf[*buflen] = '\0';
Packit Service e2ebee
Packit Service e2ebee
    return 0;
Packit Service e2ebee
  } 
Packit Service e2ebee
Packit Service e2ebee
  /* Case iii). Search PATH environment variable */
Packit Service e2ebee
  cloned_path = NULL;
Packit Service e2ebee
  token = NULL;
Packit Service e2ebee
  path_env = getenv("PATH");
Packit Service e2ebee
Packit Service e2ebee
  if (path_env == NULL)
Packit Service e2ebee
    return UV_EINVAL;
Packit Service e2ebee
Packit Service e2ebee
  cloned_path = uv__strdup(path_env);
Packit Service e2ebee
  if (cloned_path == NULL)
Packit Service e2ebee
    return UV_ENOMEM;
Packit Service e2ebee
Packit Service e2ebee
  token = strtok(cloned_path, ":");
Packit Service e2ebee
  while (token != NULL) {
Packit Service e2ebee
    snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, prog);
Packit Service e2ebee
    if (realpath(trypath, abspath) == abspath) {
Packit Service e2ebee
      /* Check the match is executable */
Packit Service e2ebee
      if (access(abspath, X_OK) == 0) {
Packit Service e2ebee
        abspath_size = strlen(abspath);
Packit Service e2ebee
Packit Service e2ebee
        *buflen -= 1;
Packit Service e2ebee
        if (*buflen > abspath_size)
Packit Service e2ebee
          *buflen = abspath_size;
Packit Service e2ebee
Packit Service e2ebee
        memcpy(buf, abspath, *buflen);
Packit Service e2ebee
        buf[*buflen] = '\0';
Packit Service e2ebee
Packit Service e2ebee
        uv__free(cloned_path);
Packit Service e2ebee
        return 0;
Packit Service e2ebee
      }
Packit Service e2ebee
    }
Packit Service e2ebee
    token = strtok(NULL, ":");
Packit Service e2ebee
  }
Packit Service e2ebee
  uv__free(cloned_path);
Packit Service e2ebee
Packit Service e2ebee
  /* Out of tokens (path entries), and no match found */
Packit Service e2ebee
  return UV_EINVAL;
Packit Service e2ebee
}