Esempio n. 1
0
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
  uv_fs_req_init(loop, req, UV_FS_FSTAT, NULL, cb);

  if (cb) {
    /* async */
    uv_ref(loop);
    req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req);

    if (!req->eio) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

  } else {
    /* sync */
    req->result = fstat(file, &req->statbuf);

    if (req->result < 0) {
      uv_err_new(loop, errno);
      return -1;
    }

    req->ptr = &req->statbuf;
  }

  return 0;
}
Esempio n. 2
0
int uv_tcp_connect6(uv_connect_t* req,
                    uv_tcp_t* handle,
                    struct sockaddr_in6 address,
                    uv_connect_cb cb) {
  int saved_errno;
  int status;

  saved_errno = errno;
  status = -1;

  if (handle->type != UV_TCP) {
    uv_err_new(handle->loop, EINVAL);
    goto out;
  }

  if (address.sin6_family != AF_INET6) {
    uv_err_new(handle->loop, EINVAL);
    goto out;
  }

  status = uv__connect(req,
                       (uv_stream_t*)handle,
                       (struct sockaddr*)&address,
                       sizeof address,
                       cb);

out:
  errno = saved_errno;
  return status;
}
Esempio n. 3
0
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
    size_t length, off_t offset, uv_fs_cb cb) {
  uv_fs_req_init(loop, req, UV_FS_WRITE, NULL, cb);

  if (cb) {
    /* async */
    uv_ref(loop);
    req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
        uv__fs_after, req);
    if (!req->eio) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

  } else {
    /* sync */
    req->result = offset < 0 ?
        write(file, buf, length) :
        pwrite(file, buf, length, offset);

    if (req->result < 0) {
      uv_err_new(loop, errno);
      return -1;
    }
  }

  return 0;
}
Esempio n. 4
0
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
  int r;

  assert(tcp->fd >= 0);

  if (tcp->delayed_error) {
    uv_err_new((uv_handle_t*)tcp, tcp->delayed_error);
    return -1;
  }

  r = listen(tcp->fd, backlog);
  if (r < 0) {
    uv_err_new((uv_handle_t*)tcp, errno);
    return -1;
  }

  tcp->connection_cb = cb;

  /* Start listening for connections. */
  ev_io_set(&tcp->read_watcher, tcp->fd, EV_READ);
  ev_set_cb(&tcp->read_watcher, uv__server_io);
  ev_io_start(EV_DEFAULT_ &tcp->read_watcher);

  return 0;
}
Esempio n. 5
0
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
    int mode, uv_fs_cb cb) {
  uv_fs_req_init(loop, req, UV_FS_OPEN, path, cb);

  if (cb) {
    /* async */
    uv_ref(loop);
    req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
    if (!req->eio) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

  } else {
    /* sync */
    req->result = open(path, flags, mode);
    if (req->result < 0) {
      uv_err_new(loop, errno);
      return -1;
    }

    uv__cloexec(req->result, 1);
  }

  return 0;
}
Esempio n. 6
0
static void uv__drain(uv_tcp_t* tcp) {
  uv_shutdown_t* req;

  assert(!uv_write_queue_head(tcp));
  assert(tcp->write_queue_size == 0);

  ev_io_stop(EV_DEFAULT_ &tcp->write_watcher);

  /* Shutdown? */
  if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUTTING) &&
      !uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING) &&
      !uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT)) {
    assert(tcp->shutdown_req);

    req = tcp->shutdown_req;

    if (shutdown(tcp->fd, SHUT_WR)) {
      /* Error. Report it. User should call uv_close(). */
      uv_err_new((uv_handle_t*)tcp, errno);
      if (req->cb) {
        req->cb(req, -1);
      }
    } else {
      uv_err_new((uv_handle_t*)tcp, 0);
      uv_flag_set((uv_handle_t*)tcp, UV_SHUT);
      if (req->cb) {
        req->cb(req, 0);
      }
    }
  }
}
Esempio n. 7
0
static void uv__drain(uv_handle_t* handle) {
    assert(!uv_write_queue_head(handle));
    assert(handle->write_queue_size == 0);

    ev_io_stop(EV_DEFAULT_ &handle->write_watcher);

    /* Shutdown? */
    if (uv_flag_is_set(handle, UV_SHUTTING) &&
            !uv_flag_is_set(handle, UV_CLOSING) &&
            !uv_flag_is_set(handle, UV_SHUT)) {
        assert(handle->shutdown_req);

        uv_req_t* req = handle->shutdown_req;
        uv_shutdown_cb cb = req->cb;

        if (shutdown(handle->fd, SHUT_WR)) {
            /* Error. Nothing we can do, close the handle. */
            uv_err_new(handle, errno);
            uv_close(handle);
            if (cb) cb(req, -1);
        } else {
            uv_err_new(handle, 0);
            uv_flag_set(handle, UV_SHUT);
            if (cb) cb(req, 0);
        }
    }
}
Esempio n. 8
0
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
    int* namelen) {
  socklen_t socklen;
  int saved_errno;
  int rv = 0;

  /* Don't clobber errno. */
  saved_errno = errno;

  if (handle->delayed_error) {
    uv_err_new(handle->loop, handle->delayed_error);
    rv = -1;
    goto out;
  }

  if (handle->fd < 0) {
    uv_err_new(handle->loop, EINVAL);
    rv = -1;
    goto out;
  }

  /* sizeof(socklen_t) != sizeof(int) on some systems. */
  socklen = (socklen_t)*namelen;

  if (getpeername(handle->fd, name, &socklen) == -1) {
    uv_err_new(handle->loop, errno);
    rv = -1;
  } else {
    *namelen = (int)socklen;
  }

out:
  errno = saved_errno;
  return rv;
}
Esempio n. 9
0
static void uv__drain(uv_stream_t* stream) {
  uv_shutdown_t* req;

  assert(!uv_write_queue_head(stream));
  assert(stream->write_queue_size == 0);

  ev_io_stop(stream->loop->ev, &stream->write_watcher);

  /* Shutdown? */
  if ((stream->flags & UV_SHUTTING) &&
      !(stream->flags & UV_CLOSING) &&
      !(stream->flags & UV_SHUT)) {
    assert(stream->shutdown_req);

    req = stream->shutdown_req;

    if (shutdown(stream->fd, SHUT_WR)) {
      /* Error. Report it. User should call uv_close(). */
      uv_err_new(stream->loop, errno);
      if (req->cb) {
        req->cb(req, -1);
      }
    } else {
      uv_err_new(stream->loop, 0);
      ((uv_handle_t*) stream)->flags |= UV_SHUT;
      if (req->cb) {
        req->cb(req, 0);
      }
    }
  }
}
Esempio n. 10
0
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
    uv_fs_cb cb) {
  int r;
  struct dirent* entry;
  size_t size = 0;
  size_t d_namlen = 0;

  uv_fs_req_init(loop, req, UV_FS_READDIR, path, cb);

  if (cb) {
    /* async */
    uv_ref(loop);
    req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req);
    if (!req->eio) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

  } else {
    /* sync */
    DIR* dir = opendir(path);
    if (!dir) {
      uv_err_new(loop, errno);
      req->result = -1;
      return -1;
    }

    /* req->result stores number of entries */
    req->result = 0;

    while ((entry = readdir(dir))) {
      d_namlen = strlen(entry->d_name);

      /* Skip . and .. */
      if ((d_namlen == 1 && entry->d_name[0] == '.') ||
          (d_namlen == 2 && entry->d_name[0] == '.' &&
           entry->d_name[1] == '.')) {
        continue;
      }

      req->ptr = realloc(req->ptr, size + d_namlen + 1);
      /* TODO check ENOMEM */
      memcpy((char*)req->ptr + size, entry->d_name, d_namlen);
      size += d_namlen;
      ((char*)req->ptr)[size] = '\0';
      size++;
      req->result++;
    }

    r = closedir(dir);
    if (r) {
      uv_err_new(loop, errno);
      req->result = -1;
      return -1;
    }
  }

  return 0;
}
Esempio n. 11
0
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
    uv_fs_cb cb) {
  ssize_t size;
  int status;
  char* buf;

  status = -1;

  uv_fs_req_init(loop, req, UV_FS_READLINK, path, cb);

  if (cb) {
    if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req))) {
      uv_ref(loop);
      return 0;
    } else {
      uv_err_new(loop, ENOMEM);
      return -1;
    }
  } else {
    /* pathconf(_PC_PATH_MAX) may return -1 to signify that path
     * lengths have no upper limit or aren't suitable for malloc'ing.
     */
    if ((size = pathconf(path, _PC_PATH_MAX)) == -1) {
#if defined(PATH_MAX)
      size = PATH_MAX;
#else
      size = 4096;
#endif
    }

    if ((buf = malloc(size + 1)) == NULL) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

    if ((size = readlink(path, buf, size)) == -1) {
      req->errorno = errno;
      req->result = -1;
      free(buf);
    } else {
      /* Cannot conceivably fail since it shrinks the buffer. */
      buf = realloc(buf, size + 1);
      buf[size] = '\0';
      req->result = 0;
      req->ptr = buf;
    }

    return 0;
  }

  assert(0 && "unreachable");
}
Esempio n. 12
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);
    }
  }
}
Esempio n. 13
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);
        }
    }
}
Esempio n. 14
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);
    }
  }
}
Esempio n. 15
0
int uv_bind(uv_handle_t* handle, struct sockaddr* addr) {
    int addrsize;
    int domain;
    int r;

    if (handle->fd <= 0) {
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd < 0) {
            uv_err_new(handle, errno);
            return -1;
        }

        if (uv_tcp_open(handle, fd)) {
            close(fd);
            return -2;
        }
    }

    assert(handle->fd >= 0);

    if (addr->sa_family == AF_INET) {
        addrsize = sizeof(struct sockaddr_in);
        domain = AF_INET;
    } else if (addr->sa_family == AF_INET6) {
        addrsize = sizeof(struct sockaddr_in6);
        domain = AF_INET6;
    } else {
        uv_err_new(handle, EFAULT);
        return -1;
    }

    r = bind(handle->fd, addr, addrsize);
    handle->delayed_error = 0;

    if (r) {
        switch (errno) {
        case EADDRINUSE:
            handle->delayed_error = errno;
            return 0;

        default:
            uv_err_new(handle, errno);
            return -1;
        }
    }

    return 0;
}
Esempio n. 16
0
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
  assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) &&
         "uv_shutdown (unix) only supports uv_handle_t right now");
  assert(stream->fd >= 0);

  if (!(stream->flags & UV_WRITABLE) ||
      stream->flags & UV_SHUT ||
      stream->flags & UV_CLOSED ||
      stream->flags & UV_CLOSING) {
    uv_err_new(stream->loop, EINVAL);
    return -1;
  }

  /* Initialize request */
  uv__req_init((uv_req_t*)req);
  req->handle = stream;
  req->cb = cb;

  stream->shutdown_req = req;
  req->type = UV_SHUTDOWN;

  ((uv_handle_t*)stream)->flags |= UV_SHUTTING;


  ev_io_start(stream->loop->ev, &stream->write_watcher);

  return 0;
}
Esempio n. 17
0
int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
  socklen_t yes;

  assert(fd >= 0);
  stream->fd = fd;

  ((uv_handle_t*)stream)->flags |= flags;

  /* Reuse the port address if applicable. */
  yes = 1;
  if (stream->type == UV_TCP
      && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    uv_err_new(stream->loop, errno);
    return -1;
  }

  /* Associate the fd with each ev_io watcher. */
  ev_io_set(&stream->read_watcher, fd, EV_READ);
  ev_io_set(&stream->write_watcher, fd, EV_WRITE);

  /* These should have been set up by uv_tcp_init or uv_pipe_init. */
  assert(stream->read_watcher.cb == uv__stream_io);
  assert(stream->write_watcher.cb == uv__stream_io);

  return 0;
}
Esempio n. 18
0
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
  assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);

  if (stream->flags & UV_CLOSING) {
    uv_err_new(stream->loop, EINVAL);
    return -1;
  }

  /* The UV_READING flag is irrelevant of the state of the tcp - it just
   * expresses the desired state of the user.
   */
  ((uv_handle_t*)stream)->flags |= UV_READING;

  /* TODO: try to do the read inline? */
  /* TODO: keep track of tcp state. If we've gotten a EOF then we should
   * not start the IO watcher.
   */
  assert(stream->fd >= 0);
  assert(alloc_cb);

  stream->read_cb = read_cb;
  stream->alloc_cb = alloc_cb;

  /* These should have been set by uv_tcp_init. */
  assert(stream->read_watcher.cb == uv__stream_io);

  ev_io_start(stream->loop->ev, &stream->read_watcher);
  return 0;
}
Esempio n. 19
0
int uv_fs_event_init(uv_loop_t* loop,
                     uv_fs_event_t* handle,
                     const char* filename,
                     uv_fs_event_cb cb) {
  uv_err_new(loop, ENOSYS);
  return -1;
}
Esempio n. 20
0
File: pipe.c Progetto: Cahya/node
/* TODO merge with uv__server_io()? */
void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
  struct sockaddr_un sun;
  uv_pipe_t* pipe;
  int saved_errno;
  int sockfd;

  saved_errno = errno;
  pipe = watcher->data;

  assert(pipe->type == UV_NAMED_PIPE);
  assert(pipe->pipe_fname != NULL);

  sockfd = uv__accept(pipe->fd, (struct sockaddr *)&sun, sizeof sun);
  if (sockfd == -1) {
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
      assert(0 && "EAGAIN on uv__accept(pipefd)");
    } else {
      uv_err_new(pipe->loop, errno);
    }
  } else {
    pipe->accepted_fd = sockfd;
    pipe->connection_cb((uv_stream_t*)pipe, 0);
    if (pipe->accepted_fd == sockfd) {
      /* The user hasn't yet accepted called uv_accept() */
      ev_io_stop(pipe->loop->ev, &pipe->read_watcher);
    }
  }

  errno = saved_errno;
}
Esempio n. 21
0
File: pipe.c Progetto: 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;
}
Esempio n. 22
0
int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
  if (addr.sin6_family != AF_INET6) {
    uv_err_new((uv_handle_t*)tcp, EFAULT);
    return -1;
  }

  return uv__bind(tcp, AF_INET6, (struct sockaddr*)&addr, sizeof(struct sockaddr_in6));
}
Esempio n. 23
0
File: core.c Progetto: Cahya/node
int uv_timer_again(uv_timer_t* timer) {
    if (!ev_is_active(&timer->timer_watcher)) {
        uv_err_new(timer->loop, EINVAL);
        return -1;
    }

    ev_timer_again(timer->loop->ev, &timer->timer_watcher);
    return 0;
}
Esempio n. 24
0
int uv_timer_again(uv_handle_t* handle) {
    if (!ev_is_active(&handle->timer_watcher)) {
        uv_err_new(handle, EINVAL);
        return -1;
    }

    ev_timer_again(EV_DEFAULT_UC_ &handle->timer_watcher);
    return 0;
}
Esempio n. 25
0
int uv_timer_again(uv_timer_t* timer) {
  if (!ev_is_active(&timer->timer_watcher)) {
    uv_err_new((uv_handle_t*)timer, EINVAL);
    return -1;
  }

  ev_timer_again(EV_DEFAULT_UC_ &timer->timer_watcher);
  return 0;
}
Esempio n. 26
0
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
  char* pathdup;
  int pathlen;

  uv_fs_req_init(loop, req, UV_FS_LSTAT, path, cb);

  /* TODO do this without duplicating the string. */
  /* TODO security */
  pathdup = strdup(path);
  pathlen = strlen(path);

  if (pathlen > 0 && path[pathlen - 1] == '\\') {
    /* TODO do not modify input string */
    pathdup[pathlen - 1] = '\0';
  }

  if (cb) {
    /* async */
    uv_ref(loop);
    req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req);

    free(pathdup);

    if (!req->eio) {
      uv_err_new(loop, ENOMEM);
      return -1;
    }

  } else {
    /* sync */
    req->result = lstat(pathdup, &req->statbuf);

    free(pathdup);

    if (req->result < 0) {
      uv_err_new(loop, errno);
      return -1;
    }

    req->ptr = &req->statbuf;
  }

  return 0;
}
Esempio n. 27
0
File: process.c Progetto: Cahya/node
int uv_process_kill(uv_process_t* process, int signum) {
  int r = kill(process->pid, signum);

  if (r) {
    uv_err_new(process->loop, errno);
    return -1;
  } else {
    return 0;
  }
}
Esempio n. 28
0
int uv_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
  int addrsize = sizeof(struct sockaddr_in);
  int domain = AF_INET;
  int r;

  if (tcp->fd <= 0) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    if (fd < 0) {
      uv_err_new((uv_handle_t*)tcp, errno);
      return -1;
    }

    if (uv_tcp_open(tcp, fd)) {
      close(fd);
      return -2;
    }
  }

  assert(tcp->fd >= 0);

  if (addr.sin_family != AF_INET) {
    uv_err_new((uv_handle_t*)tcp, EFAULT);
    return -1;
  }

  r = bind(tcp->fd, (struct sockaddr*) &addr, addrsize);
  tcp->delayed_error = 0;

  if (r) {
    switch (errno) {
      case EADDRINUSE:
        tcp->delayed_error = errno;
        return 0;

      default:
        uv_err_new((uv_handle_t*)tcp, errno);
        return -1;
    }
  }

  return 0;
}
Esempio n. 29
0
int uv_tcp_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
  if (addr.sin_family != AF_INET) {
    uv_err_new(tcp->loop, EFAULT);
    return -1;
  }

  return uv__tcp_bind(tcp,
                      AF_INET,
                      (struct sockaddr*)&addr,
                      sizeof(struct sockaddr_in));
}
Esempio n. 30
0
static int uv__tcp_bind(uv_tcp_t* tcp,
                        int domain,
                        struct sockaddr* addr,
                        int addrsize) {
  int saved_errno;
  int status;

  saved_errno = errno;
  status = -1;

  if (tcp->fd < 0) {
    if ((tcp->fd = uv__socket(domain, SOCK_STREAM, 0)) == -1) {
      uv_err_new(tcp->loop, errno);
      goto out;
    }

    if (uv__stream_open((uv_stream_t*)tcp, tcp->fd, UV_READABLE | UV_WRITABLE)) {
      uv__close(tcp->fd);
      tcp->fd = -1;
      status = -2;
      goto out;
    }
  }

  assert(tcp->fd >= 0);

  tcp->delayed_error = 0;
  if (bind(tcp->fd, addr, addrsize) == -1) {
    if (errno == EADDRINUSE) {
      tcp->delayed_error = errno;
    } else {
      uv_err_new(tcp->loop, errno);
      goto out;
    }
  }
  status = 0;

out:
  errno = saved_errno;
  return status;
}