@@ -244,6 +244,22 @@ pub fn test_abstract_uds_addr() {
244244 assert_eq ! ( unsafe { ( * addr. as_ptr( ) ) . sun_path[ 0 ] } , 0 ) ;
245245}
246246
247+ // Test getting an unnamed address (without unix socket creation)
248+ #[ test]
249+ pub fn test_unnamed_uds_addr ( ) {
250+ use crate :: nix:: sys:: socket:: SockaddrLike ;
251+
252+ let addr = UnixAddr :: new_unnamed ( ) ;
253+
254+ assert ! ( addr. is_unnamed( ) ) ;
255+ assert_eq ! ( addr. len( ) , 2 ) ;
256+ assert ! ( addr. path( ) . is_none( ) ) ;
257+ assert_eq ! ( addr. path_len( ) , 0 ) ;
258+
259+ #[ cfg( target_os = "linux" ) ]
260+ assert ! ( addr. as_abstract( ) . is_none( ) ) ;
261+ }
262+
247263#[ test]
248264pub fn test_getsockname ( ) {
249265 use nix:: sys:: socket:: bind;
@@ -1484,7 +1500,7 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
14841500
14851501// Test creating and using named unix domain sockets
14861502#[ test]
1487- pub fn test_unixdomain ( ) {
1503+ pub fn test_named_unixdomain ( ) {
14881504 use nix:: sys:: socket:: { accept, bind, connect, listen, socket, UnixAddr } ;
14891505 use nix:: sys:: socket:: { SockFlag , SockType } ;
14901506 use nix:: unistd:: { close, read, write} ;
@@ -1527,6 +1543,59 @@ pub fn test_unixdomain() {
15271543 assert_eq ! ( & buf[ ..] , b"hello" ) ;
15281544}
15291545
1546+ // Test using unnamed unix domain addresses
1547+ #[ test]
1548+ pub fn test_unnamed_unixdomain ( ) {
1549+ use nix:: sys:: socket:: { getsockname, socketpair} ;
1550+ use nix:: sys:: socket:: { SockFlag , SockType } ;
1551+ use nix:: unistd:: close;
1552+
1553+ let ( fd_1, fd_2) = socketpair (
1554+ AddressFamily :: Unix ,
1555+ SockType :: Stream ,
1556+ None ,
1557+ SockFlag :: empty ( ) ,
1558+ )
1559+ . expect ( "socketpair failed" ) ;
1560+
1561+ let addr_1: UnixAddr = getsockname ( fd_1) . expect ( "getsockname failed" ) ;
1562+ assert ! ( addr_1. is_unnamed( ) ) ;
1563+ assert_eq ! ( addr_1, UnixAddr :: new_unnamed( ) ) ;
1564+
1565+ close ( fd_1) . unwrap ( ) ;
1566+ close ( fd_2) . unwrap ( ) ;
1567+ }
1568+
1569+ // Test creating and using unnamed unix domain addresses for autobinding sockets
1570+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1571+ #[ test]
1572+ pub fn test_unnamed_unixdomain_autobind ( ) {
1573+ use nix:: sys:: socket:: { bind, getsockname, socket} ;
1574+ use nix:: sys:: socket:: { SockFlag , SockType } ;
1575+ use nix:: unistd:: close;
1576+
1577+ let fd = socket (
1578+ AddressFamily :: Unix ,
1579+ SockType :: Stream ,
1580+ SockFlag :: empty ( ) ,
1581+ None ,
1582+ )
1583+ . expect ( "socket failed" ) ;
1584+
1585+ // unix(7): "If a bind(2) call specifies addrlen as `sizeof(sa_family_t)`, or [...], then the
1586+ // socket is autobound to an abstract address"
1587+ bind ( fd, & UnixAddr :: new_unnamed ( ) ) . expect ( "bind failed" ) ;
1588+
1589+ let addr: UnixAddr = getsockname ( fd) . expect ( "getsockname failed" ) ;
1590+ let addr = addr. as_abstract ( ) . unwrap ( ) ;
1591+
1592+ // changed from 8 to 5 bytes in Linux 2.3.15, and rust's minimum supported Linux version is 3.2
1593+ // (as of 2022-11)
1594+ assert_eq ! ( addr. len( ) , 5 ) ;
1595+
1596+ close ( fd) . unwrap ( ) ;
1597+ }
1598+
15301599// Test creating and using named system control sockets
15311600#[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
15321601#[ test]
0 commit comments