diff --git a/rules/socket/shim.rs b/rules/socket/shim.rs index d78cedde7..ff5a3953c 100644 --- a/rules/socket/shim.rs +++ b/rules/socket/shim.rs @@ -256,6 +256,23 @@ impl Sockaddr { out.reinterpret_cast::() .write(SockaddrIn6::from_libc(&l)); } + Some(AddressFamily::Unix) => { + if let Some(addr) = ss.as_unix_addr() { + let l: &::libc::sockaddr_un = addr.as_ref(); + let len = out_len.read().min(ss.len()) as usize; + if len != 0 { + let bytes = (::libc::AF_UNIX as u16) + .to_ne_bytes() + .into_iter() + .chain(l.sun_path.iter().map(|&b| b as u8)); + out.reinterpret_cast::().with_slice_mut(len, |buf| { + for (dst, src) in buf.iter_mut().zip(bytes) { + *dst = src; + } + }); + } + } + } _ => {} } out_len.write(ss.len()); diff --git a/tests/unit/out/refcount/socket_unix_name.rs b/tests/unit/out/refcount/socket_unix_name.rs new file mode 100644 index 000000000..8a825a3fa --- /dev/null +++ b/tests/unit/out/refcount/socket_unix_name.rs @@ -0,0 +1,235 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn check_name_0(mut fd: i32, mut path: Ptr) { + let full: Value = Rc::new(RefCell::new(Default::default())); + match ({ ((full.as_pointer()) as Ptr).to_any() },) { + (mut __tmp_0,) => { + __tmp_0.memset((165) as u8, 128usize as usize); + (__tmp_0).clone() + } + }; + let actual: Value = Rc::new(RefCell::new((128usize as libc::socklen_t))); + assert!( + (((match ( + { (full.as_pointer()).reinterpret_cast::() }, + { (actual.as_pointer()) }, + ) { + (mut __tmp_1, mut __tmp_2) => { + match nix::sys::socket::getsockname::(fd) { + Ok(__ss) => { + Sockaddr::encode(&__ss, &__tmp_1, &__tmp_2); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + } + } == 0) as i32) + != 0) + ); + assert!(({ (((({ (*full.borrow()).ss_family } as i32) == 1) as i32) != 0) })); + assert!(({ (((((*actual.borrow()) as usize) >= 2_usize) as i32) != 0) })); + assert!(({ (((((*actual.borrow()) as usize) < 128usize) as i32) != 0) })); + if !(path).is_null() { + assert!( + (((((array_field_ptr!( + ((full.as_pointer()).reinterpret_cast::()), + sun_path + ) as Ptr::) as Ptr) + .to_any() + .memcmp(&(path).to_any(), path.to_c_string_iterator().count()) + == 0) as i32) + != 0) + ); + } + let mut capacities: [libc::socklen_t; 6] = [ + (0 as libc::socklen_t), + (1 as libc::socklen_t), + (2 as libc::socklen_t), + (*actual.borrow()).wrapping_sub((1 as libc::socklen_t)), + (*actual.borrow()), + (*actual.borrow()).wrapping_add((1 as libc::socklen_t)), + ]; + let mut i: u32 = 0_u32; + 'loop_: while ((((i as usize) + < (::std::mem::size_of::<[libc::socklen_t; 6]>() as usize) + .wrapping_div((::std::mem::size_of::() as usize))) + as i32) + != 0) + { + let out: Value> = + Rc::new(RefCell::new((0..136).map(|_| 0_u8).collect::>())); + match ({ ((out.as_pointer() as Ptr) as Ptr).to_any() },) { + (mut __tmp_3,) => { + __tmp_3.memset((165) as u8, ::std::mem::size_of::<[u8; 136]>() as usize); + (__tmp_3).clone() + } + }; + let len: Value = Rc::new(RefCell::new(capacities[(i) as usize])); + assert!( + (((match ( + { (out.as_pointer() as Ptr::).reinterpret_cast::() }, + { (len.as_pointer()) }, + ) { + (mut __tmp_4, mut __tmp_5) => { + match nix::sys::socket::getsockname::(fd) { + Ok(__ss) => { + Sockaddr::encode(&__ss, &__tmp_4, &__tmp_5); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + } + } == 0) as i32) + != 0) + ); + assert!(({ ((((*len.borrow()) == (*actual.borrow())) as i32) != 0) })); + let mut copied: u32 = (if (((capacities[(i) as usize] < (*actual.borrow())) as i32) != 0) { + capacities[(i) as usize] + } else { + (*actual.borrow()) + } as u32); + assert!( + (((((out.as_pointer() as Ptr::) as Ptr) + .to_any() + .memcmp( + &((full.as_pointer()) as Ptr).to_any(), + (copied as usize) + ) + == 0) as i32) + != 0) + ); + let mut j: u32 = copied; + 'loop_: while ((((j as usize) < ::std::mem::size_of::<[u8; 136]>()) as i32) != 0) { + assert!(({ (((((*out.borrow())[(j) as usize] as i32) == 165) as i32) != 0) })); + j.prefix_inc(); + } + i.prefix_inc(); + } +} +pub fn main() { + __cpp2rust_init_globals(); + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let mut fd: i32 = { + let __family = match 1 { + ::libc::AF_INET => nix::sys::socket::AddressFamily::Inet, + ::libc::AF_INET6 => nix::sys::socket::AddressFamily::Inet6, + ::libc::AF_UNIX => nix::sys::socket::AddressFamily::Unix, + __d => panic!("socket: unsupported domain {__d}"), + }; + let __flags = nix::sys::socket::SockFlag::from_bits_truncate(libc::SOCK_DGRAM); + let __ty = match libc::SOCK_DGRAM & !nix::sys::socket::SockFlag::all().bits() { + ::libc::SOCK_STREAM => nix::sys::socket::SockType::Stream, + ::libc::SOCK_DGRAM => nix::sys::socket::SockType::Datagram, + __t => panic!("socket: unsupported type {__t}"), + }; + let __proto = match 0 { + 0 => None, + ::libc::IPPROTO_TCP => Some(nix::sys::socket::SockProtocol::Tcp), + ::libc::IPPROTO_UDP => Some(nix::sys::socket::SockProtocol::Udp), + __p => panic!("socket: unsupported protocol {__p}"), + }; + match nix::sys::socket::socket(__family, __ty, __flags, __proto) { + Ok(__ofd) => FdRegistry::register(__ofd), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }; + assert!((((fd >= 0) as i32) != 0)); + ({ check_name_0(fd, Ptr::::null()) }); + let addr: Value = Rc::new(RefCell::new(Default::default())); + match ({ ((addr.as_pointer()) as Ptr).to_any() },) { + (mut __tmp_6,) => { + __tmp_6.memset((0) as u8, 128usize as usize); + (__tmp_6).clone() + } + }; + let len: Value = Rc::new(RefCell::new((128usize as libc::socklen_t))); + assert!( + (((match ( + { (addr.as_pointer()).reinterpret_cast::() }, + { (len.as_pointer()) }, + ) { + (mut __tmp_7, mut __tmp_8) => { + match nix::sys::socket::getsockname::(fd) { + Ok(__ss) => { + Sockaddr::encode(&__ss, &__tmp_7, &__tmp_8); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + } + } == 0) as i32) + != 0) + ); + let mut un: Ptr = + (addr.as_pointer()).reinterpret_cast::(); + match ({ ((array_field_ptr!(un, sun_path) as Ptr) as Ptr).to_any() },) { + (mut __tmp_9,) => { + __tmp_9.memcpy( + &Ptr::::from_string_literal(b"socket-unix-name").to_any(), + ::std::mem::size_of::<[i8; 17]>() as usize, + ); + (__tmp_9).clone() + } + }; + assert!( + (((match Sockaddr::decode( + &(addr.as_pointer()).reinterpret_cast::(), + (((2_usize as usize).wrapping_add( + (array_field_ptr!(un, sun_path) as Ptr::) + .to_c_string_iterator() + .count() + )) as libc::socklen_t) + ) { + Some(__addr) => match nix::sys::socket::bind(fd, &*__addr) { + Ok(()) => 0, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + }, + None => { + libcc2rs::cpp2rust_errno().write(::libc::EAFNOSUPPORT); + -1 + } + } == 0) as i32) + != 0) + ); + ({ check_name_0(fd, (array_field_ptr!(un, sun_path) as Ptr)) }); + assert!((((FdRegistry::close(fd) == 0) as i32) != 0)); + assert!( + (((match nix::unistd::unlink( + (array_field_ptr!(un, sun_path) as Ptr::) + .to_rust_string() + .as_str() + ) { + Ok(()) => 0, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 0) as i32) + != 0) + ); + return 0; +} +pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/socket_unix_name.rs b/tests/unit/out/unsafe/socket_unix_name.rs new file mode 100644 index 000000000..0b8021426 --- /dev/null +++ b/tests/unit/out/unsafe/socket_unix_name.rs @@ -0,0 +1,202 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn check_name_0(mut fd: i32, mut path: *const libc::c_char) { + let mut full: libc::sockaddr_storage = unsafe { std::mem::zeroed() }; + match ({ ((&mut full as *mut libc::sockaddr_storage) as *mut ::libc::c_void) },) { + (mut __tmp_0,) => { + let byte_0 = __tmp_0 as *mut u8; + for offset in 0..::std::mem::size_of::() { + *byte_0.offset(offset as isize) = 165 as u8; + } + __tmp_0 + } + }; + let mut actual: libc::socklen_t = + (::std::mem::size_of::() as libc::socklen_t); + assert!( + ((((libc::getsockname( + fd, + ((&mut full as *mut libc::sockaddr_storage) as *mut libc::sockaddr), + (&mut actual as *mut libc::socklen_t) + )) == (0)) as i32) + != 0) + ); + assert!(((((full.ss_family as i32) == (1)) as i32) != 0)); + assert!( + ((((actual as usize) >= (::std::mem::offset_of!(libc::sockaddr_un, sun_path))) as i32) + != 0) + ); + assert!( + ((((actual as usize) < (::std::mem::size_of::())) as i32) != 0) + ); + if !(path).is_null() { + assert!( + ((((match ({ libc::strlen(path) },) { + (mut __tmp_1,) => { + { + let sa = core::slice::from_raw_parts( + ((*((&mut full as *mut libc::sockaddr_storage) + as *mut libc::sockaddr_un)) + .sun_path + .as_mut_ptr() as *const ::libc::c_void) + as *const u8, + __tmp_1 as usize, + ); + let sb = core::slice::from_raw_parts( + (path as *const ::libc::c_void) as *const u8, + __tmp_1 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + } + } + }) == (0)) as i32) + != 0) + ); + } + let mut capacities: [libc::socklen_t; 6] = [ + (0 as libc::socklen_t), + (1 as libc::socklen_t), + (2 as libc::socklen_t), + (actual).wrapping_sub((1 as libc::socklen_t)), + actual, + (actual).wrapping_add((1 as libc::socklen_t)), + ]; + let mut i: u32 = 0_u32; + 'loop_: while ((((i as usize) + < ((::std::mem::size_of::<[libc::socklen_t; 6]>() as usize) + .wrapping_div((::std::mem::size_of::() as usize)))) + as i32) + != 0) + { + let mut out: [u8; 136] = [0_u8; 136]; + match ({ (out.as_mut_ptr() as *mut ::libc::c_void) },) { + (mut __tmp_2,) => { + let byte_0 = __tmp_2 as *mut u8; + for offset in 0..::std::mem::size_of::<[u8; 136]>() { + *byte_0.offset(offset as isize) = 165 as u8; + } + __tmp_2 + } + }; + let mut len: libc::socklen_t = capacities[(i) as usize]; + assert!( + ((((libc::getsockname( + fd, + (out.as_mut_ptr() as *mut libc::sockaddr), + (&mut len as *mut libc::socklen_t) + )) == (0)) as i32) + != 0) + ); + assert!(((((len) == (actual)) as i32) != 0)); + let mut copied: u32 = (if ((((capacities[(i) as usize]) < (actual)) as i32) != 0) { + capacities[(i) as usize] + } else { + actual + } as u32); + assert!( + ((((match ({ (copied as usize) },) { + (mut __tmp_3,) => { + { + let sa = core::slice::from_raw_parts( + (out.as_mut_ptr() as *const ::libc::c_void) as *const u8, + __tmp_3 as usize, + ); + let sb = core::slice::from_raw_parts( + ((&mut full as *mut libc::sockaddr_storage) as *const ::libc::c_void) + as *const u8, + __tmp_3 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + } + } + }) == (0)) as i32) + != 0) + ); + let mut j: u32 = copied; + 'loop_: while ((((j as usize) < (::std::mem::size_of::<[u8; 136]>())) as i32) != 0) { + assert!(((((out[(j) as usize] as i32) == (165)) as i32) != 0)); + j.prefix_inc(); + } + i.prefix_inc(); + } +} +pub fn main() { + unsafe { + __cpp2rust_init_globals(); + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut fd: i32 = libc::socket(1, libc::SOCK_DGRAM, 0); + assert!(((((fd) >= (0)) as i32) != 0)); + (unsafe { check_name_0(fd, std::ptr::null()) }); + let mut addr: libc::sockaddr_storage = unsafe { std::mem::zeroed() }; + match ({ ((&mut addr as *mut libc::sockaddr_storage) as *mut ::libc::c_void) },) { + (mut __tmp_4,) => { + let byte_0 = __tmp_4 as *mut u8; + for offset in 0..::std::mem::size_of::() { + *byte_0.offset(offset as isize) = 0 as u8; + } + __tmp_4 + } + }; + let mut len: libc::socklen_t = + (::std::mem::size_of::() as libc::socklen_t); + assert!( + ((((libc::getsockname( + fd, + ((&mut addr as *mut libc::sockaddr_storage) as *mut libc::sockaddr), + (&mut len as *mut libc::socklen_t) + )) == (0)) as i32) + != 0) + ); + let mut un: *mut libc::sockaddr_un = + ((&mut addr as *mut libc::sockaddr_storage) as *mut libc::sockaddr_un); + match ({ ((*un).sun_path.as_mut_ptr() as *mut ::libc::c_void) },) { + (mut __tmp_5,) => { + if ::std::mem::size_of::<[libc::c_char; 17]>() != 0 { + ::std::ptr::copy_nonoverlapping( + (c"socket-unix-name".as_ptr().cast_mut() as *const ::libc::c_void), + __tmp_5, + ::std::mem::size_of::<[libc::c_char; 17]>() as usize, + ) + } + __tmp_5 + } + }; + assert!( + ((((libc::bind( + fd, + ((&mut addr as *mut libc::sockaddr_storage) as *mut libc::sockaddr).cast_const(), + (((::std::mem::offset_of!(libc::sockaddr_un, sun_path) as usize) + .wrapping_add(libc::strlen(((*un).sun_path.as_mut_ptr()).cast_const()))) + as libc::socklen_t) + )) == (0)) as i32) + != 0) + ); + (unsafe { check_name_0(fd, ((*un).sun_path.as_mut_ptr()).cast_const()) }); + assert!(((((libc::close(fd)) == (0)) as i32) != 0)); + assert!(((((libc::unlink(((*un).sun_path.as_mut_ptr()).cast_const())) == (0)) as i32) != 0)); + return 0; +} +pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/socket_unix_name.c b/tests/unit/socket_unix_name.c new file mode 100644 index 000000000..629be9992 --- /dev/null +++ b/tests/unit/socket_unix_name.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +static void check_name(int fd, const char *path) { + struct sockaddr_storage full; + memset(&full, 0xa5, sizeof(full)); + socklen_t actual = sizeof(full); + assert(getsockname(fd, (struct sockaddr *)&full, &actual) == 0); + assert(full.ss_family == AF_UNIX); + assert(actual >= offsetof(struct sockaddr_un, sun_path)); + assert(actual < sizeof(full)); + if (path) + assert(memcmp(((struct sockaddr_un *)&full)->sun_path, path, + strlen(path)) == 0); + + socklen_t capacities[] = {0, 1, 2, actual - 1, actual, actual + 1}; + for (unsigned i = 0; i < sizeof(capacities) / sizeof(capacities[0]); ++i) { + unsigned char out[sizeof(struct sockaddr_storage) + 8]; + memset(out, 0xa5, sizeof(out)); + socklen_t len = capacities[i]; + assert(getsockname(fd, (struct sockaddr *)out, &len) == 0); + assert(len == actual); + unsigned copied = capacities[i] < actual ? capacities[i] : actual; + assert(memcmp(out, &full, copied) == 0); + for (unsigned j = copied; j < sizeof(out); ++j) + assert(out[j] == 0xa5); + } +} + +int main(void) { + int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + assert(fd >= 0); + check_name(fd, NULL); + + struct sockaddr_storage addr; + memset(&addr, 0, sizeof(addr)); + socklen_t len = sizeof(addr); + assert(getsockname(fd, (struct sockaddr *)&addr, &len) == 0); + struct sockaddr_un *un = (struct sockaddr_un *)&addr; + memcpy(un->sun_path, "socket-unix-name", sizeof("socket-unix-name")); + assert(bind(fd, (struct sockaddr *)&addr, + offsetof(struct sockaddr_un, sun_path) + strlen(un->sun_path)) == + 0); + check_name(fd, un->sun_path); + assert(close(fd) == 0); + assert(unlink(un->sun_path) == 0); + return 0; +}