@@ -1590,26 +1590,24 @@ ossl_ssl_s_alloc(VALUE klass)
15901590}
15911591
15921592static VALUE
1593- peer_ip_address (VALUE self )
1593+ peer_ip_address (VALUE io )
15941594{
1595- VALUE remote_address = rb_funcall (rb_attr_get ( self , id_i_io ) , rb_intern ("remote_address" ), 0 );
1595+ VALUE remote_address = rb_funcall (io , rb_intern ("remote_address" ), 0 );
15961596
15971597 return rb_funcall (remote_address , rb_intern ("inspect_sockaddr" ), 0 );
15981598}
15991599
16001600static VALUE
1601- fallback_peer_ip_address (VALUE self , VALUE args )
1601+ fallback_peer_ip_address (VALUE self , VALUE exc )
16021602{
16031603 return rb_str_new_cstr ("(null)" );
16041604}
16051605
16061606static VALUE
1607- peeraddr_ip_str (VALUE self )
1607+ peeraddr_ip_str (VALUE io )
16081608{
1609- VALUE rb_mErrno = rb_const_get (rb_cObject , rb_intern ("Errno" ));
1610- VALUE rb_eSystemCallError = rb_const_get (rb_mErrno , rb_intern ("SystemCallError" ));
1611-
1612- return rb_rescue2 (peer_ip_address , self , fallback_peer_ip_address , (VALUE )0 , rb_eSystemCallError , NULL );
1609+ return rb_rescue2 (peer_ip_address , io , fallback_peer_ip_address , Qnil ,
1610+ rb_eSystemCallError , (VALUE )0 );
16131611}
16141612
16151613/*
@@ -1714,11 +1712,15 @@ ossl_ssl_setup(VALUE self)
17141712 return Qtrue ;
17151713}
17161714
1715+ static int
1716+ errno_mapped (void )
1717+ {
17171718#ifdef _WIN32
1718- #define ssl_get_error ( ssl , ret ) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1719+ return rb_w32_map_errno (WSAGetLastError ());
17191720#else
1720- #define ssl_get_error ( ssl , ret ) SSL_get_error((ssl), (ret))
1721+ return errno ;
17211722#endif
1723+ }
17221724
17231725static void
17241726write_would_block (int nonblock )
@@ -1759,35 +1761,34 @@ static void
17591761io_wait_writable (VALUE io )
17601762{
17611763#ifdef HAVE_RB_IO_MAYBE_WAIT
1762- if (!rb_io_maybe_wait_writable ( errno , io , RUBY_IO_TIMEOUT_DEFAULT )) {
1764+ if (!rb_io_wait ( io , INT2NUM ( RUBY_IO_WRITABLE ) , RUBY_IO_TIMEOUT_DEFAULT )) {
17631765 rb_raise (IO_TIMEOUT_ERROR , "Timed out while waiting to become writable!" );
17641766 }
17651767#else
17661768 rb_io_t * fptr ;
17671769 GetOpenFile (io , fptr );
1768- rb_io_wait_writable (fptr -> fd );
1770+ rb_thread_fd_writable (fptr -> fd );
17691771#endif
17701772}
17711773
17721774static void
17731775io_wait_readable (VALUE io )
17741776{
17751777#ifdef HAVE_RB_IO_MAYBE_WAIT
1776- if (!rb_io_maybe_wait_readable ( errno , io , RUBY_IO_TIMEOUT_DEFAULT )) {
1778+ if (!rb_io_wait ( io , INT2NUM ( RUBY_IO_READABLE ) , RUBY_IO_TIMEOUT_DEFAULT )) {
17771779 rb_raise (IO_TIMEOUT_ERROR , "Timed out while waiting to become readable!" );
17781780 }
17791781#else
17801782 rb_io_t * fptr ;
17811783 GetOpenFile (io , fptr );
1782- rb_io_wait_readable (fptr -> fd );
1784+ rb_thread_wait_fd (fptr -> fd );
17831785#endif
17841786}
17851787
17861788static VALUE
17871789ossl_start_ssl (VALUE self , int (* func )(SSL * ), const char * funcname , VALUE opts )
17881790{
17891791 SSL * ssl ;
1790- int ret , ret2 ;
17911792 VALUE cb_state ;
17921793 int nonblock = opts != Qfalse ;
17931794
@@ -1797,7 +1798,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17971798
17981799 VALUE io = rb_attr_get (self , id_i_io );
17991800 for (;;) {
1800- ret = func (ssl );
1801+ int ret = func (ssl );
1802+ int saved_errno = errno_mapped ();
18011803
18021804 cb_state = rb_attr_get (self , ID_callback_state );
18031805 if (!NIL_P (cb_state )) {
@@ -1809,7 +1811,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18091811 if (ret > 0 )
18101812 break ;
18111813
1812- switch ((ret2 = ssl_get_error (ssl , ret ))) {
1814+ int code = SSL_get_error (ssl , ret );
1815+ switch (code ) {
18131816 case SSL_ERROR_WANT_WRITE :
18141817 if (no_exception_p (opts )) { return sym_wait_writable ; }
18151818 write_would_block (nonblock );
@@ -1823,10 +1826,11 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18231826 case SSL_ERROR_SYSCALL :
18241827#ifdef __APPLE__
18251828 /* See ossl_ssl_write_internal() */
1826- if (errno == EPROTOTYPE )
1829+ if (saved_errno == EPROTOTYPE )
18271830 continue ;
18281831#endif
1829- if (errno ) rb_sys_fail (funcname );
1832+ if (saved_errno )
1833+ rb_exc_raise (rb_syserr_new (saved_errno , funcname ));
18301834 /* fallthrough */
18311835 default : {
18321836 VALUE error_append = Qnil ;
@@ -1847,10 +1851,10 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18471851 ossl_raise (eSSLError ,
18481852 "%s%s returned=%d errno=%d peeraddr=%" PRIsVALUE " state=%s%" PRIsVALUE ,
18491853 funcname ,
1850- ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "" ,
1851- ret2 ,
1852- errno ,
1853- peeraddr_ip_str (self ),
1854+ code == SSL_ERROR_SYSCALL ? " SYSCALL" : "" ,
1855+ code ,
1856+ saved_errno ,
1857+ peeraddr_ip_str (io ),
18541858 SSL_state_string_long (ssl ),
18551859 error_append );
18561860 }
@@ -1992,6 +1996,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
19921996 for (;;) {
19931997 rb_str_locktmp (str );
19941998 int nread = SSL_read (ssl , RSTRING_PTR (str ), ilen );
1999+ int saved_errno = errno_mapped ();
19952000 rb_str_unlocktmp (str );
19962001
19972002 cb_state = rb_attr_get (self , ID_callback_state );
@@ -2001,7 +2006,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20012006 rb_jump_tag (NUM2INT (cb_state ));
20022007 }
20032008
2004- switch (ssl_get_error (ssl , nread )) {
2009+ switch (SSL_get_error (ssl , nread )) {
20052010 case SSL_ERROR_NONE :
20062011 rb_str_set_len (str , nread );
20072012 return str ;
@@ -2024,8 +2029,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20242029 break ;
20252030 case SSL_ERROR_SYSCALL :
20262031 if (!ERR_peek_error ()) {
2027- if (errno )
2028- rb_sys_fail ( 0 );
2032+ if (saved_errno )
2033+ rb_exc_raise ( rb_syserr_new ( saved_errno , "SSL_read" ) );
20292034 else {
20302035 /*
20312036 * The underlying BIO returned 0. This is actually a
@@ -2110,6 +2115,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
21102115
21112116 for (;;) {
21122117 int nwritten = SSL_write (ssl , RSTRING_PTR (str ), num );
2118+ int saved_errno = errno_mapped ();
21132119
21142120 cb_state = rb_attr_get (self , ID_callback_state );
21152121 if (!NIL_P (cb_state )) {
@@ -2118,7 +2124,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
21182124 rb_jump_tag (NUM2INT (cb_state ));
21192125 }
21202126
2121- switch (ssl_get_error (ssl , nwritten )) {
2127+ switch (SSL_get_error (ssl , nwritten )) {
21222128 case SSL_ERROR_NONE :
21232129 return INT2NUM (nwritten );
21242130 case SSL_ERROR_WANT_WRITE :
@@ -2139,10 +2145,11 @@ ossl_ssl_write_internal_safe(VALUE _args)
21392145 * make the error handling in line with the socket library.
21402146 * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
21412147 */
2142- if (errno == EPROTOTYPE )
2148+ if (saved_errno == EPROTOTYPE )
21432149 continue ;
21442150#endif
2145- if (errno ) rb_sys_fail (0 );
2151+ if (saved_errno )
2152+ rb_exc_raise (rb_syserr_new (saved_errno , "SSL_write" ));
21462153 /* fallthrough */
21472154 default :
21482155 ossl_raise (eSSLError , "SSL_write" );
0 commit comments