diff --git a/libcc2rs/src/fd.rs b/libcc2rs/src/fd.rs index 91c2d420..64bfb795 100644 --- a/libcc2rs/src/fd.rs +++ b/libcc2rs/src/fd.rs @@ -27,15 +27,26 @@ impl FdRegistry { raw } + fn lookup(&self, fd: i32) -> BorrowedFd<'_> { + self.fds + .get(fd as usize) + .and_then(|slot| slot.as_ref()) + .unwrap_or_else(|| panic!("ub: bad fd {fd}")) + .as_fd() + } + pub fn with_fd(fd: i32, f: impl FnOnce(BorrowedFd<'_>) -> R) -> R { FD_REGISTRY.with(|r| { let reg = r.borrow(); - let owned = reg - .fds - .get(fd as usize) - .and_then(|slot| slot.as_ref()) - .unwrap_or_else(|| panic!("ub: bad fd {fd}")); - f(owned.as_fd()) + f(reg.lookup(fd)) + }) + } + + pub fn with_fds(fds: &[i32], f: impl FnOnce(&[BorrowedFd<'_>]) -> R) -> R { + FD_REGISTRY.with(|r| { + let reg = r.borrow(); + let borrowed: Vec> = fds.iter().map(|&fd| reg.lookup(fd)).collect(); + f(&borrowed) }) } diff --git a/libcc2rs/src/libc_shims/time.rs b/libcc2rs/src/libc_shims/time.rs index e958b3c4..a1e6fd5c 100644 --- a/libcc2rs/src/libc_shims/time.rs +++ b/libcc2rs/src/libc_shims/time.rs @@ -89,7 +89,23 @@ impl Clone for Timeval { } } -impl ByteRepr for Timeval {} +impl ByteRepr for Timeval { + fn byte_size() -> usize { + 16 + } + + fn to_bytes(&self, buf: &mut [u8]) { + (*self.tv_sec.borrow()).to_bytes(&mut buf[0..8]); + (*self.tv_usec.borrow()).to_bytes(&mut buf[8..16]); + } + + fn from_bytes(buf: &[u8]) -> Self { + Self { + tv_sec: Rc::new(RefCell::new(i64::from_bytes(&buf[0..8]))), + tv_usec: Rc::new(RefCell::new(i64::from_bytes(&buf[8..16]))), + } + } +} #[derive(Default)] pub struct Timespec { diff --git a/rules/poll/src.cpp b/rules/poll/src.cpp index 58f5b7dd..301310a4 100644 --- a/rules/poll/src.cpp +++ b/rules/poll/src.cpp @@ -4,6 +4,7 @@ #include typedef struct pollfd t1; +typedef nfds_t t2; int f1(struct pollfd *fds, nfds_t nfds, int timeout) { return poll(fds, nfds, timeout); diff --git a/rules/poll/tgt_refcount.rs b/rules/poll/tgt_refcount.rs index d8302a1e..f8b37af6 100644 --- a/rules/poll/tgt_refcount.rs +++ b/rules/poll/tgt_refcount.rs @@ -6,3 +6,52 @@ use libcc2rs::*; fn t1() -> libcc2rs::Pollfd { Default::default() } + +fn f1(a0: Ptr, a1: u64, a2: i32) -> i32 { + let __p = a0.clone(); + let __timeout = match nix::poll::PollTimeout::try_from(a2) { + Ok(__t) => __t, + Err(_) => panic!("poll: unsupported timeout {}", a2), + }; + let mut __idx = Vec::new(); + let mut __wanted = Vec::new(); + let mut __events = Vec::new(); + for __i in 0..(a1 as usize) { + let (__fd, __ev) = __p + .offset(__i) + .with(|__e| (*__e.fd.borrow(), *__e.events.borrow())); + __p.offset(__i) + .with_mut(|__e| *__e.revents.borrow_mut() = 0); + if __fd >= 0 { + __idx.push(__i); + __wanted.push(__fd); + __events.push(__ev); + } + } + FdRegistry::with_fds(&__wanted, |__b| { + let mut __pfds: Vec = __b + .iter() + .zip(&__events) + .map(|(&__fd, &__ev)| { + nix::poll::PollFd::new(__fd, nix::poll::PollFlags::from_bits_truncate(__ev)) + }) + .collect(); + match nix::poll::poll(&mut __pfds, __timeout) { + Ok(__count) => { + for (__slot, &__i) in __pfds.iter().zip(&__idx) { + let __rev = match __slot.revents() { + Some(__r) => __r.bits(), + None => 0, + }; + __p.offset(__i) + .with_mut(|__e| *__e.revents.borrow_mut() = __rev); + } + __count + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }) +} diff --git a/rules/poll/tgt_unsafe.rs b/rules/poll/tgt_unsafe.rs index 97ff38ae..701e1c6a 100644 --- a/rules/poll/tgt_unsafe.rs +++ b/rules/poll/tgt_unsafe.rs @@ -5,6 +5,10 @@ fn t1() -> ::libc::pollfd { unsafe { std::mem::zeroed() } } -unsafe fn f1(a0: *mut ::libc::pollfd, a1: u64, a2: i32) -> i32 { +fn t2() -> ::libc::nfds_t { + 0 +} + +unsafe fn f1(a0: *mut ::libc::pollfd, a1: ::libc::nfds_t, a2: i32) -> i32 { libc::poll(a0, a1 as ::libc::nfds_t, a2) } diff --git a/rules/select/tgt_refcount.rs b/rules/select/tgt_refcount.rs index bbef69e5..00317292 100644 --- a/rules/select/tgt_refcount.rs +++ b/rules/select/tgt_refcount.rs @@ -22,3 +22,109 @@ fn f4(a0: i32, a1: Ptr) -> i32 { fn f5(a0: Ptr) { a0.with_mut(|__s| __s.zero()); } + +fn f1(a0: i32, a1: Ptr, a2: Ptr, a3: Ptr, a4: Ptr) -> i32 { + let __rp = a1.clone(); + let __wp = a2.clone(); + let __ep = a3.clone(); + let __tp = a4.clone(); + let __r_fds: Vec = match __rp.is_null() { + true => Vec::new(), + false => __rp.with(|__s| (0..a0).filter(|&__fd| __s.isset(__fd)).collect()), + }; + let __w_fds: Vec = match __wp.is_null() { + true => Vec::new(), + false => __wp.with(|__s| (0..a0).filter(|&__fd| __s.isset(__fd)).collect()), + }; + let __e_fds: Vec = match __ep.is_null() { + true => Vec::new(), + false => __ep.with(|__s| (0..a0).filter(|&__fd| __s.isset(__fd)).collect()), + }; + let mut __wanted = Vec::new(); + __wanted.extend(&__r_fds); + __wanted.extend(&__w_fds); + __wanted.extend(&__e_fds); + FdRegistry::with_fds(&__wanted, |__b| { + let __rn = __r_fds.len(); + let __wn = __w_fds.len(); + let mut __rs = nix::sys::select::FdSet::new(); + let mut __ws = nix::sys::select::FdSet::new(); + let mut __es = nix::sys::select::FdSet::new(); + for __bfd in &__b[..__rn] { + __rs.insert(*__bfd); + } + for __bfd in &__b[__rn..__rn + __wn] { + __ws.insert(*__bfd); + } + for __bfd in &__b[__rn + __wn..] { + __es.insert(*__bfd); + } + let mut __tv = match __tp.is_null() { + true => None, + false => Some(__tp.with(|__t| { + nix::sys::time::TimeVal::new(*__t.tv_sec.borrow() as _, *__t.tv_usec.borrow() as _) + })), + }; + match nix::sys::select::select( + a0, + match __rp.is_null() { + true => None, + false => Some(&mut __rs), + }, + match __wp.is_null() { + true => None, + false => Some(&mut __ws), + }, + match __ep.is_null() { + true => None, + false => Some(&mut __es), + }, + __tv.as_mut(), + ) { + Ok(__n) => { + if !__rp.is_null() { + __rp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __r_fds.iter().zip(&__b[..__rn]) { + if __rs.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__wp.is_null() { + __wp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __w_fds.iter().zip(&__b[__rn..__rn + __wn]) { + if __ws.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__ep.is_null() { + __ep.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __e_fds.iter().zip(&__b[__rn + __wn..]) { + if __es.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + match (__tp.is_null(), __tv.as_ref()) { + (false, Some(__t)) => __tp.with_mut(|__dst| { + *__dst.tv_sec.borrow_mut() = __t.tv_sec() as i64; + *__dst.tv_usec.borrow_mut() = __t.tv_usec() as i64; + }), + _ => {} + } + __n + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }) +} diff --git a/tests/unit/out/refcount/poll.rs b/tests/unit/out/refcount/poll.rs new file mode 100644 index 00000000..f996dc13 --- /dev/null +++ b/tests/unit/out/refcount/poll.rs @@ -0,0 +1,131 @@ +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 fds: Value> = Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )); + assert!( + (((match nix::unistd::pipe() { + Ok((__r, __w)) => { + let __fds = (fds.as_pointer() as Ptr).clone(); + __fds.write(FdRegistry::register(__r)); + __fds.offset(1).write(FdRegistry::register(__w)); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 0) as i32) + != 0) + ); + assert!( + (((match FdRegistry::with_fd((*fds.borrow())[(1) as usize], |__fd| { + Ptr::from_string_literal(b"x") + .to_any() + .reinterpret_cast::() + .with_slice(1_usize, |__buf| nix::unistd::write(__fd, __buf)) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 1_isize) as i32) + != 0) + ); + let pfd: Value> = Rc::new(RefCell::new( + (0..2) + .map(|_| Default::default()) + .collect::>(), + )); + (*(*pfd.borrow())[(0) as usize].fd.borrow_mut()) = (*fds.borrow())[(0) as usize]; + (*(*pfd.borrow())[(0) as usize].events.borrow_mut()) = 1_i16; + (*(*pfd.borrow())[(0) as usize].revents.borrow_mut()) = 0_i16; + (*(*pfd.borrow())[(1) as usize].fd.borrow_mut()) = -1_i32; + (*(*pfd.borrow())[(1) as usize].events.borrow_mut()) = 1_i16; + (*(*pfd.borrow())[(1) as usize].revents.borrow_mut()) = 42_i16; + assert!( + ((({ + let __p = (pfd.as_pointer() as Ptr).clone(); + let __timeout = match nix::poll::PollTimeout::try_from(0) { + Ok(__t) => __t, + Err(_) => panic!("poll: unsupported timeout {}", 0), + }; + let mut __idx = Vec::new(); + let mut __wanted = Vec::new(); + let mut __events = Vec::new(); + for __i in 0..((2 as ::libc::nfds_t) as usize) { + let (__fd, __ev) = __p + .offset(__i) + .with(|__e| (*__e.fd.borrow(), *__e.events.borrow())); + __p.offset(__i) + .with_mut(|__e| *__e.revents.borrow_mut() = 0); + if __fd >= 0 { + __idx.push(__i); + __wanted.push(__fd); + __events.push(__ev); + } + } + FdRegistry::with_fds(&__wanted, |__b| { + let mut __pfds: Vec = __b + .iter() + .zip(&__events) + .map(|(&__fd, &__ev)| { + nix::poll::PollFd::new(__fd, nix::poll::PollFlags::from_bits_truncate(__ev)) + }) + .collect(); + match nix::poll::poll(&mut __pfds, __timeout) { + Ok(__count) => { + for (__slot, &__i) in __pfds.iter().zip(&__idx) { + let __rev = match __slot.revents() { + Some(__r) => __r.bits(), + None => 0, + }; + __p.offset(__i) + .with_mut(|__e| *__e.revents.borrow_mut() = __rev); + } + __count + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }) + } == 1) as i32) + != 0) + ); + assert!( + ((((((*(*pfd.borrow())[(0) as usize].revents.borrow()) as i32) & 1) != 0) as i32) != 0) + ); + assert!((((((*(*pfd.borrow())[(1) as usize].revents.borrow()) as i32) == 0) as i32) != 0)); + let ch: Value = >::default(); + assert!( + (((match FdRegistry::with_fd((*fds.borrow())[(0) as usize], |__fd| { + ((ch.as_pointer()) as Ptr) + .to_any() + .reinterpret_cast::() + .with_slice_mut(1_usize, |__buf| nix::unistd::read(__fd, __buf)) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 1_isize) as i32) + != 0) + ); + assert!((((FdRegistry::close((*fds.borrow())[(0) as usize]) == 0) as i32) != 0)); + assert!((((FdRegistry::close((*fds.borrow())[(1) as usize]) == 0) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/refcount/select.rs b/tests/unit/out/refcount/select.rs new file mode 100644 index 00000000..161fbfcb --- /dev/null +++ b/tests/unit/out/refcount/select.rs @@ -0,0 +1,326 @@ +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 fds: Value> = Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )); + assert!( + (((match nix::unistd::pipe() { + Ok((__r, __w)) => { + let __fds = (fds.as_pointer() as Ptr).clone(); + __fds.write(FdRegistry::register(__r)); + __fds.offset(1).write(FdRegistry::register(__w)); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 0) as i32) + != 0) + ); + let rset: Value = Rc::new(RefCell::new(Default::default())); + (rset.as_pointer()).with_mut(|__s| __s.zero()); + (rset.as_pointer()).with_mut(|__s| __s.set((*fds.borrow())[(0) as usize])); + let tv: Value = Rc::new(RefCell::new(Default::default())); + { + ((tv.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, 16usize as usize); + ((tv.as_pointer()) as Ptr) + .to_any() + .clone() + }; + (*(*tv.borrow()).tv_sec.borrow_mut()) = 0_i64; + assert!( + ((({ + let __rp = (rset.as_pointer()).clone(); + let __wp = Ptr::::null().clone(); + let __ep = Ptr::::null().clone(); + let __tp = (tv.as_pointer()).clone(); + let __r_fds: Vec = match __rp.is_null() { + true => Vec::new(), + false => __rp.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let __w_fds: Vec = match __wp.is_null() { + true => Vec::new(), + false => __wp.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let __e_fds: Vec = match __ep.is_null() { + true => Vec::new(), + false => __ep.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let mut __wanted = Vec::new(); + __wanted.extend(&__r_fds); + __wanted.extend(&__w_fds); + __wanted.extend(&__e_fds); + FdRegistry::with_fds(&__wanted, |__b| { + let __rn = __r_fds.len(); + let __wn = __w_fds.len(); + let mut __rs = nix::sys::select::FdSet::new(); + let mut __ws = nix::sys::select::FdSet::new(); + let mut __es = nix::sys::select::FdSet::new(); + for __bfd in &__b[..__rn] { + __rs.insert(*__bfd); + } + for __bfd in &__b[__rn..__rn + __wn] { + __ws.insert(*__bfd); + } + for __bfd in &__b[__rn + __wn..] { + __es.insert(*__bfd); + } + let mut __tv = match __tp.is_null() { + true => None, + false => Some(__tp.with(|__t| { + nix::sys::time::TimeVal::new( + *__t.tv_sec.borrow() as _, + *__t.tv_usec.borrow() as _, + ) + })), + }; + match nix::sys::select::select( + ((*fds.borrow())[(0) as usize] + 1), + match __rp.is_null() { + true => None, + false => Some(&mut __rs), + }, + match __wp.is_null() { + true => None, + false => Some(&mut __ws), + }, + match __ep.is_null() { + true => None, + false => Some(&mut __es), + }, + __tv.as_mut(), + ) { + Ok(__n) => { + if !__rp.is_null() { + __rp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __r_fds.iter().zip(&__b[..__rn]) { + if __rs.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__wp.is_null() { + __wp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __w_fds.iter().zip(&__b[__rn..__rn + __wn]) { + if __ws.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__ep.is_null() { + __ep.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __e_fds.iter().zip(&__b[__rn + __wn..]) { + if __es.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + match (__tp.is_null(), __tv.as_ref()) { + (false, Some(__t)) => __tp.with_mut(|__dst| { + *__dst.tv_sec.borrow_mut() = __t.tv_sec() as i64; + *__dst.tv_usec.borrow_mut() = __t.tv_usec() as i64; + }), + _ => {} + } + __n + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }) + } == 0) as i32) + != 0) + ); + assert!( + ((!(if (rset.as_pointer()).with(|__s| __s.isset((*fds.borrow())[(0) as usize])) { + 1 + } else { + 0 + } != 0) as i32) + != 0) + ); + assert!( + (((match FdRegistry::with_fd((*fds.borrow())[(1) as usize], |__fd| { + Ptr::from_string_literal(b"x") + .to_any() + .reinterpret_cast::() + .with_slice(1_usize, |__buf| nix::unistd::write(__fd, __buf)) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } == 1_isize) as i32) + != 0) + ); + (rset.as_pointer()).with_mut(|__s| __s.zero()); + (rset.as_pointer()).with_mut(|__s| __s.set((*fds.borrow())[(0) as usize])); + (*(*tv.borrow()).tv_sec.borrow_mut()) = 1_i64; + assert!( + ((({ + let __rp = (rset.as_pointer()).clone(); + let __wp = Ptr::::null().clone(); + let __ep = Ptr::::null().clone(); + let __tp = (tv.as_pointer()).clone(); + let __r_fds: Vec = match __rp.is_null() { + true => Vec::new(), + false => __rp.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let __w_fds: Vec = match __wp.is_null() { + true => Vec::new(), + false => __wp.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let __e_fds: Vec = match __ep.is_null() { + true => Vec::new(), + false => __ep.with(|__s| { + (0..((*fds.borrow())[(0) as usize] + 1)) + .filter(|&__fd| __s.isset(__fd)) + .collect() + }), + }; + let mut __wanted = Vec::new(); + __wanted.extend(&__r_fds); + __wanted.extend(&__w_fds); + __wanted.extend(&__e_fds); + FdRegistry::with_fds(&__wanted, |__b| { + let __rn = __r_fds.len(); + let __wn = __w_fds.len(); + let mut __rs = nix::sys::select::FdSet::new(); + let mut __ws = nix::sys::select::FdSet::new(); + let mut __es = nix::sys::select::FdSet::new(); + for __bfd in &__b[..__rn] { + __rs.insert(*__bfd); + } + for __bfd in &__b[__rn..__rn + __wn] { + __ws.insert(*__bfd); + } + for __bfd in &__b[__rn + __wn..] { + __es.insert(*__bfd); + } + let mut __tv = match __tp.is_null() { + true => None, + false => Some(__tp.with(|__t| { + nix::sys::time::TimeVal::new( + *__t.tv_sec.borrow() as _, + *__t.tv_usec.borrow() as _, + ) + })), + }; + match nix::sys::select::select( + ((*fds.borrow())[(0) as usize] + 1), + match __rp.is_null() { + true => None, + false => Some(&mut __rs), + }, + match __wp.is_null() { + true => None, + false => Some(&mut __ws), + }, + match __ep.is_null() { + true => None, + false => Some(&mut __es), + }, + __tv.as_mut(), + ) { + Ok(__n) => { + if !__rp.is_null() { + __rp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __r_fds.iter().zip(&__b[..__rn]) { + if __rs.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__wp.is_null() { + __wp.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __w_fds.iter().zip(&__b[__rn..__rn + __wn]) { + if __ws.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + if !__ep.is_null() { + __ep.with_mut(|__s| { + __s.zero(); + for (__fd, __bfd) in __e_fds.iter().zip(&__b[__rn + __wn..]) { + if __es.contains(*__bfd) { + __s.set(*__fd); + } + } + }); + } + match (__tp.is_null(), __tv.as_ref()) { + (false, Some(__t)) => __tp.with_mut(|__dst| { + *__dst.tv_sec.borrow_mut() = __t.tv_sec() as i64; + *__dst.tv_usec.borrow_mut() = __t.tv_usec() as i64; + }), + _ => {} + } + __n + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } + }) + } == 1) as i32) + != 0) + ); + assert!( + (if (rset.as_pointer()).with(|__s| __s.isset((*fds.borrow())[(0) as usize])) { + 1 + } else { + 0 + } != 0) + ); + assert!((((FdRegistry::close((*fds.borrow())[(0) as usize]) == 0) as i32) != 0)); + assert!((((FdRegistry::close((*fds.borrow())[(1) as usize]) == 0) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/poll.rs b/tests/unit/out/unsafe/poll.rs new file mode 100644 index 00000000..1f7ec1e0 --- /dev/null +++ b/tests/unit/out/unsafe/poll.rs @@ -0,0 +1,51 @@ +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 fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut fds: [i32; 2] = [0_i32; 2]; + assert!(((((libc::pipe(fds.as_mut_ptr())) == (0)) as i32) != 0)); + assert!( + ((((libc::write( + fds[(1) as usize], + (c"x".as_ptr().cast_mut() as *const libc::c_char as *const ::libc::c_void), + 1_usize + )) == (1_isize)) as i32) + != 0) + ); + let mut pfd: [::libc::pollfd; 2] = [unsafe { std::mem::zeroed() }; 2]; + pfd[(0) as usize].fd = fds[(0) as usize]; + pfd[(0) as usize].events = 1_i16; + pfd[(0) as usize].revents = 0_i16; + pfd[(1) as usize].fd = -1_i32; + pfd[(1) as usize].events = 1_i16; + pfd[(1) as usize].revents = 42_i16; + assert!( + ((((libc::poll(pfd.as_mut_ptr(), (2 as ::libc::nfds_t) as ::libc::nfds_t, 0)) == (1)) + as i32) + != 0) + ); + assert!((((((pfd[(0) as usize].revents as i32) & (1)) != (0)) as i32) != 0)); + assert!(((((pfd[(1) as usize].revents as i32) == (0)) as i32) != 0)); + let mut ch: libc::c_char = (0 as libc::c_char); + assert!( + ((((libc::read( + fds[(0) as usize], + ((&mut ch as *mut libc::c_char) as *mut libc::c_char as *mut ::libc::c_void), + 1_usize + )) == (1_isize)) as i32) + != 0) + ); + assert!(((((libc::close(fds[(0) as usize])) == (0)) as i32) != 0)); + assert!(((((libc::close(fds[(1) as usize])) == (0)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/select.rs b/tests/unit/out/unsafe/select.rs new file mode 100644 index 00000000..646f3103 --- /dev/null +++ b/tests/unit/out/unsafe/select.rs @@ -0,0 +1,79 @@ +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 fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut fds: [i32; 2] = [0_i32; 2]; + assert!(((((libc::pipe(fds.as_mut_ptr())) == (0)) as i32) != 0)); + let mut rset: ::libc::fd_set = std::mem::zeroed::<::libc::fd_set>(); + libc::FD_ZERO((&mut rset as *mut ::libc::fd_set)); + libc::FD_SET(fds[(0) as usize], (&mut rset as *mut ::libc::fd_set)); + let mut tv: ::libc::timeval = unsafe { std::mem::zeroed() }; + { + let byte_0 = ((&mut tv as *mut ::libc::timeval) as *mut ::libc::timeval + as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::<::libc::timeval>() { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut tv as *mut ::libc::timeval) as *mut ::libc::timeval as *mut ::libc::c_void) + }; + tv.tv_sec = 0_i64; + assert!( + ((((libc::select( + ((fds[(0) as usize]) + (1)), + (&mut rset as *mut ::libc::fd_set), + std::ptr::null_mut(), + std::ptr::null_mut(), + (&mut tv as *mut ::libc::timeval) + )) == (0)) as i32) + != 0) + ); + assert!( + ((!(libc::FD_ISSET( + fds[(0) as usize], + (&mut rset as *mut ::libc::fd_set).cast_const() + ) as i32 + != 0) as i32) + != 0) + ); + assert!( + ((((libc::write( + fds[(1) as usize], + (c"x".as_ptr().cast_mut() as *const libc::c_char as *const ::libc::c_void), + 1_usize + )) == (1_isize)) as i32) + != 0) + ); + libc::FD_ZERO((&mut rset as *mut ::libc::fd_set)); + libc::FD_SET(fds[(0) as usize], (&mut rset as *mut ::libc::fd_set)); + tv.tv_sec = 1_i64; + assert!( + ((((libc::select( + ((fds[(0) as usize]) + (1)), + (&mut rset as *mut ::libc::fd_set), + std::ptr::null_mut(), + std::ptr::null_mut(), + (&mut tv as *mut ::libc::timeval) + )) == (1)) as i32) + != 0) + ); + assert!( + (libc::FD_ISSET( + fds[(0) as usize], + (&mut rset as *mut ::libc::fd_set).cast_const() + ) as i32 + != 0) + ); + assert!(((((libc::close(fds[(0) as usize])) == (0)) as i32) != 0)); + assert!(((((libc::close(fds[(1) as usize])) == (0)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/poll.c b/tests/unit/poll.c new file mode 100644 index 00000000..1b45c43f --- /dev/null +++ b/tests/unit/poll.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(void) { + int fds[2]; + assert(pipe(fds) == 0); + assert(write(fds[1], "x", 1) == 1); + struct pollfd pfd[2]; + pfd[0].fd = fds[0]; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + pfd[1].fd = -1; + pfd[1].events = POLLIN; + pfd[1].revents = 42; + assert(poll(pfd, 2, 0) == 1); + assert((pfd[0].revents & POLLIN) != 0); + assert(pfd[1].revents == 0); + char ch; + assert(read(fds[0], &ch, 1) == 1); + assert(close(fds[0]) == 0); + assert(close(fds[1]) == 0); + return 0; +} diff --git a/tests/unit/select.c b/tests/unit/select.c new file mode 100644 index 00000000..c83626cc --- /dev/null +++ b/tests/unit/select.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +int main(void) { + int fds[2]; + assert(pipe(fds) == 0); + fd_set rset; + FD_ZERO(&rset); + FD_SET(fds[0], &rset); + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = 0; + assert(select(fds[0] + 1, &rset, NULL, NULL, &tv) == 0); + assert(!FD_ISSET(fds[0], &rset)); + assert(write(fds[1], "x", 1) == 1); + FD_ZERO(&rset); + FD_SET(fds[0], &rset); + tv.tv_sec = 1; + assert(select(fds[0] + 1, &rset, NULL, NULL, &tv) == 1); + assert(FD_ISSET(fds[0], &rset)); + assert(close(fds[0]) == 0); + assert(close(fds[1]) == 0); + return 0; +}