How do we abstract linux bind from rust libc

Hi,

I have been trying to abstract libc::bind to reduce complexity and use directly in the programs.

Any idea how to get past this error? Any help is appreciated.

error[E0606]: casting &mut sockaddr_un as *const sockaddr is invalid
--> src/socket.rs:54:30
|
54 | ... &mut serv_addr as *const libc::sockaddr,

Code is below,

 pub fn unix_tcp_server(&mut self, path : &mut String, n_conn : u32) -> i32 {
        let mut res : i32 = -1;

        unsafe {
            self.fd = libc::socket(libc::AF_UNIX, libc::SOCK_STREAM, 0);
            if self.fd < 0 {
                res = -1;
            }

            let mut serv_addr = libc::sockaddr_un {
                sun_family : libc::AF_INET as u16,
                sun_path : [0; 108],
            };
            copy_str_to_buf(path, &mut serv_addr.sun_path);

            res = libc::bind(self.fd,
                             &mut serv_addr as *const libc::sockaddr,
                             mem::size_of::<libc::sockaddr_un>().try_into().unwrap());
        }

        res
    }

You can't convert a &mut serv_addr to a *const serv_addr. You need to do &serv_addr as *const serv_addr.

Thanks. I think you mean &serv_addr as *const sockaddr?

I've tried that and now i have got this,

error[E0606]: casting `&sockaddr_un` as `*const sockaddr` is invalid
  --> src/socket.rs:54:30
   |
54 | ...                   &serv_addr as *const libc::sockaddr,
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I think casting between different types does not seem to be valid in rust?

Ah, I see. Since sockaddr_un has a layout compatible to sockaddr and both are repr(C), that means you can use (&serv_addr as *const libc::sockaddr_un).cast() to do the cast.

2 Likes

Compilation works! Thanks very much for your help. I will come back after some testing.