Skip to content

Commit

Permalink
prefer rb_syserr_fail
Browse files Browse the repository at this point in the history
* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nobu committed Dec 23, 2015
1 parent d15f308 commit f4166e2
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 112 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
@@ -1,3 +1,9 @@
Wed Dec 23 17:57:45 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>

* 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@ruby-lang.org>

* string.c: Fix document. Default value of the first
Expand Down
3 changes: 1 addition & 2 deletions ext/io/console/console.c
Expand Up @@ -280,8 +280,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void
}
if (status) {
if (status == -1) {
errno = error;
rb_sys_fail(0);
rb_syserr_fail(error, 0);
}
rb_jump_tag(status);
}
Expand Down
3 changes: 2 additions & 1 deletion ext/openssl/ossl_bio.c
Expand Up @@ -29,8 +29,9 @@ ossl_obj2bio(VALUE obj)
}
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);
Expand Down
16 changes: 10 additions & 6 deletions ext/socket/ancdata.c
Expand Up @@ -1275,18 +1275,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
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);
Expand Down Expand Up @@ -1547,18 +1549,20 @@ bsock_recvmsg_internal(VALUE sock,
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);
goto retry;
}
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) {
e = errno;
if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
if (ex == Qfalse) {
return sym_wait_readable;
}
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block");
}
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
if (!gc_done && (e == EMFILE || e == EMSGSIZE)) {
/*
* When SCM_RIGHTS hit the file descriptors limit:
* - Linux 2.6.18 causes success with MSG_CTRUNC
Expand All @@ -1571,11 +1575,11 @@ bsock_recvmsg_internal(VALUE sock,
goto retry;
}
#else
if (NIL_P(vmaxdatlen) && grow_buffer && errno == EMSGSIZE)
if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE)
ss = (ssize_t)iov.iov_len;
else
#endif
rb_sys_fail("recvmsg(2)");
rb_syserr_fail(e, "recvmsg(2)");
}

if (grow_buffer) {
Expand Down
18 changes: 10 additions & 8 deletions ext/socket/init.c
Expand Up @@ -62,8 +62,7 @@ rsock_init_sock(VALUE sock, int fd)
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);
Expand Down Expand Up @@ -246,7 +245,8 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
alen = len0;

if (slen < 0) {
switch (errno) {
int e = errno;
switch (e) {
case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
Expand All @@ -255,7 +255,7 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
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);
Expand Down Expand Up @@ -558,7 +558,8 @@ rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
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:
Expand All @@ -571,7 +572,7 @@ rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
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);
Expand Down Expand Up @@ -604,7 +605,8 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
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:
Expand All @@ -617,7 +619,7 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
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);
Expand Down
7 changes: 4 additions & 3 deletions ext/socket/socket.c
Expand Up @@ -452,18 +452,19 @@ sock_connect_nonblock(VALUE sock, VALUE addr, VALUE ex)
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);
Expand Down
6 changes: 4 additions & 2 deletions ext/socket/unixsocket.c
Expand Up @@ -65,14 +65,16 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server)
}

if (status < 0) {
int e = errno;
close(fd);
rsock_sys_fail_path("connect(2)", path);
rsock_syserr_fail_path(e, "connect(2)", path);
}

if (server) {
if (listen(fd, SOMAXCONN) < 0) {
int e = errno;
close(fd);
rsock_sys_fail_path("listen(2)", path);
rsock_syserr_fail_path(e, "listen(2)", path);
}
}

Expand Down
5 changes: 2 additions & 3 deletions ext/stringio/stringio.c
Expand Up @@ -33,7 +33,7 @@ static void strio_init(int, VALUE *, struct StringIO *, VALUE);
static VALUE strio_unget_bytes(struct StringIO *, const char *, long);

#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
#define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))
#define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))

static struct StringIO *
Expand Down Expand Up @@ -195,8 +195,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
}
StringValue(string);
if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
errno = EACCES;
rb_sys_fail(0);
rb_syserr_fail(EACCES, 0);
}
if (trunc) {
rb_str_resize(string, 0);
Expand Down
47 changes: 28 additions & 19 deletions file.c
Expand Up @@ -1954,8 +1954,9 @@ rb_file_s_size(VALUE klass, VALUE fname)
struct stat st;

if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}
return OFFT2NUM(st.st_size);
}
Expand Down Expand Up @@ -2048,8 +2049,9 @@ rb_file_s_atime(VALUE klass, VALUE fname)
struct stat st;

if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}
return stat_atime(&st);
}
Expand Down Expand Up @@ -2096,8 +2098,9 @@ rb_file_s_mtime(VALUE klass, VALUE fname)
struct stat st;

if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}
return stat_mtime(&st);
}
Expand Down Expand Up @@ -2147,8 +2150,9 @@ rb_file_s_ctime(VALUE klass, VALUE fname)
struct stat st;

if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}
return stat_ctime(&st);
}
Expand Down Expand Up @@ -2200,8 +2204,9 @@ rb_file_s_birthtime(VALUE klass, VALUE fname)
struct stat st;

if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}
return stat_birthtime(&st);
}
Expand Down Expand Up @@ -2529,7 +2534,8 @@ NORETURN(static void utime_failed(VALUE, const struct timespec *, VALUE, VALUE))
static void
utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime)
{
if (tsp && errno == EINVAL) {
int e = errno;
if (tsp && e == EINVAL) {
VALUE e[2], a = Qnil, m = Qnil;
int d = 0;
if (!NIL_P(atime)) {
Expand All @@ -2553,9 +2559,8 @@ utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime)
e[1] = INT2FIX(EINVAL);
rb_exc_raise(rb_class_new_instance(2, e, rb_eSystemCallError));
}
errno = EINVAL;
}
rb_sys_fail_path(path);
rb_syserr_fail_path(e, path);
}
#else
#define utime_failed(path, tsp, atime, mtime) rb_sys_fail_path(path)
Expand Down Expand Up @@ -2674,7 +2679,7 @@ syserr_fail2_in(const char *func, int e, VALUE s1, VALUE s2)
#endif

if (e == EEXIST) {
rb_sys_fail_path(rb_str_ellipsize(s2, max_pathlen));
rb_syserr_fail_path(e, rb_str_ellipsize(s2, max_pathlen));
}
str = rb_str_new_cstr("(");
rb_str_append(str, rb_str_ellipsize(s1, max_pathlen));
Expand Down Expand Up @@ -2787,8 +2792,9 @@ rb_readlink(VALUE path, rb_encoding *enc)
rb_str_set_len(v, size);
}
if (rv < 0) {
int e = errno;
rb_str_resize(v, 0);
rb_sys_fail_path(path);
rb_syserr_fail_path(e, path);
}
rb_str_resize(v, rv);

Expand Down Expand Up @@ -3738,8 +3744,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE l
checkval = rb_hash_aref(loopcheck, testpath);
if (!NIL_P(checkval)) {
if (checkval == ID2SYM(resolving)) {
errno = ELOOP;
rb_sys_fail_path(testpath);
rb_syserr_fail_path(ELOOP, testpath);
}
else {
*resolvedp = rb_str_dup(checkval);
Expand All @@ -3755,14 +3760,15 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE l
ret = lstat(RSTRING_PTR(testpath2), &sbuf);
#endif
if (ret == -1) {
if (errno == ENOENT) {
int e = errno;
if (e == ENOENT) {
if (strict || !last || *unresolved_firstsep)
rb_sys_fail_path(testpath);
rb_syserr_fail_path(e, testpath);
*resolvedp = testpath;
break;
}
else {
rb_sys_fail_path(testpath);
rb_syserr_fail_path(e, testpath);
}
}
#ifdef HAVE_READLINK
Expand Down Expand Up @@ -4439,8 +4445,9 @@ rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
}
rb_update_max_fd(tmpfd);
if (chsize(tmpfd, pos) < 0) {
int e = errno;
close(tmpfd);
rb_sys_fail_path(path);
rb_syserr_fail_path(e, path);
}
close(tmpfd);
}
Expand Down Expand Up @@ -4592,7 +4599,8 @@ rb_file_flock(VALUE obj, VALUE operation)
rb_io_flush_raw(obj, 0);
}
while ((int)rb_thread_io_blocking_region(rb_thread_flock, op, fptr->fd) < 0) {
switch (errno) {
int e = errno;
switch (e) {
case EAGAIN:
case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
Expand All @@ -4613,7 +4621,7 @@ rb_file_flock(VALUE obj, VALUE operation)
break;

default:
rb_sys_fail_path(fptr->pathv);
rb_syserr_fail_path(e, fptr->pathv);
}
}
return INT2FIX(0);
Expand Down Expand Up @@ -4787,8 +4795,9 @@ rb_f_test(int argc, VALUE *argv)

CHECK(1);
if (rb_stat(fname, &st) == -1) {
int e = errno;
FilePathValue(fname);
rb_sys_fail_path(fname);
rb_syserr_fail_path(e, fname);
}

switch (cmd) {
Expand Down

0 comments on commit f4166e2

Please sign in to comment.