|
37 | 37 | #include "py/mperrno.h"
|
38 | 38 |
|
39 | 39 | #include "shared/netutils/netutils.h"
|
| 40 | +#include "shared/runtime/interrupt_char.h" |
40 | 41 |
|
41 | 42 | //| class Socket:
|
42 | 43 | //| """TCP, UDP and RAW socket. Cannot be created directly. Instead, call
|
@@ -255,6 +256,46 @@ STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
255 | 256 | }
|
256 | 257 | STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send);
|
257 | 258 |
|
| 259 | +//| def sendall(self, bytes: ReadableBuffer) -> None: |
| 260 | +//| """Send some bytes to the connected remote address. |
| 261 | +//| Suits sockets of type SOCK_STREAM |
| 262 | +//| |
| 263 | +//| This calls send() repeatedly until all the data is sent or an error |
| 264 | +//| occurs. If an error occurs, it's impossible to tell how much data |
| 265 | +//| has been sent. |
| 266 | +//| |
| 267 | +//| :param ~bytes bytes: some bytes to send""" |
| 268 | +//| ... |
| 269 | +STATIC mp_obj_t _socketpool_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) { |
| 270 | + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 271 | + if (common_hal_socketpool_socket_get_closed(self)) { |
| 272 | + // Bad file number. |
| 273 | + mp_raise_OSError(MP_EBADF); |
| 274 | + } |
| 275 | + if (!common_hal_socketpool_socket_get_connected(self)) { |
| 276 | + mp_raise_BrokenPipeError(); |
| 277 | + } |
| 278 | + mp_buffer_info_t bufinfo; |
| 279 | + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); |
| 280 | + while (bufinfo.len > 0) { |
| 281 | + mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len); |
| 282 | + if (ret == -1) { |
| 283 | + mp_raise_BrokenPipeError(); |
| 284 | + } |
| 285 | + bufinfo.len -= ret; |
| 286 | + bufinfo.buf += ret; |
| 287 | + if (bufinfo.len > 0) { |
| 288 | + RUN_BACKGROUND_TASKS; |
| 289 | + // Allow user to break out of sendall with a KeyboardInterrupt. |
| 290 | + if (mp_hal_is_interrupted()) { |
| 291 | + return 0; |
| 292 | + } |
| 293 | + } |
| 294 | + } |
| 295 | + return mp_const_none; |
| 296 | +} |
| 297 | +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_socket_sendall); |
| 298 | + |
258 | 299 | //| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int:
|
259 | 300 | //| """Send some bytes to a specific address.
|
260 | 301 | //| Suits sockets of type SOCK_DGRAM
|
@@ -372,6 +413,7 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = {
|
372 | 413 | { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) },
|
373 | 414 | { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) },
|
374 | 415 | { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) },
|
| 416 | + { MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&socketpool_socket_sendall_obj) }, |
375 | 417 | { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) },
|
376 | 418 | { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) },
|
377 | 419 | // { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) },
|
|
0 commit comments