Skip to content

Commit b178dcc

Browse files
committed
unix: modsocket: Implement recvfrom().
Required to implement UDP servers.
1 parent 3b83aeb commit b178dcc

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

unix/modsocket.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
7781
STATIC 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
}
187191
STATIC 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 },

unix/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Q(bind)
7070
Q(listen)
7171
Q(accept)
7272
Q(recv)
73+
Q(recvfrom)
7374
Q(sendto)
7475
Q(setsockopt)
7576
Q(setblocking)

0 commit comments

Comments
 (0)