@@ -162,6 +162,29 @@ static mp_obj_t socket_send(uint n_args, const mp_obj_t *args) {
162162}
163163static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (socket_send_obj , 2 , 3 , socket_send ) ;
164164
165+ static mp_obj_t socket_setsockopt (uint n_args , const mp_obj_t * args ) {
166+ mp_obj_socket_t * self = args [0 ];
167+ int level = MP_OBJ_SMALL_INT_VALUE (args [1 ]);
168+ int option = mp_obj_get_int (args [2 ]);
169+
170+ const void * optval ;
171+ socklen_t optlen ;
172+ if (MP_OBJ_IS_INT (args [3 ])) {
173+ int val = mp_obj_int_get (args [3 ]);
174+ optval = & val ;
175+ optlen = sizeof (val );
176+ } else {
177+ buffer_info_t bufinfo ;
178+ get_buffer (args [3 ], & bufinfo );
179+ optval = bufinfo .buf ;
180+ optlen = bufinfo .len ;
181+ }
182+ int r = setsockopt (self -> fd , level , option , optval , optlen );
183+ RAISE_ERRNO (r , errno );
184+ return mp_const_none ;
185+ }
186+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (socket_setsockopt_obj , 4 , 4 , socket_setsockopt ) ;
187+
165188static mp_obj_t socket_make_new (mp_obj_t type_in , uint n_args , uint n_kw , const mp_obj_t * args ) {
166189 int family = AF_INET ;
167190 int type = SOCK_STREAM ;
@@ -196,6 +219,7 @@ static const mp_method_t rawsocket_type_methods[] = {
196219 { "accept" , & socket_accept_obj },
197220 { "recv" , & socket_recv_obj },
198221 { "send" , & socket_send_obj },
222+ { "setsockopt" , & socket_setsockopt_obj },
199223 { "close" , & socket_close_obj },
200224#if MICROPY_SOCKET_EXTRA
201225 { "recv" , & mp_stream_read_obj },
@@ -299,7 +323,33 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_socket_getaddrinfo_obj, 2, 6, mod
299323
300324extern mp_obj_type_t sockaddr_in_type ;
301325
302- #define STORE_INT_CONST (m , name ) rt_store_attr(m, QSTR_FROM_STR_STATIC(#name), MP_OBJ_NEW_SMALL_INT(name))
326+ #define C (name ) { #name, name }
327+
328+ struct sym_entry {
329+ const char * sym ;
330+ int val ;
331+ } constants [] = {
332+ C (AF_UNIX ),
333+ C (AF_INET ),
334+ C (AF_INET6 ),
335+ C (SOCK_STREAM ),
336+ C (SOCK_DGRAM ),
337+ C (SOCK_RAW ),
338+
339+ C (MSG_DONTROUTE ),
340+ C (MSG_DONTWAIT ),
341+
342+ C (SOL_SOCKET ),
343+ C (SO_BROADCAST ),
344+ C (SO_ERROR ),
345+ C (SO_KEEPALIVE ),
346+ C (SO_LINGER ),
347+ C (SO_REUSEADDR ),
348+
349+ {NULL }
350+ };
351+
352+ #undef C
303353
304354void rawsocket_init () {
305355 mp_obj_t m = mp_obj_new_module (MP_QSTR_rawsocket );
@@ -311,10 +361,7 @@ void rawsocket_init() {
311361 rt_store_attr (m , MP_QSTR_gethostbyname , (mp_obj_t )& mod_socket_gethostbyname_obj );
312362#endif
313363 rt_store_attr (m , MP_QSTR_getaddrinfo , (mp_obj_t )& mod_socket_getaddrinfo_obj );
314- STORE_INT_CONST (m , AF_UNIX );
315- STORE_INT_CONST (m , AF_INET );
316- STORE_INT_CONST (m , AF_INET6 );
317- STORE_INT_CONST (m , SOCK_STREAM );
318- STORE_INT_CONST (m , SOCK_DGRAM );
319- STORE_INT_CONST (m , SOCK_RAW );
364+ for (struct sym_entry * p = constants ; p -> sym != NULL ; p ++ ) {
365+ rt_store_attr (m , QSTR_FROM_STR_STATIC (p -> sym ), MP_OBJ_NEW_SMALL_INT (p -> val ));
366+ }
320367}
0 commit comments