Пример #1
0
int uv__make_pipe(int fds[2], int flags) {
#if __linux__
  int fl;

  fl = UV__O_CLOEXEC;

  if (flags & UV__F_NONBLOCK)
    fl |= UV__O_NONBLOCK;

  if (uv__pipe2(fds, fl) == 0)
    return 0;

  if (errno != ENOSYS)
    return -1;
#endif

  if (pipe(fds))
    return -1;

  uv__cloexec(fds[0], 1);
  uv__cloexec(fds[1], 1);

  if (flags & UV__F_NONBLOCK) {
    uv__nonblock(fds[0], 1);
    uv__nonblock(fds[1], 1);
  }

  return 0;
}
Пример #2
0
static int uv__make_pipe(int fds[2], int flags) {
#if HAVE_SYS_PIPE2
  int fl;

  fl = O_CLOEXEC;

  if (flags & UV__F_NONBLOCK)
    fl |= O_NONBLOCK;

  if (sys_pipe2(fds, fl) == 0)
    return 0;

  if (errno != ENOSYS)
    return -1;

  /* errno == ENOSYS so maybe the kernel headers lied about
   * the availability of pipe2(). This can happen if people
   * build libuv against newer kernel headers than the kernel
   * they actually run the software on.
   */
#endif

  if (pipe(fds))
    return -1;

  uv__cloexec(fds[0], 1);
  uv__cloexec(fds[1], 1);

  if (flags & UV__F_NONBLOCK) {
    uv__nonblock(fds[0], 1);
    uv__nonblock(fds[1], 1);
  }

  return 0;
}
Пример #3
0
int uv__make_pipe(int fds[2], int flags) {
#if defined(__linux__)
  static int no_pipe2;

  if (no_pipe2)
    goto skip;

  if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
    return 0;

  if (errno != ENOSYS)
    return -errno;

  no_pipe2 = 1;

skip:
#endif

  if (pipe(fds))
    return -errno;

  uv__cloexec(fds[0], 1);
  uv__cloexec(fds[1], 1);

  if (flags & UV__F_NONBLOCK) {
    uv__nonblock(fds[0], 1);
    uv__nonblock(fds[1], 1);
  }

  return 0;
}
Пример #4
0
static int uv__make_socketpair(int fds[2], int flags) {
#ifdef SOCK_NONBLOCK
  int fl;

  fl = SOCK_CLOEXEC;

  if (flags & UV__F_NONBLOCK)
    fl |= SOCK_NONBLOCK;

  if (socketpair(AF_UNIX, SOCK_STREAM|fl, 0, fds) == 0)
    return 0;

  if (errno != EINVAL)
    return -1;

  /* errno == EINVAL so maybe the kernel headers lied about
   * the availability of SOCK_NONBLOCK. This can happen if people
   * build libuv against newer kernel headers than the kernel
   * they actually run the software on.
   */
#endif

  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
    return -1;

  uv__cloexec(fds[0], 1);
  uv__cloexec(fds[1], 1);

  if (flags & UV__F_NONBLOCK) {
    uv__nonblock(fds[0], 1);
    uv__nonblock(fds[1], 1);
  }

  return 0;
}
Пример #5
0
int uv__make_socketpair(int fds[2], int flags) {
#if defined(__linux__)
  static int no_cloexec;

  if (no_cloexec)
    goto skip;

  if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
    return 0;

  /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
   * Anything else is a genuine error.
   */
  if (errno != EINVAL)
    return -errno;

  no_cloexec = 1;

skip:
#endif

  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
    return -errno;

  uv__cloexec(fds[0], 1);
  uv__cloexec(fds[1], 1);

  if (flags & UV__F_NONBLOCK) {
    uv__nonblock(fds[0], 1);
    uv__nonblock(fds[1], 1);
  }

  return 0;
}
Пример #6
0
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
  int sockfd;

#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
  sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);

  if (sockfd != -1)
    goto out;

  if (errno != EINVAL)
    goto out;
#endif

  sockfd = socket(domain, type, protocol);

  if (sockfd == -1)
    goto out;

  if (uv__nonblock(sockfd, 1) || uv__cloexec(sockfd, 1)) {
    close(sockfd);
    sockfd = -1;
  }

#if defined(SO_NOSIGPIPE)
  {
    int on = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
  }
#endif

