@@ -964,6 +964,48 @@ STATIC mp_obj_t lwip_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
964964}
965965STATIC MP_DEFINE_CONST_FUN_OBJ_2 (lwip_socket_recvfrom_obj , lwip_socket_recvfrom );
966966
967+ STATIC mp_obj_t lwip_socket_sendall (mp_obj_t self_in , mp_obj_t buf_in ) {
968+ lwip_socket_obj_t * socket = self_in ;
969+ lwip_socket_check_connected (socket );
970+
971+ int _errno ;
972+ mp_buffer_info_t bufinfo ;
973+ mp_get_buffer_raise (buf_in , & bufinfo , MP_BUFFER_READ );
974+
975+ mp_uint_t ret = 0 ;
976+ switch (socket -> type ) {
977+ case MOD_NETWORK_SOCK_STREAM : {
978+ if (socket -> timeout == 0 ) {
979+ // Behavior of sendall() for non-blocking sockets isn't explicitly specified.
980+ // But it's specified that "On error, an exception is raised, there is no
981+ // way to determine how much data, if any, was successfully sent." Then, the
982+ // most useful behavior is: check whether we will be able to send all of input
983+ // data without EAGAIN, and if won't be, raise it without sending any.
984+ if (bufinfo .len > tcp_sndbuf (socket -> pcb .tcp )) {
985+ nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError , MP_OBJ_NEW_SMALL_INT (EAGAIN )));
986+ }
987+ }
988+ // TODO: In CPython3.5, socket timeout should apply to the
989+ // entire sendall() operation, not to individual send() chunks.
990+ while (bufinfo .len != 0 ) {
991+ ret = lwip_tcp_send (socket , bufinfo .buf , bufinfo .len , & _errno );
992+ if (ret == -1 ) {
993+ nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError , MP_OBJ_NEW_SMALL_INT (_errno )));
994+ }
995+ bufinfo .len -= ret ;
996+ bufinfo .buf = (char * )bufinfo .buf + ret ;
997+ }
998+ break ;
999+ }
1000+ case MOD_NETWORK_SOCK_DGRAM :
1001+ mp_not_implemented ("" );
1002+ break ;
1003+ }
1004+
1005+ return mp_const_none ;
1006+ }
1007+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (lwip_socket_sendall_obj , lwip_socket_sendall );
1008+
9671009STATIC mp_obj_t lwip_socket_settimeout (mp_obj_t self_in , mp_obj_t timeout_in ) {
9681010 lwip_socket_obj_t * socket = self_in ;
9691011 mp_uint_t timeout ;
@@ -1068,6 +1110,7 @@ STATIC const mp_map_elem_t lwip_socket_locals_dict_table[] = {
10681110 { MP_OBJ_NEW_QSTR (MP_QSTR_recv ), (mp_obj_t )& lwip_socket_recv_obj },
10691111 { MP_OBJ_NEW_QSTR (MP_QSTR_sendto ), (mp_obj_t )& lwip_socket_sendto_obj },
10701112 { MP_OBJ_NEW_QSTR (MP_QSTR_recvfrom ), (mp_obj_t )& lwip_socket_recvfrom_obj },
1113+ { MP_OBJ_NEW_QSTR (MP_QSTR_sendall ), (mp_obj_t )& lwip_socket_sendall_obj },
10711114 { MP_OBJ_NEW_QSTR (MP_QSTR_settimeout ), (mp_obj_t )& lwip_socket_settimeout_obj },
10721115 { MP_OBJ_NEW_QSTR (MP_QSTR_setblocking ), (mp_obj_t )& lwip_socket_setblocking_obj },
10731116 { MP_OBJ_NEW_QSTR (MP_QSTR_setsockopt ), (mp_obj_t )& lwip_socket_setsockopt_obj },
0 commit comments