diff --git a/ChangeLog b/ChangeLog index e7b24143e2..e9f36e59dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Wed Dec 23 17:57:45 2015 Nobuyoshi Nakada + + * 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 * string.c: Fix document. Default value of the first diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 94669307c6..fd3f03b6b4 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -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); } diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index 7e3b3070da..cd2582646b 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -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); diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index c54df04038..b19f605232 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -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); @@ -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 @@ -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) { diff --git a/ext/socket/init.c b/ext/socket/init.c index 66da534a58..797e4a185a 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -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); @@ -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: @@ -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); @@ -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: @@ -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); @@ -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: @@ -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); diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 0514bb6502..d71a94a9a8 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -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); diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index 2442bc1d12..f73f12777c 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -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); } } diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 3a14716fef..23c4356f97 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -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 * @@ -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); diff --git a/file.c b/file.c index 073c9c9817..fbb7917d43 100644 --- a/file.c +++ b/file.c @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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)) { @@ -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) @@ -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)); @@ -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); @@ -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); @@ -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 @@ -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); } @@ -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 @@ -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); @@ -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) { diff --git a/io.c b/io.c index faec319a92..976dd8f412 100644 --- a/io.c +++ b/io.c @@ -551,8 +551,9 @@ io_unread(rb_io_t *fptr) } 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) 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, VALUE io, VALUE opts, int nonblock) 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, VALUE str, VALUE ex) 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, VALUE ex) 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, VALUE ex) 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) 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) 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 *modestr, int fmode, convconfig_t *convc #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 *modestr, int fmode, convconfig_t *convc 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 *modestr, int fmode, convconfig_t *convc 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 *modestr, int fmode, convconfig_t *convc 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) } 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); diff --git a/process.c b/process.c index 4826a2e02a..0df7607fd7 100644 --- a/process.c +++ b/process.c @@ -1061,9 +1061,10 @@ proc_waitall(void) 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 child_handler_disabler_state *old) 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 child_handler_disabler_state *old) #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 child_handler_disabler_state *old) #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 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 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 id) 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 id) 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 id) 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 id) 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) } } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } UNREACHABLE; @@ -6715,8 +6705,7 @@ p_uid_switch(VALUE obj) 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) } } else { - errno = EPERM; - rb_sys_fail(0); + rb_syserr_fail(EPERM, 0); } UNREACHABLE; @@ -6830,8 +6818,7 @@ p_gid_switch(VALUE obj) 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) #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) #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)) { diff --git a/util.c b/util.c index 89dec0d19b..95ac2b09b5 100644 --- a/util.c +++ b/util.c @@ -507,9 +507,10 @@ ruby_getcwd(void) 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) 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;