VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len) { int fd2; rb_secure(3); rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len); if (fd2 < 0) { switch (errno) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif case ECONNABORTED: #if defined EPROTO case EPROTO: #endif rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block"); } rb_sys_fail("accept(2)"); } rb_update_max_fd(fd2); make_fd_nonblock(fd2); return rsock_init_sock(rb_obj_alloc(klass), fd2); }
/* * call-seq: * io.nonblock = boolean -> boolean * * Enables non-blocking mode on a stream when set to * +true+, and blocking mode when set to +false+. */ static VALUE rb_io_nonblock_set(VALUE io, VALUE nb) { rb_io_t *fptr; GetOpenFile(io, fptr); if (RTEST(nb)) rb_io_set_nonblock(fptr); else io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb)); return io; }
/** * call-seq: * Rev::Buffer#write_to(io) -> Integer * * Perform a nonblocking write of the buffer to the given IO object. * As much data as possible is written until the call would block. * Any data which is written is removed from the buffer. */ static VALUE Rev_Buffer_write_to(VALUE self, VALUE io) { struct buffer *buf; #if HAVE_RB_IO_T rb_io_t *fptr; #else OpenFile *fptr; #endif Data_Get_Struct(self, struct buffer, buf); GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr); rb_io_set_nonblock(fptr); return INT2NUM(buffer_write_to(buf, FPTR_TO_FD(fptr))); }
VALUE rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) { rb_io_t *fptr; VALUE str; union_sockaddr buf; socklen_t alen = (socklen_t)sizeof buf; VALUE len, flg; long buflen; long slen; int fd, flags; VALUE addr = Qnil; socklen_t len0; rb_scan_args(argc, argv, "11", &len, &flg); if (flg == Qnil) flags = 0; else flags = NUM2INT(flg); buflen = NUM2INT(len); #ifdef MSG_DONTWAIT /* MSG_DONTWAIT avoids the race condition between fcntl and recvfrom. It is not portable, though. */ flags |= MSG_DONTWAIT; #endif GetOpenFile(sock, fptr); if (rb_io_read_pending(fptr)) { rb_raise(rb_eIOError, "recvfrom for buffered IO"); } fd = fptr->fd; str = rb_tainted_str_new(0, buflen); rb_io_check_closed(fptr); rb_io_set_nonblock(fptr); len0 = alen; slen = recvfrom(fd, RSTRING_PTR(str), buflen, flags, &buf.addr, &alen); if (slen != -1 && len0 < alen) alen = len0; if (slen < 0) { switch (errno) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvfrom(2) would block"); } rb_sys_fail("recvfrom(2)"); } if (slen < RSTRING_LEN(str)) { rb_str_set_len(str, slen); } rb_obj_taint(str); switch (from) { case RECV_RECV: return str; case RECV_IP: if (alen && alen != sizeof(buf)) /* connection-oriented socket may not return a from result */ addr = rsock_ipaddr(&buf.addr, alen, fptr->mode & FMODE_NOREVLOOKUP); break; case RECV_SOCKET: addr = rsock_io_socket_addrinfo(sock, &buf.addr, alen); break; default: rb_bug("rsock_s_recvfrom_nonblock called with bad value"); } return rb_assoc_new(str, addr); }