Esempio n. 1
0
/* the actual thread entrypoint passed to pthread_create() */
static void *uv__thread_run(void *arg) {
  /* synchronously get the entrypoint and call it */
  uv_thread_shared_t *hnd = (uv_thread_shared_t *)arg;
  pthread_mutex_lock(&hnd->mtx);
  uv_thread_run thread_run = hnd->options->thread_run;
  void *thread_arg = hnd->options->thread_arg;
  /* ... any other processing depending on thread or options here ... */
  pthread_cond_signal(&hnd->cond);
  pthread_mutex_unlock(&hnd->mtx);  
  void *result = (*thread_run)(hnd, thread_arg);
  
  /* close any pipes created */
  if(hnd->stdin_fd != -1) uv__close(hnd->stdin_fd);
  if(hnd->stdout_fd != -1) uv__close(hnd->stdout_fd);
  if(hnd->stderr_fd != -1) uv__close(hnd->stderr_fd);

  /* synchronously notify exit to the client event loop */
  pthread_mutex_lock(&hnd->mtx);
  uv_thread_t *thread = hnd->thread_handle;
  if(thread) {
    /* copy these before they disappear ... */
    thread->exit_status = hnd->exit_status;
    thread->term_signal = hnd->term_signal;
    ev_async_send(thread->loop->ev, &thread->thread_watcher);
  }
  hnd->thread_id = 0;
  pthread_mutex_unlock(&hnd->mtx);

  /* if the handle had gone already, delete shared handle */
  if(!thread)
    uv__thread_shared_delete(hnd);
  
  return result;
}
Esempio n. 2
0
void uv__stream_close(uv_stream_t* handle) {
  unsigned int i;
  uv__stream_queued_fds_t* queued_fds;

  uv__io_close(handle->loop, &handle->io_watcher);
  uv_read_stop(handle);
  uv__handle_stop(handle);

  if (handle->io_watcher.fd != -1) {
    /* Don't close stdio file descriptors.  Nothing good comes from it. */
    if (handle->io_watcher.fd > STDERR_FILENO)
      uv__close(handle->io_watcher.fd);
    handle->io_watcher.fd = -1;
  }

  if (handle->accepted_fd != -1) {
    uv__close(handle->accepted_fd);
    handle->accepted_fd = -1;
  }

  /* Close all queued fds */
  if (handle->queued_fds != NULL) {
    queued_fds = (uv__stream_queued_fds_t*)handle->queued_fds;
    for (i = 0; i < queued_fds->offset; i++) {
      uv__close(queued_fds->fds[i]);
    }
    free(handle->queued_fds);
    handle->queued_fds = NULL;
  }

  assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
}
Esempio n. 3
0
void uv__platform_loop_delete(uv_loop_t* loop) {
  if (loop->fs_fd != -1) {
    uv__close(loop->fs_fd);
    loop->fs_fd = -1;
  }

  if (loop->backend_fd != -1) {
    uv__close(loop->backend_fd);
    loop->backend_fd = -1;
  }
}
Esempio n. 4
0
void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
    if (wa->io_watcher.fd == -1)
        return;

    if (wa->wfd != -1) {
        if (wa->wfd != wa->io_watcher.fd)
            uv__close(wa->wfd);
        wa->wfd = -1;
    }

    uv__io_stop(loop, &wa->io_watcher, POLLIN);
    uv__close(wa->io_watcher.fd);
    wa->io_watcher.fd = -1;
}
Esempio n. 5
0
void uv__async_stop(uv_loop_t* loop) {
  if (loop->async_io_watcher.fd == -1)
    return;

  if (loop->async_wfd != -1) {
    if (loop->async_wfd != loop->async_io_watcher.fd)
      uv__close(loop->async_wfd);
    loop->async_wfd = -1;
  }

  uv__io_stop(loop, &loop->async_io_watcher, POLLIN);
  uv__close(loop->async_io_watcher.fd);
  loop->async_io_watcher.fd = -1;
}
Esempio n. 6
0
void uv__udp_destroy(uv_udp_t* handle) {
  uv_udp_send_t* req;
  ngx_queue_t* q;

  uv__udp_run_completed(handle);

  while (!ngx_queue_empty(&handle->write_queue)) {
    q = ngx_queue_head(&handle->write_queue);
    ngx_queue_remove(q);

    req = ngx_queue_data(q, uv_udp_send_t, queue);
    if (req->send_cb) {
      /* FIXME proper error code like UV_EABORTED */
      uv__set_artificial_error(handle->loop, UV_EINTR);
      req->send_cb(req, -1);
    }
  }

  /* Now tear down the handle. */
  handle->flags = 0;
  handle->recv_cb = NULL;
  handle->alloc_cb = NULL;
  /* but _do not_ touch close_cb */

  if (handle->fd != -1) {
    uv__close(handle->fd);
    handle->fd = -1;
  }

  uv__udp_watcher_stop(handle, &handle->read_watcher);
  uv__udp_watcher_stop(handle, &handle->write_watcher);
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
int uv__open_cloexec(const char* path, int flags) {
  int err;
  int fd;

#if defined(UV__O_CLOEXEC)
  static int no_cloexec;

  if (!no_cloexec) {
    fd = open(path, flags | UV__O_CLOEXEC);
    if (fd != -1)
      return fd;

    if (errno != EINVAL)
      return -errno;

    /* O_CLOEXEC not supported. */
    no_cloexec = 1;
  }
#endif

  fd = open(path, flags);
  if (fd == -1)
    return -errno;

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

  return fd;
}
Esempio n. 10
0
File: core.c Progetto: Maxence/node
/* 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;
}
Esempio n. 11
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);
}
Esempio n. 12
0
int uv_fs_event_stop(uv_fs_event_t* handle) {
  if (!uv__is_active(handle))
    return 0;

  uv__handle_stop(handle);

#if defined(__APPLE__)
  if (uv__fsevents_close(handle))
#endif /* defined(__APPLE__) */
  {
    uv__io_close(handle->loop, &handle->event_watcher);
  }

  uv__free(handle->path);
  handle->path = NULL;

  if (handle->event_watcher.fd != -1) {
    /* When FSEvents is used, we don't use the event_watcher's fd under certain
     * confitions. (see uv_fs_event_start) */
    uv__close(handle->event_watcher.fd);
    handle->event_watcher.fd = -1;
  }

  return 0;
}
Esempio n. 13
0
File: udp.c Progetto: Muraad/harmony
int uv__udp_bind(uv_udp_t* handle,
                 const struct sockaddr* addr,
                 unsigned int addrlen,
                 unsigned int flags) {
  int err;
  int yes;
  int fd;

  /* Check for bad flags. */
  if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
    return -EINVAL;

  /* Cannot set IPv6-only mode on non-IPv6 socket. */
  if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
    return -EINVAL;

  fd = handle->io_watcher.fd;
  if (fd == -1) {
    err = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
    if (err < 0)
      return err;
    fd = err;
    handle->io_watcher.fd = fd;
  }

  if (flags & UV_UDP_REUSEADDR) {
    err = uv__set_reuse(fd);
    if (err)
      goto out;
  }

  if (flags & UV_UDP_IPV6ONLY) {
#ifdef IPV6_V6ONLY
    yes = 1;
    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
      err = -errno;
      goto out;
    }
#else
    err = -ENOTSUP;
    goto out;
#endif
  }

  if (bind(fd, addr, addrlen)) {
    err = -errno;
    goto out;
  }

  if (addr->sa_family == AF_INET6)
    handle->flags |= UV_HANDLE_IPV6;

  return 0;

