1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-12-23 08:57:48 +00:00
parent d15f30882a
commit f4166e2dd7
12 changed files with 125 additions and 112 deletions

View file

@ -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> Wed Dec 23 11:58:52 2015 Yuichiro Kaneko <yui-knk@ruby-lang.org>
* string.c: Fix document. Default value of the first * string.c: Fix document. Default value of the first

View file

@ -280,8 +280,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void
} }
if (status) { if (status) {
if (status == -1) { if (status == -1) {
errno = error; rb_syserr_fail(error, 0);
rb_sys_fail(0);
} }
rb_jump_tag(status); rb_jump_tag(status);
} }

View file

@ -29,8 +29,9 @@ ossl_obj2bio(VALUE obj)
} }
rb_update_max_fd(fd); rb_update_max_fd(fd);
if (!(fp = fdopen(fd, "r"))){ if (!(fp = fdopen(fd, "r"))){
int e = errno;
close(fd); close(fd);
rb_sys_fail(0); rb_syserr_fail(e, 0);
} }
if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){ if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
fclose(fp); fclose(fp);

View file

@ -1275,18 +1275,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
ss = rb_sendmsg(fptr->fd, &mh, flags); ss = rb_sendmsg(fptr->fd, &mh, flags);
if (ss == -1) { if (ss == -1) {
int e;
if (!nonblock && rb_io_wait_writable(fptr->fd)) { if (!nonblock && rb_io_wait_writable(fptr->fd)) {
rb_io_check_closed(fptr); rb_io_check_closed(fptr);
goto retry; goto retry;
} }
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { e = errno;
if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
if (ex == Qfalse) { if (ex == Qfalse) {
return sym_wait_writable; return sym_wait_writable;
} }
rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE,
"sendmsg(2) would block"); "sendmsg(2) would block");
} }
rb_sys_fail("sendmsg(2)"); rb_syserr_fail(e, "sendmsg(2)");
} }
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
RB_GC_GUARD(controls_str); RB_GC_GUARD(controls_str);
@ -1547,18 +1549,20 @@ bsock_recvmsg_internal(VALUE sock,
ss = rb_recvmsg(fptr->fd, &mh, flags); ss = rb_recvmsg(fptr->fd, &mh, flags);
if (ss == -1) { if (ss == -1) {
int e;
if (!nonblock && rb_io_wait_readable(fptr->fd)) { if (!nonblock && rb_io_wait_readable(fptr->fd)) {
rb_io_check_closed(fptr); rb_io_check_closed(fptr);
goto retry; goto retry;
} }
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { e = errno;
if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
if (ex == Qfalse) { if (ex == Qfalse) {
return sym_wait_readable; return sym_wait_readable;
} }
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block"); rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block");
} }
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) #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: * When SCM_RIGHTS hit the file descriptors limit:
* - Linux 2.6.18 causes success with MSG_CTRUNC * - Linux 2.6.18 causes success with MSG_CTRUNC
@ -1571,11 +1575,11 @@ bsock_recvmsg_internal(VALUE sock,
goto retry; goto retry;
} }
#else #else
if (NIL_P(vmaxdatlen) && grow_buffer && errno == EMSGSIZE) if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE)
ss = (ssize_t)iov.iov_len; ss = (ssize_t)iov.iov_len;
else else
#endif #endif
rb_sys_fail("recvmsg(2)"); rb_syserr_fail(e, "recvmsg(2)");
} }
if (grow_buffer) { if (grow_buffer) {

View file

@ -62,8 +62,7 @@ rsock_init_sock(VALUE sock, int fd)
rb_io_t *fp; rb_io_t *fp;
if (!is_socket(fd) || rb_reserved_fd_p(fd)) { if (!is_socket(fd) || rb_reserved_fd_p(fd)) {
errno = EBADF; rb_syserr_fail(EBADF, "not a socket file descriptor");
rb_sys_fail("not a socket file descriptor");
} }
rb_update_max_fd(fd); rb_update_max_fd(fd);
@ -246,7 +245,8 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
alen = len0; alen = len0;
if (slen < 0) { if (slen < 0) {
switch (errno) { int e = errno;
switch (e) {
case EAGAIN: case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK: case EWOULDBLOCK:
@ -255,7 +255,7 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
return sym_wait_readable; return sym_wait_readable;
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvfrom(2) would block"); 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)) { if (slen != RSTRING_LEN(str)) {
rb_str_set_len(str, slen); rb_str_set_len(str, slen);
@ -558,7 +558,8 @@ rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
rb_io_set_nonblock(fptr); rb_io_set_nonblock(fptr);
fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1);
if (fd2 < 0) { if (fd2 < 0) {
switch (errno) { int e = errno;
switch (e) {
case EAGAIN: case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK: case EWOULDBLOCK:
@ -571,7 +572,7 @@ rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
return sym_wait_readable; return sym_wait_readable;
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block"); 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); rb_update_max_fd(fd2);
return rsock_init_sock(rb_obj_alloc(klass), fd2); return rsock_init_sock(rb_obj_alloc(klass), fd2);
@ -604,7 +605,8 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
rsock_maybe_wait_fd(fd); rsock_maybe_wait_fd(fd);
fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg); fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg);
if (fd2 < 0) { if (fd2 < 0) {
switch (errno) { int e = errno;
switch (e) {
case EMFILE: case EMFILE:
case ENFILE: case ENFILE:
case ENOMEM: case ENOMEM:
@ -617,7 +619,7 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
retry = 0; retry = 0;
goto retry; goto retry;
} }
rb_sys_fail("accept(2)"); rb_syserr_fail(e, "accept(2)");
} }
rb_update_max_fd(fd2); rb_update_max_fd(fd2);
if (!klass) return INT2NUM(fd2); if (!klass) return INT2NUM(fd2);

View file

@ -452,18 +452,19 @@ sock_connect_nonblock(VALUE sock, VALUE addr, VALUE ex)
rb_io_set_nonblock(fptr); rb_io_set_nonblock(fptr);
n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)); n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr));
if (n < 0) { if (n < 0) {
if (errno == EINPROGRESS) { int e = errno;
if (e == EINPROGRESS) {
if (ex == Qfalse) { if (ex == Qfalse) {
return sym_wait_writable; return sym_wait_writable;
} }
rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "connect(2) would block"); rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "connect(2) would block");
} }
if (errno == EISCONN) { if (e == EISCONN) {
if (ex == Qfalse) { if (ex == Qfalse) {
return INT2FIX(0); 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); return INT2FIX(n);

View file

@ -65,14 +65,16 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server)
} }
if (status < 0) { if (status < 0) {
int e = errno;
close(fd); close(fd);
rsock_sys_fail_path("connect(2)", path); rsock_syserr_fail_path(e, "connect(2)", path);
} }
if (server) { if (server) {
if (listen(fd, SOMAXCONN) < 0) { if (listen(fd, SOMAXCONN) < 0) {
int e = errno;
close(fd); close(fd);
rsock_sys_fail_path("listen(2)", path); rsock_syserr_fail_path(e, "listen(2)", path);
} }
} }

View file

@ -33,7 +33,7 @@ static void strio_init(int, VALUE *, struct StringIO *, VALUE);
static VALUE strio_unget_bytes(struct StringIO *, const char *, long); static VALUE strio_unget_bytes(struct StringIO *, const char *, long);
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type)) #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)) #define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
static struct StringIO * static struct StringIO *
@ -195,8 +195,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
} }
StringValue(string); StringValue(string);
if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) { if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
errno = EACCES; rb_syserr_fail(EACCES, 0);
rb_sys_fail(0);
} }
if (trunc) { if (trunc) {
rb_str_resize(string, 0); rb_str_resize(string, 0);

47
file.c
View file

@ -1954,8 +1954,9 @@ rb_file_s_size(VALUE klass, VALUE fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
return OFFT2NUM(st.st_size); return OFFT2NUM(st.st_size);
} }
@ -2048,8 +2049,9 @@ rb_file_s_atime(VALUE klass, VALUE fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
return stat_atime(&st); return stat_atime(&st);
} }
@ -2096,8 +2098,9 @@ rb_file_s_mtime(VALUE klass, VALUE fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
return stat_mtime(&st); return stat_mtime(&st);
} }
@ -2147,8 +2150,9 @@ rb_file_s_ctime(VALUE klass, VALUE fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
return stat_ctime(&st); return stat_ctime(&st);
} }
@ -2200,8 +2204,9 @@ rb_file_s_birthtime(VALUE klass, VALUE fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
return stat_birthtime(&st); return stat_birthtime(&st);
} }
@ -2529,7 +2534,8 @@ NORETURN(static void utime_failed(VALUE, const struct timespec *, VALUE, VALUE))
static void static void
utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime) 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; VALUE e[2], a = Qnil, m = Qnil;
int d = 0; int d = 0;
if (!NIL_P(atime)) { if (!NIL_P(atime)) {
@ -2553,9 +2559,8 @@ utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime)
e[1] = INT2FIX(EINVAL); e[1] = INT2FIX(EINVAL);
rb_exc_raise(rb_class_new_instance(2, e, rb_eSystemCallError)); 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 #else
#define utime_failed(path, tsp, atime, mtime) rb_sys_fail_path(path) #define utime_failed(path, tsp, atime, mtime) rb_sys_fail_path(path)
@ -2674,7 +2679,7 @@ syserr_fail2_in(const char *func, int e, VALUE s1, VALUE s2)
#endif #endif
if (e == EEXIST) { 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("("); str = rb_str_new_cstr("(");
rb_str_append(str, rb_str_ellipsize(s1, max_pathlen)); rb_str_append(str, rb_str_ellipsize(s1, max_pathlen));
@ -2787,8 +2792,9 @@ rb_readlink(VALUE path, rb_encoding *enc)
rb_str_set_len(v, size); rb_str_set_len(v, size);
} }
if (rv < 0) { if (rv < 0) {
int e = errno;
rb_str_resize(v, 0); rb_str_resize(v, 0);
rb_sys_fail_path(path); rb_syserr_fail_path(e, path);
} }
rb_str_resize(v, rv); rb_str_resize(v, rv);
@ -3738,8 +3744,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE l
checkval = rb_hash_aref(loopcheck, testpath); checkval = rb_hash_aref(loopcheck, testpath);
if (!NIL_P(checkval)) { if (!NIL_P(checkval)) {
if (checkval == ID2SYM(resolving)) { if (checkval == ID2SYM(resolving)) {
errno = ELOOP; rb_syserr_fail_path(ELOOP, testpath);
rb_sys_fail_path(testpath);
} }
else { else {
*resolvedp = rb_str_dup(checkval); *resolvedp = rb_str_dup(checkval);
@ -3755,14 +3760,15 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE l
ret = lstat(RSTRING_PTR(testpath2), &sbuf); ret = lstat(RSTRING_PTR(testpath2), &sbuf);
#endif #endif
if (ret == -1) { if (ret == -1) {
if (errno == ENOENT) { int e = errno;
if (e == ENOENT) {
if (strict || !last || *unresolved_firstsep) if (strict || !last || *unresolved_firstsep)
rb_sys_fail_path(testpath); rb_syserr_fail_path(e, testpath);
*resolvedp = testpath; *resolvedp = testpath;
break; break;
} }
else { else {
rb_sys_fail_path(testpath); rb_syserr_fail_path(e, testpath);
} }
} }
#ifdef HAVE_READLINK #ifdef HAVE_READLINK
@ -4439,8 +4445,9 @@ rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
} }
rb_update_max_fd(tmpfd); rb_update_max_fd(tmpfd);
if (chsize(tmpfd, pos) < 0) { if (chsize(tmpfd, pos) < 0) {
int e = errno;
close(tmpfd); close(tmpfd);
rb_sys_fail_path(path); rb_syserr_fail_path(e, path);
} }
close(tmpfd); close(tmpfd);
} }
@ -4592,7 +4599,8 @@ rb_file_flock(VALUE obj, VALUE operation)
rb_io_flush_raw(obj, 0); rb_io_flush_raw(obj, 0);
} }
while ((int)rb_thread_io_blocking_region(rb_thread_flock, op, fptr->fd) < 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 EAGAIN:
case EACCES: case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
@ -4613,7 +4621,7 @@ rb_file_flock(VALUE obj, VALUE operation)
break; break;
default: default:
rb_sys_fail_path(fptr->pathv); rb_syserr_fail_path(e, fptr->pathv);
} }
} }
return INT2FIX(0); return INT2FIX(0);
@ -4787,8 +4795,9 @@ rb_f_test(int argc, VALUE *argv)
CHECK(1); CHECK(1);
if (rb_stat(fname, &st) == -1) { if (rb_stat(fname, &st) == -1) {
int e = errno;
FilePathValue(fname); FilePathValue(fname);
rb_sys_fail_path(fname); rb_syserr_fail_path(e, fname);
} }
switch (cmd) { switch (cmd) {

49
io.c
View file

@ -551,8 +551,9 @@ io_unread(rb_io_t *fptr)
} }
read_size = _read(fptr->fd, buf, fptr->rbuf.len + newlines); read_size = _read(fptr->fd, buf, fptr->rbuf.len + newlines);
if (read_size < 0) { if (read_size < 0) {
int e = errno;
free(buf); free(buf);
rb_sys_fail_path(fptr->pathv); rb_syserr_fail_path(e, fptr->pathv);
} }
if (read_size == fptr->rbuf.len) { if (read_size == fptr->rbuf.len) {
lseek(fptr->fd, r, SEEK_SET); lseek(fptr->fd, r, SEEK_SET);
@ -1768,11 +1769,12 @@ io_fillbuf(rb_io_t *fptr)
if (rb_io_wait_readable(fptr->fd)) if (rb_io_wait_readable(fptr->fd))
goto retry; goto retry;
{ {
int e = errno;
VALUE path = rb_sprintf("fd:%d ", fptr->fd); VALUE path = rb_sprintf("fd:%d ", fptr->fd);
if (!NIL_P(fptr->pathv)) { if (!NIL_P(fptr->pathv)) {
rb_str_append(path, fptr->pathv); rb_str_append(path, fptr->pathv);
} }
rb_sys_fail_path(path); rb_syserr_fail_path(e, path);
} }
} }
fptr->rbuf.off = 0; fptr->rbuf.off = 0;
@ -2537,15 +2539,16 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg); rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
n = arg.len; n = arg.len;
if (n < 0) { if (n < 0) {
int e = errno;
if (!nonblock && rb_io_wait_readable(fptr->fd)) if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again; goto again;
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) { if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
if (no_exception_p(opts)) if (no_exception_p(opts))
return sym_wait_readable; return sym_wait_readable;
else else
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block"); 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); io_set_read_length(str, n);
@ -2665,11 +2668,12 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg); rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
n = arg.len; n = arg.len;
if (n < 0) { if (n < 0) {
if ((errno == EWOULDBLOCK || errno == EAGAIN)) { int e = errno;
if ((e == EWOULDBLOCK || e == EAGAIN)) {
if (ex == Qfalse) return sym_wait_readable; if (ex == Qfalse) return sym_wait_readable;
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block"); 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); io_set_read_length(str, n);
@ -2703,7 +2707,8 @@ io_write_nonblock(VALUE io, VALUE str, VALUE ex)
n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str)); n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
if (n == -1) { if (n == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN) { int e = errno;
if (e == EWOULDBLOCK || e == EAGAIN) {
if (ex == Qfalse) { if (ex == Qfalse) {
return sym_wait_writable; return sym_wait_writable;
} }
@ -2711,7 +2716,7 @@ io_write_nonblock(VALUE io, VALUE str, VALUE ex)
rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block"); 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); return LONG2FIX(n);
@ -4244,8 +4249,7 @@ fptr_finalize(rb_io_t *fptr, int noraise)
switch (TYPE(err)) { switch (TYPE(err)) {
case T_FIXNUM: case T_FIXNUM:
case T_BIGNUM: case T_BIGNUM:
errno = NUM2INT(err); rb_syserr_fail_path(NUM2INT(err), fptr->pathv);
rb_sys_fail_path(fptr->pathv);
default: default:
rb_exc_raise(err); rb_exc_raise(err);
@ -5454,12 +5458,13 @@ rb_fdopen(int fd, const char *modestr)
file = fdopen(fd, modestr); file = fdopen(fd, modestr);
} }
if (!file) { if (!file) {
int e = errno;
#ifdef _WIN32 #ifdef _WIN32
if (errno == 0) errno = EINVAL; if (e == 0) e = EINVAL;
#elif defined(__sun) #elif defined(__sun)
if (errno == 0) errno = EMFILE; if (e == 0) e = EMFILE;
#endif #endif
rb_sys_fail(0); rb_syserr_fail(e, 0);
} }
} }
@ -5888,8 +5893,8 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
int state; int state;
struct popen_arg arg; struct popen_arg arg;
int e = 0;
#endif #endif
int e = 0;
#if defined(HAVE_SPAWNV) #if defined(HAVE_SPAWNV)
# if defined(HAVE_SPAWNVE) # if defined(HAVE_SPAWNVE)
# define DO_SPAWN(cmd, args, envp) ((args) ? \ # define DO_SPAWN(cmd, args, envp) ((args) ? \
@ -5940,11 +5945,10 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
if (rb_pipe(arg.write_pair) < 0) if (rb_pipe(arg.write_pair) < 0)
rb_sys_fail_str(prog); rb_sys_fail_str(prog);
if (rb_pipe(arg.pair) < 0) { if (rb_pipe(arg.pair) < 0) {
int e = errno; e = errno;
close(arg.write_pair[0]); close(arg.write_pair[0]);
close(arg.write_pair[1]); close(arg.write_pair[1]);
errno = e; rb_syserr_fail_str(e, prog);
rb_sys_fail_str(prog);
} }
if (eargp) { if (eargp) {
rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.write_pair[0])); rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.write_pair[0]));
@ -6027,12 +6031,11 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
close(arg.write_pair[0]); close(arg.write_pair[0]);
close(arg.write_pair[1]); close(arg.write_pair[1]);
} }
errno = e;
# if defined(HAVE_WORKING_FORK) # if defined(HAVE_WORKING_FORK)
if (errmsg[0]) if (errmsg[0])
rb_sys_fail(errmsg); rb_syserr_fail(e, errmsg);
# endif # endif
rb_sys_fail_str(prog); rb_syserr_fail_str(e, prog);
} }
if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) { if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
close(arg.pair[1]); close(arg.pair[1]);
@ -6058,11 +6061,12 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
rb_execarg_run_options(eargp, sargp, NULL, 0); rb_execarg_run_options(eargp, sargp, NULL, 0);
} }
fp = popen(cmd, modestr); fp = popen(cmd, modestr);
e = errno;
if (eargp) { if (eargp) {
rb_execarg_parent_end(execarg_obj); rb_execarg_parent_end(execarg_obj);
rb_execarg_run_options(sargp, NULL, NULL, 0); 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); fd = fileno(fp);
#endif #endif
@ -10688,8 +10692,7 @@ copy_stream_finalize(VALUE arg)
} }
rb_fd_term(&stp->fds); rb_fd_term(&stp->fds);
if (stp->syserr) { if (stp->syserr) {
errno = stp->error_no; rb_syserr_fail(stp->error_no, stp->syserr);
rb_sys_fail(stp->syserr);
} }
if (stp->notimp) { if (stp->notimp) {
rb_raise(rb_eNotImpError, "%s() not implemented", stp->notimp); rb_raise(rb_eNotImpError, "%s() not implemented", stp->notimp);

View file

@ -1061,9 +1061,10 @@ proc_waitall(void)
for (pid = -1;;) { for (pid = -1;;) {
pid = rb_waitpid(-1, &status, 0); pid = rb_waitpid(-1, &status, 0);
if (pid == -1) { if (pid == -1) {
if (errno == ECHILD) int e = errno;
if (e == ECHILD)
break; break;
rb_sys_fail(0); rb_syserr_fail(e, 0);
} }
rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get())); rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
} }
@ -3436,8 +3437,7 @@ disable_child_handler_before_fork(struct child_handler_disabler_state *old)
ret = pthread_sigmask(SIG_SETMASK, &all, &old->sigmask); /* not async-signal-safe */ ret = pthread_sigmask(SIG_SETMASK, &all, &old->sigmask); /* not async-signal-safe */
if (ret != 0) { if (ret != 0) {
errno = ret; rb_syserr_fail(ret, "pthread_sigmask");
rb_sys_fail("pthread_sigmask");
} }
#else #else
# pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" # pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous"
@ -3446,8 +3446,7 @@ disable_child_handler_before_fork(struct child_handler_disabler_state *old)
#ifdef PTHREAD_CANCEL_DISABLE #ifdef PTHREAD_CANCEL_DISABLE
ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old->cancelstate); ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old->cancelstate);
if (ret != 0) { if (ret != 0) {
errno = ret; rb_syserr_fail(ret, "pthread_setcancelstate");
rb_sys_fail("pthread_setcancelstate");
} }
#endif #endif
} }
@ -3460,16 +3459,14 @@ disable_child_handler_fork_parent(struct child_handler_disabler_state *old)
#ifdef PTHREAD_CANCEL_DISABLE #ifdef PTHREAD_CANCEL_DISABLE
ret = pthread_setcancelstate(old->cancelstate, NULL); ret = pthread_setcancelstate(old->cancelstate, NULL);
if (ret != 0) { if (ret != 0) {
errno = ret; rb_syserr_fail(ret, "pthread_setcancelstate");
rb_sys_fail("pthread_setcancelstate");
} }
#endif #endif
#ifdef HAVE_PTHREAD_SIGMASK #ifdef HAVE_PTHREAD_SIGMASK
ret = pthread_sigmask(SIG_SETMASK, &old->sigmask, NULL); /* not async-signal-safe */ ret = pthread_sigmask(SIG_SETMASK, &old->sigmask, NULL); /* not async-signal-safe */
if (ret != 0) { if (ret != 0) {
errno = ret; rb_syserr_fail(ret, "pthread_sigmask");
rb_sys_fail("pthread_sigmask");
} }
#else #else
# pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" # pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous"
@ -5023,9 +5020,10 @@ obj2uid(VALUE id
errno = ERANGE; errno = ERANGE;
/* gepwnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ /* 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)) { 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_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); rb_str_modify_expand(*getpw_tmp, getpw_buf_len);
getpw_buf = RSTRING_PTR(*getpw_tmp); getpw_buf = RSTRING_PTR(*getpw_tmp);
@ -5101,9 +5099,10 @@ obj2gid(VALUE id
errno = ERANGE; errno = ERANGE;
/* gegrnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ /* 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)) { 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_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); rb_str_modify_expand(*getgr_tmp, getgr_buf_len);
getgr_buf = RSTRING_PTR(*getgr_tmp); getgr_buf = RSTRING_PTR(*getgr_tmp);
@ -5494,8 +5493,7 @@ p_uid_change_privilege(VALUE obj, VALUE id)
if (setruid(uid) < 0) rb_sys_fail(0); if (setruid(uid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_44BSD_SETUID #elif defined HAVE_44BSD_SETUID
if (getuid() == uid) { if (getuid() == uid) {
@ -5504,24 +5502,21 @@ p_uid_change_privilege(VALUE obj, VALUE id)
SAVED_USER_ID = uid; SAVED_USER_ID = uid;
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_SETEUID #elif defined HAVE_SETEUID
if (getuid() == uid && SAVED_USER_ID == uid) { if (getuid() == uid && SAVED_USER_ID == uid) {
if (seteuid(uid) < 0) rb_sys_fail(0); if (seteuid(uid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_SETUID #elif defined HAVE_SETUID
if (getuid() == uid && SAVED_USER_ID == uid) { if (getuid() == uid && SAVED_USER_ID == uid) {
if (setuid(uid) < 0) rb_sys_fail(0); if (setuid(uid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#else #else
rb_notimplement(); rb_notimplement();
@ -6200,8 +6195,7 @@ p_gid_change_privilege(VALUE obj, VALUE id)
if (setrgid(gid) < 0) rb_sys_fail(0); if (setrgid(gid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_44BSD_SETGID #elif defined HAVE_44BSD_SETGID
if (getgid() == gid) { if (getgid() == gid) {
@ -6210,24 +6204,21 @@ p_gid_change_privilege(VALUE obj, VALUE id)
SAVED_GROUP_ID = gid; SAVED_GROUP_ID = gid;
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_SETEGID #elif defined HAVE_SETEGID
if (getgid() == gid && SAVED_GROUP_ID == gid) { if (getgid() == gid && SAVED_GROUP_ID == gid) {
if (setegid(gid) < 0) rb_sys_fail(0); if (setegid(gid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#elif defined HAVE_SETGID #elif defined HAVE_SETGID
if (getgid() == gid && SAVED_GROUP_ID == gid) { if (getgid() == gid && SAVED_GROUP_ID == gid) {
if (setgid(gid) < 0) rb_sys_fail(0); if (setgid(gid) < 0) rb_sys_fail(0);
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
#else #else
(void)gid; (void)gid;
@ -6690,8 +6681,7 @@ p_uid_switch(VALUE obj)
} }
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
UNREACHABLE; UNREACHABLE;
@ -6715,8 +6705,7 @@ p_uid_switch(VALUE obj)
euid = geteuid(); euid = geteuid();
if (uid == euid) { if (uid == euid) {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
p_uid_exchange(obj); p_uid_exchange(obj);
if (rb_block_given_p()) { if (rb_block_given_p()) {
@ -6805,8 +6794,7 @@ p_gid_switch(VALUE obj)
} }
} }
else { else {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
UNREACHABLE; UNREACHABLE;
@ -6830,8 +6818,7 @@ p_gid_switch(VALUE obj)
egid = getegid(); egid = getegid();
if (gid == egid) { if (gid == egid) {
errno = EPERM; rb_syserr_fail(EPERM, 0);
rb_sys_fail(0);
} }
p_gid_exchange(obj); p_gid_exchange(obj);
if (rb_block_given_p()) { if (rb_block_given_p()) {
@ -7375,8 +7362,7 @@ rb_clock_gettime(int argc, VALUE *argv)
#endif #endif
} }
/* EINVAL emulates clock_gettime behavior when clock_id is invalid. */ /* EINVAL emulates clock_gettime behavior when clock_id is invalid. */
errno = EINVAL; rb_syserr_fail(EINVAL, 0);
rb_sys_fail(0);
success: success:
return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit); return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
@ -7514,8 +7500,7 @@ rb_clock_getres(int argc, VALUE *argv)
#endif #endif
} }
/* EINVAL emulates clock_getres behavior when clock_id is invalid. */ /* EINVAL emulates clock_getres behavior when clock_id is invalid. */
errno = EINVAL; rb_syserr_fail(EINVAL, 0);
rb_sys_fail(0);
success: success:
if (unit == ID2SYM(id_hertz)) { if (unit == ID2SYM(id_hertz)) {

8
util.c
View file

@ -507,9 +507,10 @@ ruby_getcwd(void)
char *buf = xmalloc(size); char *buf = xmalloc(size);
while (!getcwd(buf, size)) { while (!getcwd(buf, size)) {
if (errno != ERANGE) { int e = errno;
if (e != ERANGE) {
xfree(buf); xfree(buf);
rb_sys_fail("getcwd"); rb_syserr_fail(e, "getcwd");
} }
size *= 2; size *= 2;
buf = xrealloc(buf, size); buf = xrealloc(buf, size);
@ -527,8 +528,9 @@ ruby_getcwd(void)
char *buf = xmalloc(PATH_MAX+1); char *buf = xmalloc(PATH_MAX+1);
if (!getwd(buf)) { if (!getwd(buf)) {
int e = errno;
xfree(buf); xfree(buf);
rb_sys_fail("getwd"); rb_syserr_fail(e, "getwd");
} }
#endif #endif
return buf; return buf;