@@ -1696,11 +1696,15 @@ ossl_ssl_setup(VALUE self)
16961696 return Qtrue ;
16971697}
16981698
1699+ static int
1700+ errno_mapped (void )
1701+ {
16991702#ifdef _WIN32
1700- #define ssl_get_error ( ssl , ret ) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1703+ return rb_w32_map_errno (WSAGetLastError ());
17011704#else
1702- #define ssl_get_error ( ssl , ret ) SSL_get_error((ssl), (ret))
1705+ return errno ;
17031706#endif
1707+ }
17041708
17051709static void
17061710write_would_block (int nonblock )
@@ -1741,7 +1745,7 @@ static void
17411745io_wait_writable (VALUE io )
17421746{
17431747#ifdef HAVE_RB_IO_MAYBE_WAIT
1744- if (!rb_io_maybe_wait_writable ( errno , io , RUBY_IO_TIMEOUT_DEFAULT )) {
1748+ if (!rb_io_wait ( io , INT2NUM ( RUBY_IO_WRITABLE ) , RUBY_IO_TIMEOUT_DEFAULT )) {
17451749 rb_raise (IO_TIMEOUT_ERROR , "Timed out while waiting to become writable!" );
17461750 }
17471751#else
@@ -1755,7 +1759,7 @@ static void
17551759io_wait_readable (VALUE io )
17561760{
17571761#ifdef HAVE_RB_IO_MAYBE_WAIT
1758- if (!rb_io_maybe_wait_readable ( errno , io , RUBY_IO_TIMEOUT_DEFAULT )) {
1762+ if (!rb_io_wait ( io , INT2NUM ( RUBY_IO_READABLE ) , RUBY_IO_TIMEOUT_DEFAULT )) {
17591763 rb_raise (IO_TIMEOUT_ERROR , "Timed out while waiting to become readable!" );
17601764 }
17611765#else
@@ -1769,7 +1773,6 @@ static VALUE
17691773ossl_start_ssl (VALUE self , int (* func )(SSL * ), const char * funcname , VALUE opts )
17701774{
17711775 SSL * ssl ;
1772- int ret , ret2 ;
17731776 VALUE cb_state ;
17741777 int nonblock = opts != Qfalse ;
17751778
@@ -1779,7 +1782,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17791782
17801783 VALUE io = rb_attr_get (self , id_i_io );
17811784 for (;;) {
1782- ret = func (ssl );
1785+ int ret = func (ssl );
1786+ int saved_errno = errno_mapped ();
17831787
17841788 cb_state = rb_attr_get (self , ID_callback_state );
17851789 if (!NIL_P (cb_state )) {
@@ -1791,7 +1795,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17911795 if (ret > 0 )
17921796 break ;
17931797
1794- switch ((ret2 = ssl_get_error (ssl , ret ))) {
1798+ int code = SSL_get_error (ssl , ret );
1799+ switch (code ) {
17951800 case SSL_ERROR_WANT_WRITE :
17961801 if (no_exception_p (opts )) { return sym_wait_writable ; }
17971802 write_would_block (nonblock );
@@ -1805,10 +1810,11 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18051810 case SSL_ERROR_SYSCALL :
18061811#ifdef __APPLE__
18071812 /* See ossl_ssl_write_internal() */
1808- if (errno == EPROTOTYPE )
1813+ if (saved_errno == EPROTOTYPE )
18091814 continue ;
18101815#endif
1811- if (errno ) rb_sys_fail (funcname );
1816+ if (saved_errno )
1817+ rb_exc_raise (rb_syserr_new (saved_errno , funcname ));
18121818 /* fallthrough */
18131819 default : {
18141820 VALUE error_append = Qnil ;
@@ -1829,9 +1835,9 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18291835 ossl_raise (eSSLError ,
18301836 "%s%s returned=%d errno=%d peeraddr=%" PRIsVALUE " state=%s%" PRIsVALUE ,
18311837 funcname ,
1832- ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "" ,
1833- ret2 ,
1834- errno ,
1838+ code == SSL_ERROR_SYSCALL ? " SYSCALL" : "" ,
1839+ code ,
1840+ saved_errno ,
18351841 peeraddr_ip_str (self ),
18361842 SSL_state_string_long (ssl ),
18371843 error_append );
@@ -1974,6 +1980,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
19741980 for (;;) {
19751981 rb_str_locktmp (str );
19761982 int nread = SSL_read (ssl , RSTRING_PTR (str ), ilen );
1983+ int saved_errno = errno_mapped ();
19771984 rb_str_unlocktmp (str );
19781985
19791986 cb_state = rb_attr_get (self , ID_callback_state );
@@ -1983,7 +1990,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
19831990 rb_jump_tag (NUM2INT (cb_state ));
19841991 }
19851992
1986- switch (ssl_get_error (ssl , nread )) {
1993+ switch (SSL_get_error (ssl , nread )) {
19871994 case SSL_ERROR_NONE :
19881995 rb_str_set_len (str , nread );
19891996 return str ;
@@ -2006,8 +2013,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20062013 break ;
20072014 case SSL_ERROR_SYSCALL :
20082015 if (!ERR_peek_error ()) {
2009- if (errno )
2010- rb_sys_fail ( 0 );
2016+ if (saved_errno )
2017+ rb_exc_raise ( rb_syserr_new ( saved_errno , "SSL_read" ) );
20112018 else {
20122019 /*
20132020 * The underlying BIO returned 0. This is actually a
@@ -2092,6 +2099,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
20922099
20932100 for (;;) {
20942101 int nwritten = SSL_write (ssl , RSTRING_PTR (str ), num );
2102+ int saved_errno = errno_mapped ();
20952103
20962104 cb_state = rb_attr_get (self , ID_callback_state );
20972105 if (!NIL_P (cb_state )) {
@@ -2100,7 +2108,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
21002108 rb_jump_tag (NUM2INT (cb_state ));
21012109 }
21022110
2103- switch (ssl_get_error (ssl , nwritten )) {
2111+ switch (SSL_get_error (ssl , nwritten )) {
21042112 case SSL_ERROR_NONE :
21052113 return INT2NUM (nwritten );
21062114 case SSL_ERROR_WANT_WRITE :
@@ -2121,10 +2129,11 @@ ossl_ssl_write_internal_safe(VALUE _args)
21212129 * make the error handling in line with the socket library.
21222130 * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
21232131 */
2124- if (errno == EPROTOTYPE )
2132+ if (saved_errno == EPROTOTYPE )
21252133 continue ;
21262134#endif
2127- if (errno ) rb_sys_fail (0 );
2135+ if (saved_errno )
2136+ rb_exc_raise (rb_syserr_new (saved_errno , "SSL_write" ));
21282137 /* fallthrough */
21292138 default :
21302139 ossl_raise (eSSLError , "SSL_write" );
0 commit comments