out:
  return sockfd;
}
Пример #7
0
static int uv__process_open_stream(uv_stdio_container_t* container,
                                   int pipefds[2],
                                   int writable) {
  int flags;

  if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
    return 0;

  if (uv__close(pipefds[1]))
    if (errno != EINTR && errno != EINPROGRESS)
      abort();

  pipefds[1] = -1;
  uv__nonblock(pipefds[0], 1);

  if (container->data.stream->type == UV_NAMED_PIPE &&
      ((uv_pipe_t*)container->data.stream)->ipc)
    flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
  else if (writable)
    flags = UV_STREAM_WRITABLE;
  else
    flags = UV_STREAM_READABLE;

  return uv__stream_open(container->data.stream, pipefds[0], flags);
}
Пример #8
0
int uv_pipe_open(uv_pipe_t* handle, uv_os_fd_t fd) {
  int flags;
  int mode;
  int err;
  flags = 0;

  if (uv__fd_exists(handle->loop, fd))
    return UV_EEXIST;

  do
    mode = fcntl(fd, F_GETFL);
  while (mode == -1 && errno == EINTR);

  if (mode == -1)
    return UV__ERR(errno); /* according to docs, must be EBADF */

  err = uv__nonblock(fd, 1);
  if (err)
    return err;

#if defined(__APPLE__)
  err = uv__stream_try_select((uv_stream_t*) handle, &fd);
  if (err)
    return err;
#endif /* defined(__APPLE__) */

  mode &= O_ACCMODE;
  if (mode != O_WRONLY)
    flags |= UV_HANDLE_READABLE;
  if (mode != O_RDONLY)
    flags |= UV_HANDLE_WRITABLE;

  return uv__stream_open((uv_stream_t*)handle, fd, flags);
}
Пример #9
0
static int new_inotify_fd(void) {
  int err;
  int fd;

  fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
  if (fd != -1)
    return fd;

  if (errno != ENOSYS)
    return -errno;

  fd = uv__inotify_init();
  if (fd == -1)
    return -errno;

  err = uv__cloexec(fd, 1);
  if (err == 0)
    err = uv__nonblock(fd, 1);

  if (err) {
    uv__close(fd);
    return err;
  }

  return fd;
}
Пример #10
0
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
  int sockfd;

#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
  sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);

  if (sockfd != -1)
    goto out;

  if (errno != EINVAL)
    goto out;
#endif

  sockfd = socket(domain, type, protocol);

  if (sockfd == -1)
    goto out;

  if (uv__nonblock(sockfd, 1) || uv__cloexec(sockfd, 1)) {
    uv__close(sockfd);
    sockfd = -1;
  }

out:
  return sockfd;
}
Пример #11
0
int uv_device_open(uv_loop_t* loop,
                   uv_device_t* device,
                   uv_os_fd_t fd,
                   int flags) {
    int err;
    int stream_flags = 0;

    assert(device);
    if (flags != O_RDONLY && flags != O_WRONLY && flags != O_RDWR) {
        return -EINVAL;
    }
    uv__stream_init(loop, (uv_stream_t*) device, UV_DEVICE);

    if (flags & O_RDONLY) {
        stream_flags |= UV_STREAM_READABLE;
    } else if (flags & O_WRONLY) {
        stream_flags |= UV_STREAM_WRITABLE;
    } else if (flags & O_RDWR) {
        stream_flags |= UV_STREAM_READABLE | UV_STREAM_WRITABLE;
    }

    err = uv__nonblock(fd, 1);
    if (err) {
        return err;
    }

    err = uv__stream_open((uv_stream_t*) device, fd, stream_flags);
    if (err) {
        return err;
    }
    return 0;
}
Пример #12
0
int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
  int peerfd;

  assert(sockfd >= 0);

  while (1) {
#if __linux__
    peerfd = uv__accept4(sockfd, saddr, &slen, UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
    if (peerfd != -1)
      break;

    if (errno == EINTR)
      continue;

    if (errno != ENOSYS)
      break;
#endif

    if ((peerfd = accept(sockfd, saddr, &slen)) == -1) {
      if (errno == EINTR)
        continue;
      else
        break;
    }

    if (uv__cloexec(peerfd, 1) || uv__nonblock(peerfd, 1)) {
      close(peerfd);
      peerfd = -1;
    }

    break;
  }

  return peerfd;
}
Пример #13
0
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
  int err;

  if (uv__fd_exists(loop, fd))
    return UV_EEXIST;

  err = uv__io_check_fd(loop, fd);
  if (err)
    return err;

  /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL).
   * Workaround for e.g. kqueue fds not supporting ioctls.
   */
  err = uv__nonblock(fd, 1);
  if (err == UV_ENOTTY)
    if (uv__nonblock == uv__nonblock_ioctl)
      err = uv__nonblock_fcntl(fd, 1);

  if (err)
    return err;

  uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
  uv__io_init(&handle->io_watcher, uv__poll_io, fd);
  handle->poll_cb = NULL;
  return 0;
}
Пример #14
0
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
  int sockfd;
  int err;

