11#![ allow( unused_variables, dead_code) ]
22use crate :: path:: Path ;
3- use crate :: { fmt, io} ;
3+ use crate :: sys:: cvt;
4+ use crate :: { fmt, io, mem} ;
45
56pub ( super ) fn sockaddr_un ( path : & Path ) -> io:: Result < ( libc:: sockaddr_un , libc:: socklen_t ) > {
67 Err ( crate :: io:: const_io_error!(
@@ -9,6 +10,13 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s
910 ) )
1011}
1112
13+ fn sun_path_offset ( addr : & libc:: sockaddr_un ) -> usize {
14+ // Work with an actual instance of the type since using a null pointer is UB
15+ let base = ( addr as * const libc:: sockaddr_un ) . addr ( ) ;
16+ let path = ( & addr. sun_path as * const libc:: c_char ) . addr ( ) ;
17+ path - base
18+ }
19+
1220/// An address associated with a Unix socket.
1321///
1422/// Not currently supported on this platform
@@ -20,6 +28,36 @@ pub struct SocketAddr {
2028}
2129
2230impl SocketAddr {
31+ pub ( super ) fn new < F > ( f : F ) -> io:: Result < SocketAddr >
32+ where
33+ F : FnOnce ( * mut libc:: sockaddr , * mut libc:: socklen_t ) -> libc:: c_int ,
34+ {
35+ unsafe {
36+ let mut addr: libc:: sockaddr_un = mem:: zeroed ( ) ;
37+ let mut len = mem:: size_of :: < libc:: sockaddr_un > ( ) as libc:: socklen_t ;
38+ cvt ( f ( & mut addr as * mut _ as * mut _ , & mut len) ) ?;
39+ SocketAddr :: from_parts ( addr, len)
40+ }
41+ }
42+
43+ pub ( super ) fn from_parts (
44+ addr : libc:: sockaddr_un ,
45+ mut len : libc:: socklen_t ,
46+ ) -> io:: Result < SocketAddr > {
47+ if len == 0 {
48+ // When there is a datagram from unnamed unix socket
49+ // linux returns zero bytes of address
50+ len = sun_path_offset ( & addr) as libc:: socklen_t ; // i.e., zero-length address
51+ } else if addr. sun_family != libc:: AF_UNIX as libc:: sa_family_t {
52+ return Err ( io:: const_io_error!(
53+ io:: ErrorKind :: InvalidInput ,
54+ "file descriptor did not correspond to a Unix socket" ,
55+ ) ) ;
56+ }
57+
58+ Ok ( SocketAddr { addr, len } )
59+ }
60+
2361 /// Constructs a `SockAddr` with the family `AF_UNIX` and the provided path.
2462 ///
2563 /// Not currently supported on this platform
0 commit comments