diff --git a/libcc2rs/src/libc_shims/socket.rs b/libcc2rs/src/libc_shims/socket.rs index 954184e9..3b15500a 100644 --- a/libcc2rs/src/libc_shims/socket.rs +++ b/libcc2rs/src/libc_shims/socket.rs @@ -2,7 +2,7 @@ // Distributed under the MIT license that can be found in the LICENSE file. use super::{In6Addr, InAddr}; -use crate::{ByteRepr, Value}; +use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; @@ -77,6 +77,23 @@ impl SockaddrIn { sin_zero, } } + + #[cfg(target_os = "macos")] + pub fn to_libc(&self) -> ::libc::sockaddr_in { + let mut sin_zero = [0i8; 8]; + for (dst, src) in sin_zero.iter_mut().zip(self.sin_zero.borrow().iter()) { + *dst = *src as i8; + } + ::libc::sockaddr_in { + sin_len: ::std::mem::size_of::<::libc::sockaddr_in>() as u8, + sin_family: *self.sin_family.borrow() as u8, + sin_port: *self.sin_port.borrow(), + sin_addr: ::libc::in_addr { + s_addr: *self.sin_addr.borrow().s_addr.borrow(), + }, + sin_zero, + } + } } impl SockaddrIn6 { @@ -119,6 +136,20 @@ impl SockaddrIn6 { sin6_scope_id: *self.sin6_scope_id.borrow(), } } + + #[cfg(target_os = "macos")] + pub fn to_libc(&self) -> ::libc::sockaddr_in6 { + let mut s6_addr = [0u8; 16]; + s6_addr.copy_from_slice(&self.sin6_addr.borrow().s6_addr.borrow()); + ::libc::sockaddr_in6 { + sin6_len: ::std::mem::size_of::<::libc::sockaddr_in6>() as u8, + sin6_family: *self.sin6_family.borrow() as u8, + sin6_port: *self.sin6_port.borrow(), + sin6_flowinfo: *self.sin6_flowinfo.borrow(), + sin6_addr: ::libc::in6_addr { s6_addr }, + sin6_scope_id: *self.sin6_scope_id.borrow(), + } + } } impl Default for Sockaddr { @@ -304,3 +335,46 @@ impl ByteRepr for ::libc::sockaddr_in {} impl ByteRepr for ::libc::sockaddr_in6 {} impl ByteRepr for ::libc::sockaddr_un {} impl ByteRepr for ::libc::sockaddr_storage {} + +impl Sockaddr { + pub fn decode( + addr: &Ptr, + _len: u32, + ) -> Option> { + let family = addr.reinterpret_cast::().read(); + if family == ::libc::AF_INET as u16 { + let m = addr.reinterpret_cast::().read(); + Some(Box::new(nix::sys::socket::SockaddrIn::from(m.to_libc()))) + } else if family == ::libc::AF_INET6 as u16 { + let m = addr.reinterpret_cast::().read(); + Some(Box::new(nix::sys::socket::SockaddrIn6::from(m.to_libc()))) + } else if family == ::libc::AF_UNIX as u16 { + let m = addr.reinterpret_cast::().read(); + let path = m.sun_path.borrow(); + let end = path.iter().position(|&c| c == 0).unwrap_or(path.len()); + nix::sys::socket::UnixAddr::new(&path[..end]) + .ok() + .map(|u| Box::new(u) as Box) + } else { + None + } + } + + pub fn encode(ss: &nix::sys::socket::SockaddrStorage, out: &Ptr, out_len: &Ptr) { + use nix::sys::socket::{AddressFamily, SockaddrLike}; + match ss.family() { + Some(AddressFamily::Inet) => { + let l = ::libc::sockaddr_in::from(*ss.as_sockaddr_in().unwrap()); + out.reinterpret_cast::() + .write(SockaddrIn::from_libc(&l)); + } + Some(AddressFamily::Inet6) => { + let l = ::libc::sockaddr_in6::from(*ss.as_sockaddr_in6().unwrap()); + out.reinterpret_cast::() + .write(SockaddrIn6::from_libc(&l)); + } + _ => {} + } + out_len.write(ss.len()); + } +} diff --git a/rules/socket/tgt_refcount.rs b/rules/socket/tgt_refcount.rs index 5d591a14..67dcb270 100644 --- a/rules/socket/tgt_refcount.rs +++ b/rules/socket/tgt_refcount.rs @@ -15,6 +15,107 @@ fn t3() -> libcc2rs::SockaddrUn { Default::default() } +fn f12(a0: i32, a1: Ptr, a2: Ptr) -> i32 { + match nix::sys::socket::getsockname::(a0) { + Ok(__ss) => { + Sockaddr::encode(&__ss, &a1, &a2); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} + +fn f13(a0: i32, a1: Ptr, a2: u32) -> i32 { + match Sockaddr::decode(&a1, a2) { + Some(__addr) => match nix::sys::socket::connect(a0, &*__addr) { + Ok(()) => 0, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + }, + None => { + libcc2rs::cpp2rust_errno().write(::libc::EAFNOSUPPORT); + -1 + } + } +} + +fn f14(a0: i32, a1: Ptr, a2: Ptr) -> i32 { + match nix::sys::socket::getpeername::(a0) { + Ok(__ss) => { + Sockaddr::encode(&__ss, &a1, &a2); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} + +fn f16(a0: i32, a1: Ptr, a2: u32) -> i32 { + match Sockaddr::decode(&a1, a2) { + Some(__addr) => match nix::sys::socket::bind(a0, &*__addr) { + Ok(()) => 0, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + }, + None => { + libcc2rs::cpp2rust_errno().write(::libc::EAFNOSUPPORT); + -1 + } + } +} + +fn f18(a0: i32, a1: AnyPtr, a2: usize, a3: i32, a4: Ptr, a5: Ptr) -> isize { + let __buf = a1.reinterpret_cast::(); + match __buf.with_slice_mut(a2, |__s| { + nix::sys::socket::recvfrom::(a0, __s) + }) { + Ok((__n, __from)) => { + match __from { + Some(__ss) => Sockaddr::encode(&__ss, &a4, &a5), + None => {} + } + __n as isize + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} + +fn f19(a0: i32, a1: AnyPtr, a2: usize, a3: i32, a4: Ptr, a5: u32) -> isize { + let __buf = a1.reinterpret_cast::(); + match Sockaddr::decode(&a4, a5) { + Some(__addr) => match __buf.with_slice(a2, |__s| { + nix::sys::socket::sendto( + a0, + __s, + &*__addr, + nix::sys::socket::MsgFlags::from_bits_truncate(a3), + ) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + }, + None => { + libcc2rs::cpp2rust_errno().write(::libc::EAFNOSUPPORT); + -1 + } + } +} + fn f9(a0: i32, a1: AnyPtr, a2: usize, a3: i32) -> isize { let __buf = a1.reinterpret_cast::(); match __buf.with_slice_mut(a2, |__s| { diff --git a/tests/unit/out/refcount/socket_transparent_union.rs b/tests/unit/out/refcount/socket_transparent_union.rs new file mode 100644 index 00000000..8ff1ea8c --- /dev/null +++ b/tests/unit/out/refcount/socket_transparent_union.rs @@ -0,0 +1,55 @@ +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 main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let fd: Value = Rc::new(RefCell::new(0)); + let ssloc: Value = Rc::new(RefCell::new(Default::default())); + let slen: Value = Rc::new(RefCell::new((128usize as u32))); + assert!( + (((match nix::sys::socket::getsockname::((*fd.borrow())) + { + Ok(__ss) => { + Sockaddr::encode( + &__ss, + &(ssloc.as_pointer()).reinterpret_cast::(), + &(slen.as_pointer()), + ); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == -1_i32) as i32) + != 0) + ); + let sin: Value = Rc::new(RefCell::new(Default::default())); + let inlen: Value = Rc::new(RefCell::new((16usize as u32))); + assert!( + (((match nix::sys::socket::getsockname::((*fd.borrow())) + { + Ok(__ss) => { + Sockaddr::encode( + &__ss, + &(sin.as_pointer()).reinterpret_cast::(), + &(inlen.as_pointer()), + ); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == -1_i32) as i32) + != 0) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/stdlib_h.rs b/tests/unit/out/unsafe/stdlib_h.rs index 674bcb94..a61ef3ad 100644 --- a/tests/unit/out/unsafe/stdlib_h.rs +++ b/tests/unit/out/unsafe/stdlib_h.rs @@ -70,7 +70,7 @@ pub unsafe fn test_realpath_1() { .is_null()) as i32) != 0) ); - assert!(((((*libcc2rs::cpp2rust_errno_unsafe()) == (2)) as i32) != 0)); + assert!(((((*libcc2rs::cpp2rust_errno_unsafe()) == (libc::ENOENT)) as i32) != 0)); } pub fn main() { unsafe { diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c index 7ee4b865..05cecd69 100644 --- a/tests/unit/socket_transparent_union.c +++ b/tests/unit/socket_transparent_union.c @@ -1,4 +1,3 @@ -// no-compile: refcount #define _GNU_SOURCE #include #include