@@ -226,6 +226,48 @@ mod _socket {
226226 #[ pyattr]
227227 use c:: { AF_SYSTEM , PF_SYSTEM , SYSPROTO_CONTROL , TCP_KEEPALIVE } ;
228228
229+ // RFC3542 IPv6 socket options for macOS (netinet6/in6.h)
230+ // Not available in libc, define manually
231+ #[ cfg( target_vendor = "apple" ) ]
232+ #[ pyattr]
233+ const IPV6_RECVHOPLIMIT : i32 = 37 ;
234+ #[ cfg( target_vendor = "apple" ) ]
235+ #[ pyattr]
236+ const IPV6_RECVRTHDR : i32 = 38 ;
237+ #[ cfg( target_vendor = "apple" ) ]
238+ #[ pyattr]
239+ const IPV6_RECVHOPOPTS : i32 = 39 ;
240+ #[ cfg( target_vendor = "apple" ) ]
241+ #[ pyattr]
242+ const IPV6_RECVDSTOPTS : i32 = 40 ;
243+ #[ cfg( target_vendor = "apple" ) ]
244+ #[ pyattr]
245+ const IPV6_USE_MIN_MTU : i32 = 42 ;
246+ #[ cfg( target_vendor = "apple" ) ]
247+ #[ pyattr]
248+ const IPV6_RECVPATHMTU : i32 = 43 ;
249+ #[ cfg( target_vendor = "apple" ) ]
250+ #[ pyattr]
251+ const IPV6_PATHMTU : i32 = 44 ;
252+ #[ cfg( target_vendor = "apple" ) ]
253+ #[ pyattr]
254+ const IPV6_NEXTHOP : i32 = 48 ;
255+ #[ cfg( target_vendor = "apple" ) ]
256+ #[ pyattr]
257+ const IPV6_HOPOPTS : i32 = 49 ;
258+ #[ cfg( target_vendor = "apple" ) ]
259+ #[ pyattr]
260+ const IPV6_DSTOPTS : i32 = 50 ;
261+ #[ cfg( target_vendor = "apple" ) ]
262+ #[ pyattr]
263+ const IPV6_RTHDR : i32 = 51 ;
264+ #[ cfg( target_vendor = "apple" ) ]
265+ #[ pyattr]
266+ const IPV6_RTHDRDSTOPTS : i32 = 57 ;
267+ #[ cfg( target_vendor = "apple" ) ]
268+ #[ pyattr]
269+ const IPV6_RTHDR_TYPE_0 : i32 = 0 ;
270+
229271 #[ cfg( windows) ]
230272 #[ pyattr]
231273 use c:: {
@@ -491,6 +533,7 @@ mod _socket {
491533 target_os = "dragonfly" ,
492534 target_os = "freebsd" ,
493535 target_os = "linux" ,
536+ target_vendor = "apple" ,
494537 windows
495538 ) ) ]
496539 #[ pyattr]
@@ -1597,6 +1640,38 @@ mod _socket {
15971640 Ok ( ( ) )
15981641 }
15991642
1643+ #[ pymethod]
1644+ fn __del__ ( & self , vm : & VirtualMachine ) {
1645+ // Emit ResourceWarning if socket is still open
1646+ if self . sock . read ( ) . is_some ( ) {
1647+ let laddr = if let Ok ( sock) = self . sock ( )
1648+ && let Ok ( addr) = sock. local_addr ( )
1649+ && let Ok ( repr) = get_addr_tuple ( & addr, vm) . repr ( vm)
1650+ {
1651+ format ! ( ", laddr={}" , repr. as_str( ) )
1652+ } else {
1653+ String :: new ( )
1654+ } ;
1655+
1656+ let msg = format ! (
1657+ "unclosed <socket.socket fd={}, family={}, type={}, proto={}{}>" ,
1658+ self . fileno( ) ,
1659+ self . family. load( ) ,
1660+ self . kind. load( ) ,
1661+ self . proto. load( ) ,
1662+ laddr
1663+ ) ;
1664+ let _ = crate :: vm:: warn:: warn (
1665+ vm. ctx . new_str ( msg) ,
1666+ Some ( vm. ctx . exceptions . resource_warning . to_owned ( ) ) ,
1667+ 1 ,
1668+ None ,
1669+ vm,
1670+ ) ;
1671+ }
1672+ let _ = self . close ( ) ;
1673+ }
1674+
16001675 #[ pymethod]
16011676 #[ inline]
16021677 fn detach ( & self ) -> i64 {
0 commit comments