#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
  sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
  if (sockfd != -1)
    return sockfd;

  if (errno != EINVAL)
    return -errno;
#endif

  sockfd = socket(domain, type, protocol);
  if (sockfd == -1)
    return -errno;

  err = uv__nonblock(sockfd, 1);
  if (err == 0)
    err = uv__cloexec(sockfd, 1);

  if (err) {
    uv__close(sockfd);
    return err;
  }

#if defined(SO_NOSIGPIPE)
  {
    int on = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
  }
#endif

  return sockfd;
}
Пример #15
0
int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
  int err;

  err = uv__nonblock(sock, 1);
  if (err)
    return err;

  return uv__stream_open((uv_stream_t*)handle,
                         sock,
                         UV_STREAM_READABLE | UV_STREAM_WRITABLE);
}
Пример #16
0
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
  int err;

  err = uv__nonblock(fd, 1);
  if (err)
    return err;

  uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
  uv__io_init(&handle->io_watcher, uv__poll_io, fd);
  handle->poll_cb = NULL;
  return 0;
}
Пример #17
0
int uv__accept(int sockfd) {
  int peerfd;
  int err;

  assert(sockfd >= 0);

  while (1) {
#if defined(__linux__)                          || \
    (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \
    defined(__NetBSD__)
    static int no_accept4;

    if (no_accept4)
      goto skip;

    peerfd = uv__accept4(sockfd,
                         NULL,
                         NULL,
                         UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
    if (peerfd != -1)
      return peerfd;

    if (errno == EINTR)
      continue;

    if (errno != ENOSYS)
      return UV__ERR(errno);

    no_accept4 = 1;
skip:
#endif

    peerfd = accept(sockfd, NULL, NULL);
    if (peerfd == -1) {
      if (errno == EINTR)
        continue;
      return UV__ERR(errno);
    }

    err = uv__cloexec(peerfd, 1);
    if (err == 0)
      err = uv__nonblock(peerfd, 1);

    if (err) {
      uv__close(peerfd);
      return err;
    }

    return peerfd;
  }
}
Пример #18
0
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
  int flags;
  int newfd;
  int r;

  uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);

  /* Reopen the file descriptor when it refers to a tty. This lets us put the
   * tty in non-blocking mode without affecting other processes that share it
   * with us.
   *
   * Example: `node | cat` - if we put our fd 0 in non-blocking mode, it also
   * affects fd 1 of `cat` because both file descriptors refer to the same
   * struct file in the kernel. When we reopen our fd 0, it points to a
   * different struct file, hence changing its properties doesn't affect
   * other processes.
   */
  if (isatty(fd)) {
    newfd = open("/dev/tty", O_RDWR);

    if (newfd == -1)
      return uv__set_sys_error(loop, errno);

    do
      r = dup2(newfd, fd);
    while (r == -1 && (errno == EINTR || errno == EBUSY));

    /* EINVAL means newfd == fd which could conceivably happen if another
     * thread called close(fd) between our calls to isatty() and open().
     * That's a rather unlikely event but let's handle it anyway.
     */
    if (r == -1 && errno != EINVAL) {
      close(newfd);
      return uv__set_sys_error(loop, errno);
    }

    fd = newfd;
  }

  if (readable)
    flags = UV_STREAM_READABLE;
  else
    flags = UV_STREAM_WRITABLE;

  uv__nonblock(fd, 1);
  uv__stream_open((uv_stream_t*)tty, fd, flags);
  tty->mode = 0;

  return 0;
}
Пример #19
0
Файл: core.c Проект: yemol/node
int uv__accept(int sockfd) {
  int peerfd;
  int err;

  assert(sockfd >= 0);

  while (1) {
#if defined(__linux__)
    static int no_accept4;
    no_accept4 = 1;  /* accept4 doesn't work on QNAP */
    if (no_accept4)
      goto skip;

    peerfd = uv__accept4(sockfd,
                         NULL,
                         NULL,
                         UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
    if (peerfd != -1)
      return peerfd;

    if (errno == EINTR)
      continue;

    if (errno != ENOSYS)
      return -errno;

    no_accept4 = 1;
skip:
#endif

    peerfd = accept(sockfd, NULL, NULL);
    if (peerfd == -1) {
      if (errno == EINTR)
        continue;
      return -errno;
    }

    err = uv__cloexec(peerfd, 1);
    if (err == 0)
      err = uv__nonblock(peerfd, 1);

    if (err) {
      uv__close(peerfd);
      return err;
    }

    return peerfd;
  }
}
Пример #20
0
int uv__accept(int sockfd) {
  int peerfd;

  assert(sockfd >= 0);

  while (1) {
#if defined(__linux__)
    static int no_accept4;

    if (no_accept4)
      goto skip;

    peerfd = uv__accept4(sockfd,
                         NULL,
                         NULL,
                         UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);

    if (peerfd != -1)
      break;

    if (errno == EINTR)
      continue;

    if (errno != ENOSYS)
      break;

    no_accept4 = 1;
skip:
#endif

    peerfd = accept(sockfd, NULL, NULL);

    if (peerfd == -1) {
      if (errno == EINTR)
        continue;
      else
        break;
    }

    if (uv__cloexec(peerfd, 1) || uv__nonblock(peerfd, 1)) {
      close(peerfd);
      peerfd = -1;
    }

    break;
  }

  return peerfd;
}
Пример #21
0
Файл: tty.c Проект: 2hanson/node
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
  uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);

  if (readable) {
    uv__nonblock(fd, 1);
    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE);
  } else {
    /* Note: writable tty we set to blocking mode. */
    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE);
    tty->flags |= UV_STREAM_BLOCKING;
  }

  tty->mode = 0;
  return 0;
}
Пример #22
0
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
  uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);

  if (readable) {
    uv__nonblock(fd, 1);
    uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE);
  } else {
    /* Note: writable tty we set to blocking mode. */
    uv__stream_open((uv_stream_t*)tty, fd, UV_WRITABLE);
    tty->blocking = 1;
  }

  loop->counters.tty_init++;
  tty->mode = 0;
  return 0;
}
Пример #23
0
static int new_inotify_fd(void) {
#if HAVE_INOTIFY_INIT1
  return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
#else
  int fd;

  if ((fd = inotify_init()) == -1)
    return -1;

  if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
    SAVE_ERRNO(uv__close(fd));
    fd = -1;
  }

  return fd;