out:
  uv__close(handle->io_watcher.fd);
  handle->io_watcher.fd = -1;
  return err;
}
Esempio n. 14
0
void uv__fs_event_destroy(uv_fs_event_t* handle) {
  ev_ref(handle->loop->ev);
  ev_io_stop(handle->loop->ev, &handle->read_watcher);
  uv__close(handle->fd);
  handle->fd = -1;
  free(handle->filename);
  handle->filename = NULL;
}
Esempio n. 15
0
int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
    int pipefd[2];
    int err;

    if (wa->io_watcher.fd != -1)
        return 0;

    err = uv__async_eventfd();
    if (err >= 0) {
        pipefd[0] = err;
        pipefd[1] = -1;
    }
    else if (err == -ENOSYS) {
        err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
#if defined(__linux__)
        /* Save a file descriptor by opening one of the pipe descriptors as
         * read/write through the procfs.  That file descriptor can then
         * function as both ends of the pipe.
         */
        if (err == 0) {
            char buf[32];
            int fd;

            snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
            fd = uv__open_cloexec(buf, O_RDWR);
            if (fd >= 0) {
                uv__close(pipefd[0]);
                uv__close(pipefd[1]);
                pipefd[0] = fd;
                pipefd[1] = fd;
            }
        }
#endif
    }

    if (err < 0)
        return err;

    uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
    uv__io_start(loop, &wa->io_watcher, POLLIN);
    wa->wfd = pipefd[1];
    wa->cb = cb;

    return 0;
}
Esempio n. 16
0
File: udp.c Progetto: Muraad/harmony
void uv__udp_close(uv_udp_t* handle) {
  uv__io_close(handle->loop, &handle->io_watcher);
  uv__handle_stop(handle);

  if (handle->io_watcher.fd != -1) {
    uv__close(handle->io_watcher.fd);
    handle->io_watcher.fd = -1;
  }
}
Esempio n. 17
0
int uv_resident_set_memory(size_t* rss) {
  char buf[1024];
  const char* s;
  ssize_t n;
  long val;
  int fd;
  int i;

  do
    fd = open("/proc/self/stat", O_RDONLY);
  while (fd == -1 && errno == EINTR);

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

  do
    n = read(fd, buf, sizeof(buf) - 1);
  while (n == -1 && errno == EINTR);

  uv__close(fd);
  if (n == -1)
    return -errno;
  buf[n] = '\0';

  s = strchr(buf, ' ');
  if (s == NULL)
    goto err;

  s += 1;
  if (*s != '(')
    goto err;

  s = strchr(s, ')');
  if (s == NULL)
    goto err;

  for (i = 1; i <= 22; i++) {
    s = strchr(s + 1, ' ');
    if (s == NULL)
      goto err;
  }

  errno = 0;
  val = strtol(s, NULL, 10);
  if (errno != 0)
    goto err;
  if (val < 0)
    goto err;

  *rss = val * getpagesize();
  return 0;

err:
  return -EINVAL;
}
Esempio n. 18
0
File: pipe.c Progetto: clibs/uv
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
  struct sockaddr_un saddr;
  const char* pipe_fname;
  int sockfd;
  int err;
  size_t name_len;

  pipe_fname = NULL;
  sockfd = -1;
  name_len = strlen(name);

  if (name_len > sizeof(saddr.sun_path) - 1)
    return -ENAMETOOLONG;

  /* Already bound? */
  if (uv__stream_fd(handle) >= 0)
    return -EINVAL;

  /* Make a copy of the file name, it outlives this function's scope. */
  pipe_fname = uv__strdup(name);
  if (pipe_fname == NULL)
    return -ENOMEM;

  /* We've got a copy, don't touch the original any more. */
  name = NULL;

  err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
  if (err < 0)
    goto err_socket;
  sockfd = err;

  memset(&saddr, 0, sizeof saddr);
  memcpy(saddr.sun_path, pipe_fname, name_len);
  saddr.sun_family = AF_UNIX;

  if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
    err = -errno;
    /* Convert ENOENT to EACCES for compatibility with Windows. */
    if (err == -ENOENT)
      err = -EACCES;

    uv__close(sockfd);
    goto err_socket;
  }

  /* Success. */
  handle->flags |= UV_HANDLE_BOUND;
  handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
  handle->io_watcher.fd = sockfd;
  return 0;

