@@ -74,6 +74,10 @@ STATIC const mp_obj_type_t usocket_type;
7474 { if (err_flag == -1) \
7575 { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error_val))); } }
7676
77+ static inline mp_obj_t mp_obj_from_sockaddr (const struct sockaddr * addr , socklen_t len ) {
78+ return mp_obj_new_bytes ((const byte * )addr , len );
79+ }
80+
7781STATIC mp_obj_socket_t * socket_new (int fd ) {
7882 mp_obj_socket_t * o = m_new_obj (mp_obj_socket_t );
7983 o -> base .type = & usocket_type ;
@@ -186,6 +190,33 @@ STATIC mp_obj_t socket_recv(mp_uint_t n_args, const mp_obj_t *args) {
186190}
187191STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (socket_recv_obj , 2 , 3 , socket_recv );
188192
193+ STATIC mp_obj_t socket_recvfrom (mp_uint_t n_args , const mp_obj_t * args ) {
194+ mp_obj_socket_t * self = args [0 ];
195+ int sz = MP_OBJ_SMALL_INT_VALUE (args [1 ]);
196+ int flags = 0 ;
197+
198+ if (n_args > 2 ) {
199+ flags = MP_OBJ_SMALL_INT_VALUE (args [2 ]);
200+ }
201+
202+ struct sockaddr_storage addr ;
203+ socklen_t addr_len = sizeof (addr );
204+
205+ byte * buf = m_new (byte , sz );
206+ int out_sz = recvfrom (self -> fd , buf , sz , flags , (struct sockaddr * )& addr , & addr_len );
207+ RAISE_ERRNO (out_sz , errno );
208+
209+ mp_obj_t buf_o = mp_obj_new_str_of_type (& mp_type_bytes , buf , out_sz );
210+ m_del (char , buf , sz );
211+
212+ mp_obj_tuple_t * t = mp_obj_new_tuple (2 , NULL );
213+ t -> items [0 ] = buf_o ;
214+ t -> items [1 ] = mp_obj_from_sockaddr ((struct sockaddr * )& addr , addr_len );
215+
216+ return t ;
217+ }
218+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (socket_recvfrom_obj , 2 , 3 , socket_recvfrom );
219+
189220// Note: besides flag param, this differs from write() in that
190221// this does not swallow blocking errors (EAGAIN, EWOULDBLOCK) -
191222// these would be thrown as exceptions.
@@ -320,6 +351,7 @@ STATIC const mp_map_elem_t usocket_locals_dict_table[] = {
320351 { MP_OBJ_NEW_QSTR (MP_QSTR_listen ), (mp_obj_t )& socket_listen_obj },
321352 { MP_OBJ_NEW_QSTR (MP_QSTR_accept ), (mp_obj_t )& socket_accept_obj },
322353 { MP_OBJ_NEW_QSTR (MP_QSTR_recv ), (mp_obj_t )& socket_recv_obj },
354+ { MP_OBJ_NEW_QSTR (MP_QSTR_recvfrom ), (mp_obj_t )& socket_recvfrom_obj },
323355 { MP_OBJ_NEW_QSTR (MP_QSTR_send ), (mp_obj_t )& socket_send_obj },
324356 { MP_OBJ_NEW_QSTR (MP_QSTR_sendto ), (mp_obj_t )& socket_sendto_obj },
325357 { MP_OBJ_NEW_QSTR (MP_QSTR_setsockopt ), (mp_obj_t )& socket_setsockopt_obj },
0 commit comments