88 * (See the file 'LICENCE'.)
99 */
1010#include "ossl.h"
11+ #include <openssl/bio.h>
1112
1213BIO *
1314ossl_obj2bio (volatile VALUE * pobj )
@@ -42,7 +43,8 @@ ossl_membio2str(BIO *bio)
4243}
4344
4445BIO_METHOD * ossl_bio_meth ;
45- static int bio_state_idx , bio_errinfo_idx ;
46+ static int bio_state_idx , bio_errinfo_idx , bio_eof_idx ;
47+ static VALUE nonblock_kwargs ;
4648
4749static void
4850bio_save_error (BIO * bio , int state )
@@ -77,8 +79,8 @@ ossl_bio_restore_error(BIO *bio)
7779struct bwrite_args {
7880 BIO * bio ;
7981 const char * data ;
80- size_t dlen ;
81- size_t * written ;
82+ int dlen ;
83+ int written ;
8284};
8385
8486static VALUE
@@ -88,15 +90,12 @@ bio_bwrite0(VALUE args)
8890 VALUE io = (VALUE )BIO_get_data (p -> bio );
8991 BIO_clear_retry_flags (p -> bio );
9092
91- VALUE str = rb_str_new_static (p -> data , p -> dlen );
92- VALUE kwargs = rb_hash_new ();
93- rb_hash_aset (kwargs , ID2SYM (rb_intern ("exception" )), Qfalse );
94- VALUE funcallargs [] = { str , kwargs };
93+ VALUE fargs [] = { rb_str_new_static (p -> data , p -> dlen ), nonblock_kwargs };
9594 VALUE ret = rb_funcallv_public_kw (io , rb_intern ("write_nonblock" ),
96- 2 , funcallargs , RB_PASS_KEYWORDS );
95+ 2 , fargs , RB_PASS_KEYWORDS );
9796
9897 if (RB_INTEGER_TYPE_P (ret )) {
99- * p -> written = NUM2SIZET (ret );
98+ p -> written = NUM2INT (ret );
10099 return INT2FIX (1 );
101100 }
102101 else if (ret == ID2SYM (rb_intern ("wait_readable" ))) {
@@ -114,23 +113,25 @@ bio_bwrite0(VALUE args)
114113}
115114
116115static int
117- bio_bwrite (BIO * bio , const char * data , size_t dlen , size_t * written )
116+ bio_bwrite (BIO * bio , const char * data , int dlen )
118117{
119- struct bwrite_args args = { bio , data , dlen , written };
118+ struct bwrite_args args = { bio , data , dlen , 0 };
120119 int state ;
121120
122121 VALUE ret = rb_protect (bio_bwrite0 , (VALUE )& args , & state );
123122 bio_save_error (bio , state );
124123 if (state )
125124 return 0 ;
126- return FIX2INT (ret );
125+ if (FIX2INT (ret ))
126+ return args .written ;
127+ return -1 ;
127128}
128129
129130struct bread_args {
130131 BIO * bio ;
131132 char * data ;
132- size_t dlen ;
133- size_t * readbytes ;
133+ int dlen ;
134+ int readbytes ;
134135};
135136
136137static VALUE
@@ -140,22 +141,21 @@ bio_bread0(VALUE args)
140141 VALUE io = (VALUE )BIO_get_data (p -> bio );
141142 BIO_clear_retry_flags (p -> bio );
142143
143- VALUE kwargs = rb_hash_new ();
144- rb_hash_aset (kwargs , ID2SYM (rb_intern ("exception" )), Qfalse );
145- VALUE funcallargs [] = { SIZET2NUM (p -> dlen ), kwargs };
144+ VALUE fargs [] = { INT2NUM (p -> dlen ), nonblock_kwargs };
146145 VALUE ret = rb_funcallv_public_kw (io , rb_intern ("read_nonblock" ),
147- 2 , funcallargs , RB_PASS_KEYWORDS );
146+ 2 , fargs , RB_PASS_KEYWORDS );
148147
149148 if (RB_TYPE_P (ret , T_STRING )) {
150- size_t len = ( size_t ) RSTRING_LEN (ret );
149+ int len = RSTRING_LENINT (ret );
151150 if (len > p -> dlen )
152151 rb_raise (rb_eTypeError , "read_nonblock returned too much data" );
153152 memcpy (p -> data , RSTRING_PTR (ret ), len );
154- * p -> readbytes = len ;
153+ p -> readbytes = len ;
155154 return INT2FIX (1 );
156155 }
157156 else if (NIL_P (ret )) {
158- BIO_set_flags (p -> bio , BIO_FLAGS_IN_EOF );
157+ // In OpenSSL 3.0 or later: BIO_set_flags(p->bio, BIO_FLAGS_IN_EOF);
158+ BIO_set_ex_data (p -> bio , bio_eof_idx , (void * )1 );
159159 return INT2FIX (0 );
160160 }
161161 else if (ret == ID2SYM (rb_intern ("wait_readable" ))) {
@@ -173,16 +173,18 @@ bio_bread0(VALUE args)
173173}
174174
175175static int
176- bio_bread (BIO * bio , char * data , size_t dlen , size_t * readbytes )
176+ bio_bread (BIO * bio , char * data , int dlen )
177177{
178- struct bread_args args = { bio , data , dlen , readbytes };
178+ struct bread_args args = { bio , data , dlen , 0 };
179179 int state ;
180180
181181 VALUE ret = rb_protect (bio_bread0 , (VALUE )& args , & state );
182182 bio_save_error (bio , state );
183183 if (state )
184184 return 0 ;
185- return FIX2INT (ret );
185+ if (FIX2INT (ret ))
186+ return args .readbytes ;
187+ return -1 ;
186188}
187189
188190static VALUE
@@ -199,7 +201,7 @@ bio_ctrl(BIO *bio, int cmd, long larg, void *parg)
199201
200202 switch (cmd ) {
201203 case BIO_CTRL_EOF :
202- return BIO_test_flags ( bio , BIO_FLAGS_IN_EOF );
204+ return ( int )( uintptr_t ) BIO_get_ex_data ( bio , bio_eof_idx );
203205 case BIO_CTRL_FLUSH :
204206 rb_protect (bio_flush0 , (VALUE )bio , & state );
205207 bio_save_error (bio , state );
@@ -213,17 +215,22 @@ void
213215Init_ossl_bio (void )
214216{
215217 if ((bio_state_idx = BIO_get_ex_new_index (0 , NULL , NULL , NULL , NULL )) < 0 ||
216- (bio_errinfo_idx = BIO_get_ex_new_index (0 , NULL , NULL , NULL , NULL )) < 0 )
218+ (bio_errinfo_idx = BIO_get_ex_new_index (0 , NULL , NULL , NULL , NULL )) < 0 ||
219+ (bio_eof_idx = BIO_get_ex_new_index (0 , NULL , NULL , NULL , NULL )) < 0 )
217220 ossl_raise (eOSSLError , "BIO_get_ex_new_index" );
218221
219222 ossl_bio_meth = BIO_meth_new (BIO_TYPE_SOURCE_SINK , "Ruby IO-like object" );
220223 if (!ossl_bio_meth )
221224 ossl_raise (eOSSLError , "BIO_meth_new" );
222- if (!BIO_meth_set_write_ex (ossl_bio_meth , bio_bwrite ) ||
223- !BIO_meth_set_read_ex (ossl_bio_meth , bio_bread ) ||
225+ if (!BIO_meth_set_write (ossl_bio_meth , bio_bwrite ) ||
226+ !BIO_meth_set_read (ossl_bio_meth , bio_bread ) ||
224227 !BIO_meth_set_ctrl (ossl_bio_meth , bio_ctrl )) {
225228 BIO_meth_free (ossl_bio_meth );
226229 ossl_bio_meth = NULL ;
227230 ossl_raise (eOSSLError , "BIO_meth_set_*" );
228231 }
232+
233+ nonblock_kwargs = rb_hash_new ();
234+ rb_hash_aset (nonblock_kwargs , ID2SYM (rb_intern ("exception" )), Qfalse );
235+ rb_global_variable (& nonblock_kwargs );
229236}
0 commit comments