ruby-changes:41192
From: nobu <ko1@a...>
Date: Wed, 23 Dec 2015 17:58:06 +0900 (JST)
Subject: [ruby-changes:41192] nobu:r53264 (trunk): prefer rb_syserr_fail
nobu 2015-12-23 17:57:48 +0900 (Wed, 23 Dec 2015) New Revision: 53264 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53264 Log: prefer rb_syserr_fail * file.c, io.c, util.c: prefer rb_syserr_fail with saved errno over setting errno then call rb_sys_fail, not to be clobbered potentially and to reduce thread local errno accesses. Modified files: trunk/ChangeLog trunk/ext/io/console/console.c trunk/ext/openssl/ossl_bio.c trunk/ext/socket/ancdata.c trunk/ext/socket/init.c trunk/ext/socket/socket.c trunk/ext/socket/unixsocket.c trunk/ext/stringio/stringio.c trunk/file.c trunk/io.c trunk/process.c trunk/util.c Index: ChangeLog =================================================================== --- ChangeLog (revision 53263) +++ ChangeLog (revision 53264) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 23 17:57:45 2015 Nobuyoshi Nakada <nobu@r...> + + * file.c, io.c, util.c: prefer rb_syserr_fail with saved errno + over setting errno then call rb_sys_fail, not to be clobbered + potentially and to reduce thread local errno accesses. + Wed Dec 23 11:58:52 2015 Yuichiro Kaneko <yui-knk@r...> * string.c: Fix document. Default value of the first Index: io.c =================================================================== --- io.c (revision 53263) +++ io.c (revision 53264) @@ -551,8 +551,9 @@ io_unread(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L551 } read_size = _read(fptr->fd, buf, fptr->rbuf.len + newlines); if (read_size < 0) { + int e = errno; free(buf); - rb_sys_fail_path(fptr->pathv); + rb_syserr_fail_path(e, fptr->pathv); } if (read_size == fptr->rbuf.len) { lseek(fptr->fd, r, SEEK_SET); @@ -1768,11 +1769,12 @@ io_fillbuf(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L1769 if (rb_io_wait_readable(fptr->fd)) goto retry; { + int e = errno; VALUE path = rb_sprintf("fd:%d ", fptr->fd); if (!NIL_P(fptr->pathv)) { rb_str_append(path, fptr->pathv); } - rb_sys_fail_path(path); + rb_syserr_fail_path(e, path); } } fptr->rbuf.off = 0; @@ -2537,15 +2539,16 @@ io_getpartial(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/io.c#L2539 rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg); n = arg.len; if (n < 0) { + int e = errno; if (!nonblock && rb_io_wait_readable(fptr->fd)) goto again; - if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { if (no_exception_p(opts)) return sym_wait_readable; else rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block"); } - rb_sys_fail_path(fptr->pathv); + rb_syserr_fail_path(e, fptr->pathv); } } io_set_read_length(str, n); @@ -2665,11 +2668,12 @@ io_read_nonblock(VALUE io, VALUE length, https://github.com/ruby/ruby/blob/trunk/io.c#L2668 rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg); n = arg.len; if (n < 0) { - if ((errno == EWOULDBLOCK || errno == EAGAIN)) { + int e = errno; + if ((e == EWOULDBLOCK || e == EAGAIN)) { if (ex == Qfalse) return sym_wait_readable; rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block"); } - rb_sys_fail_path(fptr->pathv); + rb_syserr_fail_path(e, fptr->pathv); } } io_set_read_length(str, n); @@ -2703,7 +2707,8 @@ io_write_nonblock(VALUE io, VALUE str, V https://github.com/ruby/ruby/blob/trunk/io.c#L2707 n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str)); if (n == -1) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { + int e = errno; + if (e == EWOULDBLOCK || e == EAGAIN) { if (ex == Qfalse) { return sym_wait_writable; } @@ -2711,7 +2716,7 @@ io_write_nonblock(VALUE io, VALUE str, V https://github.com/ruby/ruby/blob/trunk/io.c#L2716 rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block"); } } - rb_sys_fail_path(fptr->pathv); + rb_syserr_fail_path(e, fptr->pathv); } return LONG2FIX(n); @@ -4244,8 +4249,7 @@ fptr_finalize(rb_io_t *fptr, int noraise https://github.com/ruby/ruby/blob/trunk/io.c#L4249 switch (TYPE(err)) { case T_FIXNUM: case T_BIGNUM: - errno = NUM2INT(err); - rb_sys_fail_path(fptr->pathv); + rb_syserr_fail_path(NUM2INT(err), fptr->pathv); default: rb_exc_raise(err); @@ -5454,12 +5458,13 @@ rb_fdopen(int fd, const char *modestr) https://github.com/ruby/ruby/blob/trunk/io.c#L5458 file = fdopen(fd, modestr); } if (!file) { + int e = errno; #ifdef _WIN32 - if (errno == 0) errno = EINVAL; + if (e == 0) e = EINVAL; #elif defined(__sun) - if (errno == 0) errno = EMFILE; + if (e == 0) e = EMFILE; #endif - rb_sys_fail(0); + rb_syserr_fail(e, 0); } } @@ -5888,8 +5893,8 @@ pipe_open(VALUE execarg_obj, const char https://github.com/ruby/ruby/blob/trunk/io.c#L5893 #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) int state; struct popen_arg arg; - int e = 0; #endif + int e = 0; #if defined(HAVE_SPAWNV) # if defined(HAVE_SPAWNVE) # define DO_SPAWN(cmd, args, envp) ((args) ? \ @@ -5940,11 +5945,10 @@ pipe_open(VALUE execarg_obj, const char https://github.com/ruby/ruby/blob/trunk/io.c#L5945 if (rb_pipe(arg.write_pair) < 0) rb_sys_fail_str(prog); if (rb_pipe(arg.pair) < 0) { - int e = errno; + e = errno; close(arg.write_pair[0]); close(arg.write_pair[1]); - errno = e; - rb_sys_fail_str(prog); + rb_syserr_fail_str(e, prog); } if (eargp) { rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.write_pair[0])); @@ -6027,12 +6031,11 @@ pipe_open(VALUE execarg_obj, const char https://github.com/ruby/ruby/blob/trunk/io.c#L6031 close(arg.write_pair[0]); close(arg.write_pair[1]); } - errno = e; # if defined(HAVE_WORKING_FORK) if (errmsg[0]) - rb_sys_fail(errmsg); + rb_syserr_fail(e, errmsg); # endif - rb_sys_fail_str(prog); + rb_syserr_fail_str(e, prog); } if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) { close(arg.pair[1]); @@ -6058,11 +6061,12 @@ pipe_open(VALUE execarg_obj, const char https://github.com/ruby/ruby/blob/trunk/io.c#L6061 rb_execarg_run_options(eargp, sargp, NULL, 0); } fp = popen(cmd, modestr); + e = errno; if (eargp) { rb_execarg_parent_end(execarg_obj); rb_execarg_run_options(sargp, NULL, NULL, 0); } - if (!fp) rb_sys_fail_path(prog); + if (!fp) rb_syserr_fail_path(e, prog); fd = fileno(fp); #endif @@ -10688,8 +10692,7 @@ copy_stream_finalize(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L10692 } rb_fd_term(&stp->fds); if (stp->syserr) { - errno = stp->error_no; - rb_sys_fail(stp->syserr); + rb_syserr_fail(stp->error_no, stp->syserr); } if (stp->notimp) { rb_raise(rb_eNotImpError, "%s() not implemented", stp->notimp); Index: util.c =================================================================== --- util.c (revision 53263) +++ util.c (revision 53264) @@ -507,9 +507,10 @@ ruby_getcwd(void) https://github.com/ruby/ruby/blob/trunk/util.c#L507 char *buf = xmalloc(size); while (!getcwd(buf, size)) { - if (errno != ERANGE) { + int e = errno; + if (e != ERANGE) { xfree(buf); - rb_sys_fail("getcwd"); + rb_syserr_fail(e, "getcwd"); } size *= 2; buf = xrealloc(buf, size); @@ -527,8 +528,9 @@ ruby_getcwd(void) https://github.com/ruby/ruby/blob/trunk/util.c#L528 char *buf = xmalloc(PATH_MAX+1); if (!getwd(buf)) { + int e = errno; xfree(buf); - rb_sys_fail("getwd"); + rb_syserr_fail(e, "getwd"); } #endif return buf; Index: process.c =================================================================== --- process.c (revision 53263) +++ process.c (revision 53264) @@ -1061,9 +1061,10 @@ proc_waitall(void) https://github.com/ruby/ruby/blob/trunk/process.c#L1061 for (pid = -1;;) { pid = rb_waitpid(-1, &status, 0); if (pid == -1) { - if (errno == ECHILD) + int e = errno; + if (e == ECHILD) break; - rb_sys_fail(0); + rb_syserr_fail(e, 0); } rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get())); } @@ -3436,8 +3437,7 @@ disable_child_handler_before_fork(struct https://github.com/ruby/ruby/blob/trunk/process.c#L3437 ret = pthread_sigmask(SIG_SETMASK, &all, &old->sigmask); /* not async-signal-safe */ if (ret != 0) { - errno = ret; - rb_sys_fail("pthread_sigmask"); + rb_syserr_fail(ret, "pthread_sigmask"); } #else # pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" @@ -3446,8 +3446,7 @@ disable_child_handler_before_fork(struct https://github.com/ruby/ruby/blob/trunk/process.c#L3446 #ifdef PTHREAD_CANCEL_DISABLE ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old->cancelstate); if (ret != 0) { - errno = ret; - rb_sys_fail("pthread_setcancelstate"); + rb_syserr_fail(ret, "pthread_setcancelstate"); } #endif } @@ -3460,16 +3459,14 @@ disable_child_handler_fork_parent(struct https://github.com/ruby/ruby/blob/trunk/process.c#L3459 #ifdef PTHREAD_CANCEL_DISABLE ret = pthread_setcancelstate(old->cancelstate, NULL); if (ret != 0) { - errno = ret; - rb_sys_fail("pthread_setcancelstate"); + rb_syserr_fail(ret, "pthread_setcancelstate"); } #endif #ifdef HAVE_PTHREAD_SIGMASK ret = pthread_sigmask(SIG_SETMASK, &old->sigmask, NULL); /* not async-signal-safe */ if (ret != 0) { - errno = ret; - rb_sys_fail("pthread_sigmask"); + rb_syserr_fail(ret, "pthread_sigmask"); } #else # pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" @@ -5023,9 +5020,10 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/process.c#L5020 errno = ERANGE; /* gepwnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ while (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr)) { - if (errno != ERANGE || getpw_buf_len >= GETPW_R_SIZE_LIMIT) { + int e = errno; + if (e != ERANGE || getpw_buf_len >= GETPW_R_SIZE_LIMIT) { rb_free_tmp_buffer(getpw_tmp); - rb_sys_fail("getpwnam_r"); + rb_syserr_fail(e, "getpwnam_r"); } rb_str_modify_expand(*getpw_tmp, getpw_buf_len); getpw_buf = RSTRING_PTR(*getpw_tmp); @@ -5101,9 +5099,10 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/process.c#L5099 errno = ERANGE; /* gegrnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ while (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr)) { - if (errno != ERANGE || getgr_buf_len >= GETGR_R_SIZE_LIMIT) { + int e = errno; + if (e != ERANGE || getgr_buf_len >= GETGR_R_SIZE_LIMIT) { rb_free_tmp_buffer(getgr_tmp); - rb_sys_fail("getgrnam_r"); + rb_syserr_fail(e, "getgrnam_r"); } rb_str_modify_expand(*getgr_tmp, getgr_buf_len); getgr_buf = RSTRING_PTR(*getgr_tmp); @@ -5494,8 +5493,7 @@ p_uid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/process.c#L5493 if (setruid(uid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_44BSD_SETUID if (getuid() == uid) { @@ -5504,24 +5502,21 @@ p_uid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/process.c#L5502 SAVED_USER_ID = uid; } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_SETEUID if (getuid() == uid && SAVED_USER_ID == uid) { if (seteuid(uid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_SETUID if (getuid() == uid && SAVED_USER_ID == uid) { if (setuid(uid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #else rb_notimplement(); @@ -6200,8 +6195,7 @@ p_gid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/process.c#L6195 if (setrgid(gid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_44BSD_SETGID if (getgid() == gid) { @@ -6210,24 +6204,21 @@ p_gid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/process.c#L6204 SAVED_GROUP_ID = gid; } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_SETEGID if (getgid() == gid && SAVED_GROUP_ID == gid) { if (setegid(gid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #elif defined HAVE_SETGID if (getgid() == gid && SAVED_GROUP_ID == gid) { if (setgid(gid) < 0) rb_sys_fail(0); } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } #else (void)gid; @@ -6690,8 +6681,7 @@ p_uid_switch(VALUE obj) https://github.com/ruby/ruby/blob/trunk/process.c#L6681 } } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } UNREACHABLE; @@ -6715,8 +6705,7 @@ p_uid_switch(VALUE obj) https://github.com/ruby/ruby/blob/trunk/process.c#L6705 euid = geteuid(); if (uid == euid) { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } p_uid_exchange(obj); if (rb_block_given_p()) { @@ -6805,8 +6794,7 @@ p_gid_switch(VALUE obj) https://github.com/ruby/ruby/blob/trunk/process.c#L6794 } } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } UNREACHABLE; @@ -6830,8 +6818,7 @@ p_gid_switch(VALUE obj) https://github.com/ruby/ruby/blob/trunk/process.c#L6818 egid = getegid(); if (gid == egid) { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } p_gid_exchange(obj); if (rb_block_given_p()) { @@ -7375,8 +7362,7 @@ rb_clock_gettime(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/process.c#L7362 #endif } /* EINVAL emulates clock_gettime behavior when clock_id is invalid. */ - errno = EINVAL; - rb_sys_fail(0); + rb_syserr_fail(EINVAL, 0); success: return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit); @@ -7514,8 +7500,7 @@ rb_clock_getres(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/process.c#L7500 #endif } /* EINVAL emulates clock_getres behavior when clock_id is invalid. */ - errno = EINVAL; - rb_sys_fail(0); + rb_syserr_fail(EINVAL, 0); success: if (unit == ID2SYM(id_hertz)) { Index: ext/openssl/ossl_bio.c =================================================================== --- ext/openssl/ossl_bio.c (revision 53263) +++ ext/openssl/ossl_bio.c (revision 53264) @@ -29,8 +29,9 @@ ossl_obj2bio(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_bio.c#L29 } rb_update_max_fd(fd); if (!(fp = fdopen(fd, "r"))){ + int e = errno; close(fd); - rb_sys_fail(0); + rb_syserr_fail(e, 0); } if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){ fclose(fp); Index: ext/socket/init.c =================================================================== --- ext/socket/init.c (revision 53263) +++ ext/socket/init.c (revision 53264) @@ -62,8 +62,7 @@ rsock_init_sock(VALUE sock, int fd) https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L62 rb_io_t *fp; if (!is_socket(fd) || rb_reserved_fd_p(fd)) { - errno = EBADF; - rb_sys_fail("not a socket file descriptor"); + rb_syserr_fail(EBADF, "not a socket file descriptor"); } rb_update_max_fd(fd); @@ -246,7 +245,8 @@ rsock_s_recvfrom_nonblock(VALUE sock, VA https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L245 alen = len0; if (slen < 0) { - switch (errno) { + int e = errno; + switch (e) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: @@ -255,7 +255,7 @@ rsock_s_recvfrom_nonblock(VALUE sock, VA https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L255 return sym_wait_readable; rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvfrom(2) would block"); } - rb_sys_fail("recvfrom(2)"); + rb_syserr_fail(e, "recvfrom(2)"); } if (slen != RSTRING_LEN(str)) { rb_str_set_len(str, slen); @@ -558,7 +558,8 @@ rsock_s_accept_nonblock(VALUE klass, VAL https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L558 rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1); if (fd2 < 0) { - switch (errno) { + int e = errno; + switch (e) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: @@ -571,7 +572,7 @@ rsock_s_accept_nonblock(VALUE klass, VAL https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L572 return sym_wait_readable; rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block"); } - rb_sys_fail("accept(2)"); + rb_syserr_fail(e, "accept(2)"); } rb_update_max_fd(fd2); return rsock_init_sock(rb_obj_alloc(klass), fd2); @@ -604,7 +605,8 @@ rsock_s_accept(VALUE klass, int fd, stru https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L605 rsock_maybe_wait_fd(fd); fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg); if (fd2 < 0) { - switch (errno) { + int e = errno; + switch (e) { case EMFILE: case ENFILE: case ENOMEM: @@ -617,7 +619,7 @@ rsock_s_accept(VALUE klass, int fd, stru https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L619 retry = 0; goto retry; } - rb_sys_fail("accept(2)"); + rb_syserr_fail(e, "accept(2)"); } rb_update_max_fd(fd2); if (!klass) return INT2NUM(fd2); Index: ext/socket/socket.c =================================================================== --- ext/socket/socket.c (revision 53263) +++ ext/socket/socket.c (revision 53264) @@ -452,18 +452,19 @@ sock_connect_nonblock(VALUE sock, VALUE https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L452 rb_io_set_nonblock(fptr); n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)); if (n < 0) { - if (errno == EINPROGRESS) { + int e = errno; + if (e == EINPROGRESS) { if (ex == Qfalse) { return sym_wait_writable; } rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "connect(2) would block"); } - if (errno == EISCONN) { + if (e == EISCONN) { if (ex == Qfalse) { return INT2FIX(0); } } - rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); + rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); } return INT2FIX(n); Index: ext/socket/ancdata.c =================================================================== --- ext/socket/ancdata.c (revision 53263) +++ ext/socket/ancdata.c (revision 53264) @@ -1275,18 +1275,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE https://github.com/ruby/ruby/blob/trunk/ext/socket/ancdata.c#L1275 ss = rb_sendmsg(fptr->fd, &mh, flags); if (ss == -1) { + int e; if (!nonblock && rb_io_wait_writable(fptr->fd)) { rb_io_check_closed(fptr); goto retry; } - if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { + e = errno; + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { if (ex == Qfalse) { return sym_wait_writable; } rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block"); } - rb_sys_fail("sendmsg(2)"); + rb_syserr_fail(e, "sendmsg(2)"); } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) RB_GC_GUARD(controls_str); @@ -1547,18 +1549,20 @@ bsock_recvmsg_internal(VALUE sock, https://github.com/ruby/ruby/blob/trunk/ext/socket/ancdata.c#L1549 ss = rb_recvmsg(fptr->fd, &mh, flags); if (ss == -1) { + int e; if (!nonblock && rb_io_wait_readable(fptr->fd)) { rb_io_check_closed(fptr); (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/