err_socket:
  uv__free((void*)pipe_fname);
  return err;
}
Esempio n. 19
0
File: core.c Progetto: gamemake/sail
int uv__dup2_cloexec(int oldfd, int newfd) {
  int r;
#if defined(__FreeBSD__) && __FreeBSD__ >= 10
  do
    r = dup3(oldfd, newfd, O_CLOEXEC);
  while (r == -1 && errno == EINTR);
  if (r == -1)
    return -errno;
  return r;
#elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
  do
    r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
  while (r == -1 && errno == EINTR);
  if (r != -1)
    return r;
  if (errno != EINVAL)
    return -errno;
  /* Fall through. */
#elif defined(__linux__)
  static int no_dup3;
  if (!no_dup3) {
    do
      r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC);
    while (r == -1 && (errno == EINTR || errno == EBUSY));
    if (r != -1)
      return r;
    if (errno != ENOSYS)
      return -errno;
    /* Fall through. */
    no_dup3 = 1;
  }
#endif
  {
    int err;
    do
      r = dup2(oldfd, newfd);
#if defined(__linux__)
    while (r == -1 && (errno == EINTR || errno == EBUSY));
#else
    while (r == -1 && errno == EINTR);
#endif

    if (r == -1)
      return -errno;

    err = uv__cloexec(newfd, 1);
    if (err) {
      uv__close(newfd);
      return err;
    }

    return r;
  }
}
Esempio n. 20
0
File: core.c Progetto: Maxence/node
/* This function is not execve-safe, there is a race window
 * between the call to dup() and fcntl(FD_CLOEXEC).
 */
