static VALUE my_connect(VALUE klass, int io_wait, int domain, const void *addr, socklen_t addrlen) { int fd = my_socket(domain); if (connect(fd, addr, addrlen) < 0) { if (errno == EINPROGRESS) { VALUE io = sock_for_fd(klass, fd); if (io_wait) { errno = EAGAIN; (void)kgio_call_wait_writable(io); } return io; } close_fail(fd, "connect"); } return sock_for_fd(klass, fd); }
static VALUE my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen) { int fd = socket(domain, MY_SOCK_STREAM, 0); if (fd == -1) { switch (errno) { case EMFILE: case ENFILE: #ifdef ENOBUFS case ENOBUFS: #endif /* ENOBUFS */ errno = 0; rb_gc(); fd = socket(domain, MY_SOCK_STREAM, 0); } if (fd == -1) rb_sys_fail("socket"); } #ifndef SOCK_NONBLOCK if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1) close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)"); #endif /* SOCK_NONBLOCK */ if (connect(fd, addr, addrlen) == -1) { if (errno == EINPROGRESS) { VALUE io = sock_for_fd(klass, fd); if (io_wait) { errno = EAGAIN; (void)kgio_call_wait_writable(io); } return io; } close_fail(fd, "connect"); } return sock_for_fd(klass, fd); }
static int write_check(struct io_args *a, long n, const char *msg, int io_wait) { if (a->len == n) { done: a->buf = Qnil; } else if (n == -1) { if (errno == EINTR) { a->fd = my_fileno(a->io); return -1; } if (errno == EAGAIN) { long written = RSTRING_LEN(a->buf) - a->len; if (io_wait) { (void)kgio_call_wait_writable(a->io); /* buf may be modified in other thread/fiber */ a->len = RSTRING_LEN(a->buf) - written; if (a->len <= 0) goto done; a->ptr = RSTRING_PTR(a->buf) + written; return -1; } else if (written > 0) { a->buf = rb_str_new(a->ptr, a->len); } else { a->buf = sym_wait_writable; } return 0; } wr_sys_fail(msg); } else { assert(n >= 0 && n < a->len && "write/send syscall broken?"); a->ptr += n; a->len -= n; return -1; } return 0; }
static long writev_check(struct wrv_args *a, ssize_t n, const char *msg, int io_wait) { if (n >= 0) { if (n > 0) a->something_written = 1; return trim_writev_buffer(a, n); } else if (n < 0) { if (errno == EINTR) { a->fd = my_fileno(a->io); return -1; } if (errno == EAGAIN) { if (io_wait) { (void)kgio_call_wait_writable(a->io); return -1; } else if (!a->something_written) { a->buf = sym_wait_writable; } return 0; } kgio_wr_sys_fail(msg); } return 0; }