@@ -397,6 +397,38 @@ fn build_stream_socket(
397397 Ok ( sock. unbind ( ) )
398398}
399399
400+ #[ cfg( unix) ]
401+ fn set_socket_bool_option_unix (
402+ py : Python < ' _ > ,
403+ sock : & Py < PyAny > ,
404+ level : libc:: c_int ,
405+ option : libc:: c_int ,
406+ enabled : bool ,
407+ ) -> PyResult < ( ) > {
408+ let fd = fd_ops:: fileobj_to_fd ( py, sock. bind ( py) ) ?;
409+ let fd: libc:: c_int = fd
410+ . try_into ( )
411+ . map_err ( |_| PyRuntimeError :: new_err ( "socket file descriptor out of range" ) ) ?;
412+ let value: libc:: c_int = enabled. into ( ) ;
413+ let value_len: libc:: socklen_t = std:: mem:: size_of_val ( & value)
414+ . try_into ( )
415+ . expect ( "socklen_t can represent c_int size" ) ;
416+ let result = unsafe {
417+ libc:: setsockopt (
418+ fd,
419+ level,
420+ option,
421+ ( & value as * const libc:: c_int ) . cast ( ) ,
422+ value_len,
423+ )
424+ } ;
425+ if result == 0 {
426+ Ok ( ( ) )
427+ } else {
428+ Err ( PyErr :: from ( std:: io:: Error :: last_os_error ( ) ) )
429+ }
430+ }
431+
400432async fn connect_socket_to_address ( sock : Py < PyAny > , address : Py < PyAny > ) -> PyResult < ( ) > {
401433 let fd = Python :: attach ( |py| fd_ops:: fileobj_to_fd ( py, sock. bind ( py) ) ) ?;
402434 match Python :: attach ( |py| -> PyResult < ( ) > {
@@ -524,6 +556,7 @@ fn build_tcp_server_sockets(
524556 let sol_socket = socket_mod. getattr ( "SOL_SOCKET" ) ?;
525557 let so_reuseaddr = socket_mod. getattr ( "SO_REUSEADDR" ) ?;
526558 let so_reuseport = socket_mod. getattr ( "SO_REUSEPORT" ) . ok ( ) ;
559+ #[ cfg( not( unix) ) ]
527560 let so_keepalive = socket_mod. getattr ( "SO_KEEPALIVE" ) ?;
528561 let addrinfos = resolve_stream_addrinfos ( py, host, port, family, 0 , flags) ?;
529562 let mut sockets = Vec :: with_capacity ( addrinfos. len ( ) ) ;
@@ -547,15 +580,28 @@ fn build_tcp_server_sockets(
547580 }
548581 }
549582 if let Some ( keep_alive) = keep_alive {
550- sock. call_method1 (
551- py,
552- "setsockopt" ,
553- (
554- sol_socket. clone ( ) ,
555- so_keepalive. clone ( ) ,
556- i32:: from ( keep_alive) ,
557- ) ,
558- ) ?;
583+ #[ cfg( unix) ]
584+ {
585+ set_socket_bool_option_unix (
586+ py,
587+ & sock,
588+ libc:: SOL_SOCKET ,
589+ libc:: SO_KEEPALIVE ,
590+ keep_alive,
591+ ) ?;
592+ }
593+ #[ cfg( not( unix) ) ]
594+ {
595+ sock. call_method1 (
596+ py,
597+ "setsockopt" ,
598+ (
599+ sol_socket. clone ( ) ,
600+ so_keepalive. clone ( ) ,
601+ i32:: from ( keep_alive) ,
602+ ) ,
603+ ) ?;
604+ }
559605 }
560606 sock. call_method1 ( py, "bind" , ( sockaddr, ) ) ?;
561607 sock. call_method1 ( py, "listen" , ( backlog, ) ) ?;
0 commit comments