Пример #1
0
Файл: pipe.c Проект: Cahya/node
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
  int saved_errno;
  int status;

  saved_errno = errno;
  status = -1;

  if (handle->fd == -1) {
    uv_err_new_artificial(handle->loop, UV_EINVAL);
    goto out;
  }
  assert(handle->fd >= 0);

  if ((status = listen(handle->fd, backlog)) == -1) {
    uv_err_new(handle->loop, errno);
  } else {
    handle->connection_cb = cb;
    ev_io_init(&handle->read_watcher, uv__pipe_accept, handle->fd, EV_READ);
    ev_io_start(handle->loop->ev, &handle->read_watcher);
  }

out:
  errno = saved_errno;
  return status;
}
Пример #2
0
/* TODO: share this with windows? */
int uv_ares_init_options(ares_channel *channelptr,
                         struct ares_options *options,
                         int optmask) {
  int rc;

  /* only allow single init at a time */
  if (ares_data.channel != NULL) {
    uv_err_new_artificial(NULL, UV_EALREADY);
    return -1;
  }

  /* set our callback as an option */
  options->sock_state_cb = uv__ares_sockstate_cb;
  options->sock_state_cb_data = &ares_data;
  optmask |= ARES_OPT_SOCK_STATE_CB;

  /* We do the call to ares_init_option for caller. */
  rc = ares_init_options(channelptr, options, optmask);

  /* if success, save channel */
  if (rc == ARES_SUCCESS) {
    ares_data.channel = *channelptr;
  }

  /*
   * Initialize the timeout timer. The timer won't be started until the
   * first socket is opened.
   */
  ev_init(&ares_data.timer, uv__ares_timeout);
  ares_data.timer.repeat = 1.0;

  return rc;
}
Пример #3
0
static void uv__read(uv_stream_t* stream) {
  uv_buf_t buf;
  ssize_t nread;
  struct ev_loop* ev = stream->loop->ev;

  /* XXX: Maybe instead of having UV_READING we just test if
   * tcp->read_cb is NULL or not?
   */
  while (stream->read_cb && ((uv_handle_t*)stream)->flags & UV_READING) {
    assert(stream->alloc_cb);
    buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024);

    assert(buf.len > 0);
    assert(buf.base);
    assert(stream->fd >= 0);

    do {
      nread = read(stream->fd, buf.base, buf.len);
    }
    while (nread < 0 && errno == EINTR);

    if (nread < 0) {
      /* Error */
      if (errno == EAGAIN) {
        /* Wait for the next one. */
        if (stream->flags & UV_READING) {
          ev_io_start(ev, &stream->read_watcher);
        }
        uv_err_new(stream->loop, EAGAIN);
        stream->read_cb(stream, 0, buf);
        return;
      } else {
        /* Error. User should call uv_close(). */
        uv_err_new(stream->loop, errno);
        stream->read_cb(stream, -1, buf);
        assert(!ev_is_active(&stream->read_watcher));
        return;
      }
    } else if (nread == 0) {
      /* EOF */
      uv_err_new_artificial(stream->loop, UV_EOF);
      ev_io_stop(ev, &stream->read_watcher);
      stream->read_cb(stream, -1, buf);
      return;
    } else {
      /* Successful read */
      stream->read_cb(stream, nread, buf);
    }
  }
}
Пример #4
0
void uv__read(uv_handle_t* handle) {
    /* XXX: Maybe instead of having UV_READING we just test if
     * handle->read_cb is NULL or not?
     */
    while (handle->read_cb && uv_flag_is_set(handle, UV_READING)) {
        assert(alloc_cb);
        uv_buf_t buf = alloc_cb(handle, 64 * 1024);

        assert(buf.len > 0);
        assert(buf.base);

        struct iovec* iov = (struct iovec*) &buf;

        ssize_t nread = readv(handle->fd, iov, 1);

        if (nread < 0) {
            /* Error */
            if (errno == EAGAIN) {
                /* Wait for the next one. */
                if (uv_flag_is_set(handle, UV_READING)) {
                    ev_io_start(EV_DEFAULT_UC_ &handle->read_watcher);
                }
                uv_err_new(handle, EAGAIN);
                handle->read_cb(handle, 0, buf);
                return;
            } else {
                uv_err_new(handle, errno);
                uv_close(handle);
                handle->read_cb(handle, -1, buf);
                assert(!ev_is_active(&handle->read_watcher));
                return;
            }
        } else if (nread == 0) {
            /* EOF */
            uv_err_new_artificial(handle, UV_EOF);
            ev_io_stop(EV_DEFAULT_UC_ &handle->read_watcher);
            handle->read_cb(handle, -1, buf);

            if (uv_flag_is_set(handle, UV_SHUT)) {
                uv_close(handle);
            }
            return;
        } else {
            /* Successful read */
            handle->read_cb(handle, nread, buf);
        }
    }
}
Пример #5
0
void uv__read(uv_tcp_t* tcp) {
  uv_buf_t buf;
  struct iovec* iov;
  ssize_t nread;

  /* XXX: Maybe instead of having UV_READING we just test if
   * tcp->read_cb is NULL or not?
   */
  while (tcp->read_cb && uv_flag_is_set((uv_handle_t*)tcp, UV_READING)) {
    assert(tcp->alloc_cb);
    buf = tcp->alloc_cb((uv_stream_t*)tcp, 64 * 1024);

    assert(buf.len > 0);
    assert(buf.base);

    iov = (struct iovec*) &buf;

    nread = read(tcp->fd, buf.base, buf.len);

    if (nread < 0) {
      /* Error */
      if (errno == EAGAIN) {
        /* Wait for the next one. */
        if (uv_flag_is_set((uv_handle_t*)tcp, UV_READING)) {
          ev_io_start(EV_DEFAULT_UC_ &tcp->read_watcher);
        }
        uv_err_new((uv_handle_t*)tcp, EAGAIN);
        tcp->read_cb((uv_stream_t*)tcp, 0, buf);
        return;
      } else {
        /* Error. User should call uv_close(). */
        uv_err_new((uv_handle_t*)tcp, errno);
        tcp->read_cb((uv_stream_t*)tcp, -1, buf);
        assert(!ev_is_active(&tcp->read_watcher));
        return;
      }
    } else if (nread == 0) {
      /* EOF */
      uv_err_new_artificial((uv_handle_t*)tcp, UV_EOF);
      ev_io_stop(EV_DEFAULT_UC_ &tcp->read_watcher);
      tcp->read_cb((uv_stream_t*)tcp, -1, buf);
      return;
    } else {
      /* Successful read */
      tcp->read_cb((uv_stream_t*)tcp, nread, buf);
    }
  }
}
Пример #6
0
Файл: core.c Проект: Cahya/node
/* stub implementation of uv_getaddrinfo */
int uv_getaddrinfo(uv_loop_t* loop,
                   uv_getaddrinfo_t* handle,
                   uv_getaddrinfo_cb cb,
                   const char* hostname,
                   const char* service,
                   const struct addrinfo* hints) {
    eio_req* req;
    uv_eio_init(loop);

    if (handle == NULL || cb == NULL ||
            (hostname == NULL && service == NULL)) {
        uv_err_new_artificial(loop, UV_EINVAL);
        return -1;
    }

    uv__req_init((uv_req_t*)handle);
    handle->type = UV_GETADDRINFO;
    handle->loop = loop;
    handle->cb = cb;

    /* TODO don't alloc so much. */

    if (hints) {
        handle->hints = malloc(sizeof(struct addrinfo));
        memcpy(&handle->hints, hints, sizeof(struct addrinfo));
    }

    /* TODO security! check lengths, check return values. */

    handle->hostname = hostname ? strdup(hostname) : NULL;
    handle->service = service ? strdup(service) : NULL;
    handle->res = NULL;
    handle->retcode = 0;

    /* TODO check handle->hostname == NULL */
    /* TODO check handle->service == NULL */

    uv_ref(loop);

    req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
                     uv_getaddrinfo_done, handle);
    assert(req);
    assert(req->data == handle);

    return 0;
}
Пример #7
0
Файл: pipe.c Проект: Cahya/node
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
  struct sockaddr_un sun;
  const char* pipe_fname;
  int saved_errno;
  int sockfd;
  int status;
  int bound;

  saved_errno = errno;
  pipe_fname = NULL;
  sockfd = -1;
  status = -1;
  bound = 0;

  /* Already bound? */
  if (handle->fd >= 0) {
    uv_err_new_artificial(handle->loop, UV_EINVAL);
    goto out;
  }

  /* Make a copy of the file name, it outlives this function's scope. */
  if ((pipe_fname = strdup(name)) == NULL) {
    uv_err_new(handle->loop, ENOMEM);
    goto out;
  }

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

  if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    uv_err_new(handle->loop, errno);
    goto out;
  }

  memset(&sun, 0, sizeof sun);
  uv__strlcpy(sun.sun_path, pipe_fname, sizeof(sun.sun_path));
  sun.sun_family = AF_UNIX;

  if (bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
    /* On EADDRINUSE:
     *
     * We hold the file lock so there is no other process listening
     * on the socket. Ergo, it's stale - remove it.
     *
     * This assumes that the other process uses locking too
     * but that's a good enough assumption for now.
     */
    if (errno != EADDRINUSE
        || unlink(pipe_fname) == -1
        || bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
      /* Convert ENOENT to EACCES for compatibility with Windows. */
      uv_err_new(handle->loop, (errno == ENOENT) ? EACCES : errno);
      goto out;
    }
  }
  bound = 1;

  /* Success. */
  handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
  handle->fd = sockfd;
  status = 0;

out:
  /* Clean up on error. */
  if (status) {
    if (bound) {
      /* unlink() before close() to avoid races. */
      assert(pipe_fname != NULL);
      unlink(pipe_fname);
    }
    uv__close(sockfd);

    free((void*)pipe_fname);
  }

  errno = saved_errno;
  return status;
}