#endif
}
Пример #24
0
Файл: pipe.c Проект: clibs/uv
int uv_pipe_open(uv_pipe_t* handle, uv_os_fd_t fd) {
  int err;

  err = uv__nonblock(fd, 1);
  if (err)
    return err;

#if defined(__APPLE__)
  err = uv__stream_try_select((uv_stream_t*) handle, &fd);
  if (err)
    return err;
#endif /* defined(__APPLE__) */

  return uv__stream_open((uv_stream_t*)handle,
                         fd,
                         UV_STREAM_READABLE | UV_STREAM_WRITABLE);
}
Пример #25
0
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
int uv__socket(int domain, int type, int protocol) {
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
  return socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
#else
  int sockfd;

  if ((sockfd = socket(domain, type, protocol)) == -1) {
    return -1;
  }

  if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) {
    uv__close(sockfd);
    return -1;
  }

  return sockfd;
#endif
}
Пример #26
0
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
  int err;

  /* Check for already active socket. */
  if (handle->io_watcher.fd != -1)
    return -EALREADY;  /* FIXME(bnoordhuis) Should be -EBUSY. */

  err = uv__nonblock(sock, 1);
  if (err)
    return err;

  err = uv__set_reuse(sock);
  if (err)
    return err;

  handle->io_watcher.fd = sock;
  return 0;
}
Пример #27
0
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
  int err;

  /* Check for already active socket. */
  if (handle->io_watcher.fd != -1)
    return -EBUSY;

  err = uv__nonblock(sock, 1);
  if (err)
    return err;

  err = uv__set_reuse(sock);
  if (err)
    return err;

  handle->io_watcher.fd = sock;
  return 0;
}
Пример #28
0
static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
                                   int writable) {
  int fd = fds[writable ? 1 : 0];
  int child_fd = fds[writable ? 0 : 1];
  int flags;

  /* No need to create stream */
  if (!(container->flags & UV_CREATE_PIPE) || fd < 0) {
    return 0;
  }

  assert(child_fd >= 0);
  close(child_fd);

  uv__nonblock(fd, 1);
  flags = uv__process_stdio_flags(container, writable);

  return uv__stream_open((uv_stream_t*)container->data.stream, fd, flags);
}
Пример #29
0
static int new_inotify_fd(void) {
  int fd;

  fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
  if (fd != -1)
    return fd;
  if (errno != ENOSYS)
    return -1;

  if ((fd = uv__inotify_init()) == -1)
    return -1;

  if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
    SAVE_ERRNO(close(fd));
    return -1;
  }

  return fd;
}
Пример #30
0
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
  uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);

#if defined(__APPLE__)
  if (uv__stream_try_select((uv_stream_t*) tty, &fd))
    return -1;
#endif /* defined(__APPLE__) */

  if (readable) {
    uv__nonblock(fd, 1);
    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE);
  } else {
    /* Note: writable tty we set to blocking mode. */
    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE);
    tty->flags |= UV_STREAM_BLOCKING;
  }

  tty->mode = 0;
  return 0;
}