Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion libcc2rs/src/libc_shims/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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<Sockaddr>,
_len: u32,
) -> Option<Box<dyn nix::sys::socket::SockaddrLike>> {
let family = addr.reinterpret_cast::<u16>().read();
if family == ::libc::AF_INET as u16 {
let m = addr.reinterpret_cast::<SockaddrIn>().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::<SockaddrIn6>().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::<SockaddrUn>().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<dyn nix::sys::socket::SockaddrLike>)
} else {
None
}
}

pub fn encode(ss: &nix::sys::socket::SockaddrStorage, out: &Ptr<Sockaddr>, out_len: &Ptr<u32>) {
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::<SockaddrIn>()
.write(SockaddrIn::from_libc(&l));
}
Some(AddressFamily::Inet6) => {
let l = ::libc::sockaddr_in6::from(*ss.as_sockaddr_in6().unwrap());
out.reinterpret_cast::<SockaddrIn6>()
.write(SockaddrIn6::from_libc(&l));
}
_ => {}
}
out_len.write(ss.len());
}
}
101 changes: 101 additions & 0 deletions rules/socket/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,107 @@ fn t3() -> libcc2rs::SockaddrUn {
Default::default()
}

fn f12(a0: i32, a1: Ptr<Sockaddr>, a2: Ptr<u32>) -> i32 {
match nix::sys::socket::getsockname::<nix::sys::socket::SockaddrStorage>(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<Sockaddr>, 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<Sockaddr>, a2: Ptr<u32>) -> i32 {
match nix::sys::socket::getpeername::<nix::sys::socket::SockaddrStorage>(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<Sockaddr>, 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<Sockaddr>, a5: Ptr<u32>) -> isize {
let __buf = a1.reinterpret_cast::<u8>();
match __buf.with_slice_mut(a2, |__s| {
nix::sys::socket::recvfrom::<nix::sys::socket::SockaddrStorage>(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<Sockaddr>, a5: u32) -> isize {
let __buf = a1.reinterpret_cast::<u8>();
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::<u8>();
match __buf.with_slice_mut(a2, |__s| {
Expand Down
55 changes: 55 additions & 0 deletions tests/unit/out/refcount/socket_transparent_union.rs
Original file line number Diff line number Diff line change
@@ -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<i32> = Rc::new(RefCell::new(0));
let ssloc: Value<libcc2rs::SockaddrStorage> = Rc::new(RefCell::new(Default::default()));
let slen: Value<u32> = Rc::new(RefCell::new((128usize as u32)));
assert!(
(((match nix::sys::socket::getsockname::<nix::sys::socket::SockaddrStorage>((*fd.borrow()))
{
Ok(__ss) => {
Sockaddr::encode(
&__ss,
&(ssloc.as_pointer()).reinterpret_cast::<libcc2rs::Sockaddr>(),
&(slen.as_pointer()),
);
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
} == -1_i32) as i32)
!= 0)
);
let sin: Value<libcc2rs::SockaddrIn> = Rc::new(RefCell::new(Default::default()));
let inlen: Value<u32> = Rc::new(RefCell::new((16usize as u32)));
assert!(
(((match nix::sys::socket::getsockname::<nix::sys::socket::SockaddrStorage>((*fd.borrow()))
{
Ok(__ss) => {
Sockaddr::encode(
&__ss,
&(sin.as_pointer()).reinterpret_cast::<libcc2rs::Sockaddr>(),
&(inlen.as_pointer()),
);
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
} == -1_i32) as i32)
!= 0)
);
return 0;
}
2 changes: 1 addition & 1 deletion tests/unit/out/unsafe/stdlib_h.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion tests/unit/socket_transparent_union.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// no-compile: refcount
#define _GNU_SOURCE
#include <assert.h>
#include <netinet/in.h>
Expand Down
Loading