int uv__dup(int fd) {
  fd = dup(fd);

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

  if (uv__cloexec(fd, 1)) {
    SAVE_ERRNO(uv__close(fd));
    return -1;
  }

  return fd;
}
Esempio n. 21
0
File: core.c Progetto: Kitware/CMake
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;
  }
}
Esempio n. 22
0
/* get a file pointer to a file in read-only and close-on-exec mode */
FILE* uv__open_file(const char* path) {
  int fd;
  FILE* fp;

  fd = uv__open_cloexec(path, O_RDONLY);
  if (fd < 0)
    return NULL;

   fp = fdopen(fd, "r");
   if (fp == NULL)
     uv__close(fd);

   return fp;
}
Esempio n. 23
0
void uv__loop_close(uv_loop_t* loop) {
  uv__signal_loop_cleanup(loop);
  uv__platform_loop_delete(loop);
  uv__async_stop(loop);

  if (loop->emfile_fd != -1) {
    uv__close(loop->emfile_fd);
    loop->emfile_fd = -1;
  }

  if (loop->backend_fd != -1) {
    uv__close(loop->backend_fd);
    loop->backend_fd = -1;
  }

  uv_mutex_lock(&loop->wq_mutex);
  assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
  assert(!uv__has_active_reqs(loop));
  uv_mutex_unlock(&loop->wq_mutex);
  uv_mutex_destroy(&loop->wq_mutex);

  /*
   * Note that all thread pool stuff is finished at this point and
   * it is safe to just destroy rw lock
   */
  uv_rwlock_destroy(&loop->cloexec_lock);

#if 0
  assert(QUEUE_EMPTY(&loop->pending_queue));
  assert(QUEUE_EMPTY(&loop->watcher_queue));
  assert(loop->nfds == 0);
#endif

  uv__free(loop->watchers);
  loop->watchers = NULL;
  loop->nwatchers = 0;
}
Esempio n. 24
0
File: core.c Progetto: 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;
  }
}
Esempio n. 25
0
static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
  struct sockaddr_storage saddr;
  socklen_t slen;
  int sockfd;
  int err;

  err = uv__socket(domain, SOCK_STREAM, 0);
  if (err < 0)
    return err;
  sockfd = err;

  err = uv__stream_open((uv_stream_t*) handle, sockfd, flags);
  if (err) {
    uv__close(sockfd);
    return err;
  }

  if (flags & UV_HANDLE_BOUND) {
    /* Bind this new socket to an arbitrary port */
    slen = sizeof(saddr);
    memset(&saddr, 0, sizeof(saddr));
    err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen);
    if (err) {
      uv__close(sockfd);
      return err;
    }

    err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen);
    if (err) {
      uv__close(sockfd);
      return err;
    }
  }

  return 0;
}
Esempio n. 26
0
int uv_fs_event_start(uv_fs_event_t* handle,
                      uv_fs_event_cb cb,
                      const char* path,
                      unsigned int flags) {
#if defined(__APPLE__)
  struct stat statbuf;
#endif /* defined(__APPLE__) */
  int fd;

  if (uv__is_active(handle))
    return -EINVAL;

  /* TODO open asynchronously - but how do we report back errors? */
  fd = open(path, O_RDONLY);
  if (fd == -1)
    return -errno;

  uv__handle_start(handle);
  uv__io_init(&handle->event_watcher, uv__fs_event, fd);
  handle->path = uv__strdup(path);
  handle->cb = cb;

#if defined(__APPLE__)
  /* Nullify field to perform checks later */
  handle->cf_cb = NULL;
  handle->realpath = NULL;
  handle->realpath_len = 0;
  handle->cf_flags = flags;

  if (fstat(fd, &statbuf))
    goto fallback;
  /* FSEvents works only with directories */
  if (!(statbuf.st_mode & S_IFDIR))
    goto fallback;

  /* The fallback fd is no longer needed */
  uv__close(fd);
  handle->event_watcher.fd = -1;

  return uv__fsevents_init(handle);

fallback:
#endif /* defined(__APPLE__) */

  uv__io_start(handle->loop, &handle->event_watcher, POLLIN);

  return 0;
}
Esempio n. 27
0
int uv_fs_event_init(uv_loop_t* loop,
                     uv_fs_event_t* handle,
                     const char* filename,
                     uv_fs_event_cb cb,
                     int flags) {
  int events;
  int fd;

  loop->counters.fs_event_init++;

  /* We don't support any flags yet. */
  assert(!flags);

  /*
   * TODO share a single inotify fd across the event loop?
   * We'll run into fs.inotify.max_user_instances if we
   * keep creating new inotify fds.
   */
  if ((fd = new_inotify_fd()) == -1) {
    uv__set_sys_error(loop, errno);
    return -1;
  }

  events = IN_ATTRIB
         | IN_CREATE
         | IN_MODIFY
         | IN_DELETE
         | IN_DELETE_SELF
         | IN_MOVED_FROM
         | IN_MOVED_TO;

  if (inotify_add_watch(fd, filename, events) == -1) {
    uv__set_sys_error(loop, errno);
    uv__close(fd);
    return -1;
  }

  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
  handle->filename = strdup(filename); /* this should go! */
  handle->cb = cb;
  handle->fd = fd;

  ev_io_init(&handle->read_watcher, uv__inotify_read, fd, EV_READ);
  ev_io_start(loop->ev, &handle->read_watcher);
  ev_unref(loop->ev);

  return 0;
}
Esempio n. 28
0
int uv__io_fork(uv_loop_t* loop) {
  int err;
  void* old_watchers;

  old_watchers = loop->inotify_watchers;

  uv__close(loop->backend_fd);
  loop->backend_fd = -1;
  uv__platform_loop_delete(loop);

  err = uv__platform_loop_init(loop);
  if (err)
    return err;

  return uv__inotify_fork(loop, old_watchers);
}
Esempio n. 29
0
/* This function is not execve-safe, there is a race window
 * between the call to dup() and fcntl(FD_CLOEXEC).
 */
int uv__dup(int fd) {
  int err;

  fd = dup(fd);

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

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

  return fd;
}
Esempio n. 30
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
}