@@ -276,29 +276,35 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
276
276
}
277
277
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_recvfrom_obj , socket_recvfrom );
278
278
279
+ int _socket_send (socket_obj_t * sock , const char * data , size_t datalen ) {
280
+ int sentlen = 0 ;
281
+ for (int i = 0 ; i < sock -> retries && sentlen < datalen ; i ++ ) {
282
+ int r = lwip_write_r (sock -> fd , data + sentlen , datalen - sentlen );
283
+ if (r < 0 && errno != EWOULDBLOCK ) exception_from_errno (errno );
284
+ if (r > 0 ) sentlen += r ;
285
+ check_for_exceptions ();
286
+ }
287
+ if (sentlen == 0 ) mp_raise_OSError (MP_ETIMEDOUT );
288
+ return sentlen ;
289
+ }
290
+
279
291
STATIC mp_obj_t socket_send (const mp_obj_t arg0 , const mp_obj_t arg1 ) {
280
- socket_obj_t * self = MP_OBJ_TO_PTR (arg0 );
292
+ socket_obj_t * sock = MP_OBJ_TO_PTR (arg0 );
281
293
mp_uint_t datalen ;
282
294
const char * data = mp_obj_str_get_data (arg1 , & datalen );
283
- int x = lwip_write_r (self -> fd , data , datalen );
284
- if (x >= 0 ) return mp_obj_new_int (x );
285
- if (errno == EWOULDBLOCK ) return mp_obj_new_int (0 );
286
- exception_from_errno (errno );
295
+ int r = _socket_send (sock , data , datalen );
296
+ return mp_obj_new_int (r );
287
297
}
288
298
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_send_obj , socket_send );
289
299
290
300
STATIC mp_obj_t socket_sendall (const mp_obj_t arg0 , const mp_obj_t arg1 ) {
291
301
// XXX behaviour when nonblocking (see extmod/modlwip.c)
292
302
// XXX also timeout behaviour.
293
- socket_obj_t * self = MP_OBJ_TO_PTR (arg0 );
303
+ socket_obj_t * sock = MP_OBJ_TO_PTR (arg0 );
294
304
mp_buffer_info_t bufinfo ;
295
305
mp_get_buffer_raise (arg1 , & bufinfo , MP_BUFFER_READ );
296
- while (bufinfo .len != 0 ) {
297
- int ret = lwip_write_r (self -> fd , bufinfo .buf , bufinfo .len );
298
- if (ret < 0 ) exception_from_errno (errno );
299
- bufinfo .len -= ret ;
300
- bufinfo .buf = (char * )bufinfo .buf + ret ;
301
- }
306
+ int r = _socket_send (sock , bufinfo .buf , bufinfo .len );
307
+ if (r < bufinfo .len ) mp_raise_OSError (MP_ETIMEDOUT );
302
308
return mp_const_none ;
303
309
}
304
310
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_sendall_obj , socket_sendall );
@@ -317,12 +323,15 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
317
323
to .sin_port = lwip_htons (netutils_parse_inet_addr (addr_in , (uint8_t * )& to .sin_addr , NETUTILS_BIG ));
318
324
319
325
// send the data
320
- int ret = lwip_sendto_r (self -> fd , bufinfo .buf , bufinfo .len , 0 , (struct sockaddr * )& to , sizeof (to ));
321
- if (ret == -1 ) {
322
- exception_from_errno (errno );
326
+ for (int i = 0 ; i < self -> retries ; i ++ ) {
327
+ int ret = lwip_sendto_r (self -> fd , bufinfo .buf , bufinfo .len , 0 , (struct sockaddr * )& to , sizeof (to ));
328
+ if (ret > 0 ) return mp_obj_new_int_from_uint (ret );
329
+ if (ret == -1 && errno != EWOULDBLOCK ) {
330
+ exception_from_errno (errno );
331
+ }
332
+ check_for_exceptions ();
323
333
}
324
-
325
- return mp_obj_new_int_from_uint (ret );
334
+ mp_raise_OSError (MP_ETIMEDOUT );
326
335
}
327
336
STATIC MP_DEFINE_CONST_FUN_OBJ_3 (socket_sendto_obj , socket_sendto );
328
337
@@ -357,12 +366,14 @@ STATIC mp_uint_t socket_stream_read(mp_obj_t self_in, void *buf, mp_uint_t size,
357
366
}
358
367
359
368
STATIC mp_uint_t socket_stream_write (mp_obj_t self_in , const void * buf , mp_uint_t size , int * errcode ) {
360
- socket_obj_t * socket = self_in ;
361
- int x = lwip_write_r (socket -> fd , buf , size );
362
- if (x >= 0 ) return x ;
363
- if (errno == EWOULDBLOCK ) return 0 ;
364
- * errcode = MP_EIO ;
365
- return MP_STREAM_ERROR ;
369
+ socket_obj_t * sock = self_in ;
370
+ for (int i = 0 ; i < sock -> retries ; i ++ ) {
371
+ int r = lwip_write_r (sock -> fd , buf , size );
372
+ if (r > 0 ) return r ;
373
+ if (r < 0 && errno != EWOULDBLOCK ) { * errcode = errno ; return MP_STREAM_ERROR ; }
374
+ check_for_exceptions ();
375
+ }
376
+ return 0 ;
366
377
}
367
378
368
379
STATIC mp_uint_t socket_stream_ioctl (mp_obj_t self_in , mp_uint_t request , uintptr_t arg , int * errcode ) {
0 commit comments