From a1b4d7c0d5ddcfa62d439b819d2ac3d7f964167c Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 16 Jul 2026 22:45:04 +0100 Subject: [PATCH 1/8] Add misc safe rules --- libcc2rs/src/libc_shims/pwd.rs | 19 ++++ libcc2rs/src/libc_shims/stat.rs | 21 +++++ rules/cstdlib/tgt_refcount.rs | 11 +++ rules/dirent/tgt_refcount.rs | 65 +++++++++++++ rules/locale/tgt_refcount.rs | 8 ++ rules/pwd/tgt_refcount.rs | 7 ++ rules/src/modules.rs | 2 + rules/stat/tgt_refcount.rs | 26 ++++++ tests/unit/libc_char_ptr_field.c | 1 - .../unit/out/refcount/libc_char_ptr_field.rs | 91 +++++++++++++++++++ 10 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 rules/locale/tgt_refcount.rs create mode 100644 tests/unit/out/refcount/libc_char_ptr_field.rs diff --git a/libcc2rs/src/libc_shims/pwd.rs b/libcc2rs/src/libc_shims/pwd.rs index dd76bde2..a18be065 100644 --- a/libcc2rs/src/libc_shims/pwd.rs +++ b/libcc2rs/src/libc_shims/pwd.rs @@ -16,6 +16,25 @@ pub struct Passwd { pub pw_shell: Value>, } +impl Passwd { + pub fn from_user(u: &nix::unistd::User) -> Self { + let mk = |s: &[u8]| -> Value> { + let mut v = s.to_vec(); + v.push(0); + Rc::new(RefCell::new(Ptr::alloc_array(v.into_boxed_slice()))) + }; + Self { + pw_name: mk(u.name.as_bytes()), + pw_passwd: mk(u.passwd.as_bytes()), + pw_uid: Rc::new(RefCell::new(u.uid.as_raw())), + pw_gid: Rc::new(RefCell::new(u.gid.as_raw())), + pw_gecos: mk(u.gecos.as_bytes()), + pw_dir: mk(u.dir.as_os_str().as_encoded_bytes()), + pw_shell: mk(u.shell.as_os_str().as_encoded_bytes()), + } + } +} + impl Clone for Passwd { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index b73b6acb..792bff49 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -22,6 +22,27 @@ pub struct Stat { pub st_ctime: Value, } +impl Stat { + #[allow(clippy::unnecessary_cast)] + pub fn from_libc(s: &::libc::stat) -> Self { + Self { + st_dev: Rc::new(RefCell::new(s.st_dev as u64)), + st_ino: Rc::new(RefCell::new(s.st_ino as u64)), + st_nlink: Rc::new(RefCell::new(s.st_nlink as u64)), + st_mode: Rc::new(RefCell::new(s.st_mode as u32)), + st_uid: Rc::new(RefCell::new(s.st_uid)), + st_gid: Rc::new(RefCell::new(s.st_gid)), + st_rdev: Rc::new(RefCell::new(s.st_rdev as u64)), + st_size: Rc::new(RefCell::new(s.st_size as i64)), + st_blksize: Rc::new(RefCell::new(s.st_blksize as i64)), + st_blocks: Rc::new(RefCell::new(s.st_blocks as i64)), + st_atime: Rc::new(RefCell::new(s.st_atime as i64)), + st_mtime: Rc::new(RefCell::new(s.st_mtime as i64)), + st_ctime: Rc::new(RefCell::new(s.st_ctime as i64)), + } + } +} + impl Clone for Stat { fn clone(&self) -> Self { Self { diff --git a/rules/cstdlib/tgt_refcount.rs b/rules/cstdlib/tgt_refcount.rs index 5c52137d..cb04f452 100644 --- a/rules/cstdlib/tgt_refcount.rs +++ b/rules/cstdlib/tgt_refcount.rs @@ -19,6 +19,17 @@ fn f5(a0: usize, a1: usize) -> AnyPtr { libcc2rs::calloc_refcount(a0, a1) } +fn f6(a0: Ptr) -> Ptr { + match ::std::env::var(a0.to_rust_string()) { + Ok(__val) => { + let mut __bytes = __val.into_bytes(); + __bytes.push(0); + Ptr::alloc_array(__bytes.into_boxed_slice()) + } + Err(_) => Ptr::null(), + } +} + fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i32) -> AnyPtr { let __base = a1.reinterpret_cast::(); let mut __lo: isize = 0; diff --git a/rules/dirent/tgt_refcount.rs b/rules/dirent/tgt_refcount.rs index cb0b8f9b..6c4065b3 100644 --- a/rules/dirent/tgt_refcount.rs +++ b/rules/dirent/tgt_refcount.rs @@ -10,3 +10,68 @@ fn t1() -> Ptr { fn t2() -> libcc2rs::Dirent { Default::default() } + +fn f1(a0: Ptr) -> Ptr { + match nix::dir::Dir::open( + a0.to_rust_string().as_str(), + nix::fcntl::OFlag::O_RDONLY, + nix::sys::stat::Mode::empty(), + ) { + Ok(__dir) => { + let mut __entries: Vec<(u64, Vec, u8)> = Vec::new(); + for __e in __dir { + match __e { + Ok(__ent) => { + let __ty = match __ent.file_type() { + Some(nix::dir::Type::Fifo) => ::libc::DT_FIFO, + Some(nix::dir::Type::CharacterDevice) => ::libc::DT_CHR, + Some(nix::dir::Type::Directory) => ::libc::DT_DIR, + Some(nix::dir::Type::BlockDevice) => ::libc::DT_BLK, + Some(nix::dir::Type::File) => ::libc::DT_REG, + Some(nix::dir::Type::Symlink) => ::libc::DT_LNK, + Some(nix::dir::Type::Socket) => ::libc::DT_SOCK, + None => ::libc::DT_UNKNOWN, + }; + __entries.push((__ent.ino(), __ent.file_name().to_bytes().to_vec(), __ty)); + } + Err(_) => {} + } + } + Ptr::alloc(CDir { + entries: __entries, + pos: ::std::cell::Cell::new(0), + }) + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } + } +} + +fn f2(a0: Ptr) -> Ptr { + a0.with(|__d| { + let __i = __d.pos.get(); + if __i >= __d.entries.len() { + Ptr::null() + } else { + __d.pos.set(__i + 1); + let __e = &__d.entries[__i]; + let __de = Dirent::default(); + *__de.d_ino.borrow_mut() = __e.0; + *__de.d_type.borrow_mut() = __e.2; + { + let mut __nm = __de.d_name.borrow_mut(); + let __n = __e.1.len().min(__nm.len() - 1); + __nm[..__n].copy_from_slice(&__e.1[..__n]); + __nm[__n] = 0; + } + Ptr::alloc(__de) + } + }) +} + +fn f3(a0: Ptr) -> i32 { + a0.delete(); + 0 +} diff --git a/rules/locale/tgt_refcount.rs b/rules/locale/tgt_refcount.rs new file mode 100644 index 00000000..bb0921e9 --- /dev/null +++ b/rules/locale/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn f1(a0: i32, a1: Ptr) -> Ptr { + Ptr::from_string_literal(b"C") +} diff --git a/rules/pwd/tgt_refcount.rs b/rules/pwd/tgt_refcount.rs index 31c14099..f9ed443f 100644 --- a/rules/pwd/tgt_refcount.rs +++ b/rules/pwd/tgt_refcount.rs @@ -6,3 +6,10 @@ use libcc2rs::*; fn t1() -> libcc2rs::Passwd { Default::default() } + +fn f1(a0: u32) -> Ptr { + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) { + Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), + _ => Ptr::null(), + } +} diff --git a/rules/src/modules.rs b/rules/src/modules.rs index 65dbeae7..baef05d8 100644 --- a/rules/src/modules.rs +++ b/rules/src/modules.rs @@ -84,6 +84,8 @@ pub mod ip_tgt_refcount; pub mod ip_tgt_unsafe; #[path = r#"../limits/tgt_unsafe.rs"#] pub mod limits_tgt_unsafe; +#[path = r#"../locale/tgt_refcount.rs"#] +pub mod locale_tgt_refcount; #[path = r#"../locale/tgt_unsafe.rs"#] pub mod locale_tgt_unsafe; #[path = r#"../map/tgt_refcount.rs"#] diff --git a/rules/stat/tgt_refcount.rs b/rules/stat/tgt_refcount.rs index 32856e53..bf577f5c 100644 --- a/rules/stat/tgt_refcount.rs +++ b/rules/stat/tgt_refcount.rs @@ -6,3 +6,29 @@ use libcc2rs::*; fn t1() -> libcc2rs::Stat { Default::default() } + +fn f1(a0: Ptr, a1: Ptr) -> i32 { + match nix::sys::stat::stat(a0.to_rust_string().as_str()) { + Ok(__s) => { + a1.with_mut(|__st| *__st = Stat::from_libc(&__s)); + 0 + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} + +fn f3(a0: Ptr, a1: ::libc::mode_t) -> i32 { + match nix::unistd::mkdir( + a0.to_rust_string().as_str(), + nix::sys::stat::Mode::from_bits_truncate(a1), + ) { + Ok(()) => 0, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} diff --git a/tests/unit/libc_char_ptr_field.c b/tests/unit/libc_char_ptr_field.c index dd37e238..f898aef1 100644 --- a/tests/unit/libc_char_ptr_field.c +++ b/tests/unit/libc_char_ptr_field.c @@ -1,4 +1,3 @@ -// no-compile: refcount #include #include #include diff --git a/tests/unit/out/refcount/libc_char_ptr_field.rs b/tests/unit/out/refcount/libc_char_ptr_field.rs new file mode 100644 index 00000000..865fc6ea --- /dev/null +++ b/tests/unit/out/refcount/libc_char_ptr_field.rs @@ -0,0 +1,91 @@ +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 pw: Value> = Rc::new(RefCell::new( + match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw( + nix::unistd::geteuid().as_raw(), + )) { + Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), + _ => Ptr::null(), + }, + )); + if !!(*pw.borrow()).is_null() { + return 0; + } + let home: Value> = Rc::new(RefCell::new( + (*(*(*pw.borrow()).upgrade().deref()).pw_dir.borrow()).clone(), + )); + let d: Value> = Rc::new(RefCell::new( + match nix::dir::Dir::open( + Ptr::from_string_literal(b"/tmp").to_rust_string().as_str(), + nix::fcntl::OFlag::O_RDONLY, + nix::sys::stat::Mode::empty(), + ) { + Ok(__dir) => { + let mut __entries: Vec<(u64, Vec, u8)> = Vec::new(); + for __e in __dir { + match __e { + Ok(__ent) => { + let __ty = match __ent.file_type() { + Some(nix::dir::Type::Fifo) => ::libc::DT_FIFO, + Some(nix::dir::Type::CharacterDevice) => ::libc::DT_CHR, + Some(nix::dir::Type::Directory) => ::libc::DT_DIR, + Some(nix::dir::Type::BlockDevice) => ::libc::DT_BLK, + Some(nix::dir::Type::File) => ::libc::DT_REG, + Some(nix::dir::Type::Symlink) => ::libc::DT_LNK, + Some(nix::dir::Type::Socket) => ::libc::DT_SOCK, + None => ::libc::DT_UNKNOWN, + }; + __entries.push(( + __ent.ino(), + __ent.file_name().to_bytes().to_vec(), + __ty, + )); + } + Err(_) => {} + } + } + Ptr::alloc(CDir { + entries: __entries, + pos: ::std::cell::Cell::new(0), + }) + } + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } + } + .with(|__d| { + let __i = __d.pos.get(); + if __i >= __d.entries.len() { + Ptr::null() + } else { + __d.pos.set(__i + 1); + let __e = &__d.entries[__i]; + let __de = Dirent::default(); + *__de.d_ino.borrow_mut() = __e.0; + *__de.d_type.borrow_mut() = __e.2; + { + let mut __nm = __de.d_name.borrow_mut(); + let __n = __e.1.len().min(__nm.len() - 1); + __nm[..__n].copy_from_slice(&__e.1[..__n]); + __nm[__n] = 0; + } + Ptr::alloc(__de) + } + }), + )); + let dname: Value> = Rc::new(RefCell::new( + ((*(*d.borrow()).upgrade().deref()).d_name.as_pointer() as Ptr), + )); + return 0; +} From 184231c07351b833d2d9e89f184f9312ea5c298f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 17 Jul 2026 11:33:06 +0100 Subject: [PATCH 2/8] Add conversion function for Dirent --- libcc2rs/src/libc_shims/dirent.rs | 15 +++++++++++++++ rules/dirent/tgt_refcount.rs | 11 +---------- tests/unit/out/refcount/libc_char_ptr_field.rs | 11 +---------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/libcc2rs/src/libc_shims/dirent.rs b/libcc2rs/src/libc_shims/dirent.rs index f36bd5ad..b8835f96 100644 --- a/libcc2rs/src/libc_shims/dirent.rs +++ b/libcc2rs/src/libc_shims/dirent.rs @@ -25,6 +25,21 @@ impl Default for Dirent { } } +impl Dirent { + pub fn from_entry(ino: u64, name: &[u8], d_type: u8) -> Self { + let de = Dirent::default(); + *de.d_ino.borrow_mut() = ino; + *de.d_type.borrow_mut() = d_type; + { + let mut nm = de.d_name.borrow_mut(); + let n = name.len().min(nm.len() - 1); + nm[..n].copy_from_slice(&name[..n]); + nm[n] = 0; + } + de + } +} + impl Clone for Dirent { fn clone(&self) -> Self { Self { diff --git a/rules/dirent/tgt_refcount.rs b/rules/dirent/tgt_refcount.rs index 6c4065b3..03457f4b 100644 --- a/rules/dirent/tgt_refcount.rs +++ b/rules/dirent/tgt_refcount.rs @@ -57,16 +57,7 @@ fn f2(a0: Ptr) -> Ptr { } else { __d.pos.set(__i + 1); let __e = &__d.entries[__i]; - let __de = Dirent::default(); - *__de.d_ino.borrow_mut() = __e.0; - *__de.d_type.borrow_mut() = __e.2; - { - let mut __nm = __de.d_name.borrow_mut(); - let __n = __e.1.len().min(__nm.len() - 1); - __nm[..__n].copy_from_slice(&__e.1[..__n]); - __nm[__n] = 0; - } - Ptr::alloc(__de) + Ptr::alloc(Dirent::from_entry(__e.0, &__e.1, __e.2)) } }) } diff --git a/tests/unit/out/refcount/libc_char_ptr_field.rs b/tests/unit/out/refcount/libc_char_ptr_field.rs index 865fc6ea..8cb0c4a3 100644 --- a/tests/unit/out/refcount/libc_char_ptr_field.rs +++ b/tests/unit/out/refcount/libc_char_ptr_field.rs @@ -71,16 +71,7 @@ fn main_0() -> i32 { } else { __d.pos.set(__i + 1); let __e = &__d.entries[__i]; - let __de = Dirent::default(); - *__de.d_ino.borrow_mut() = __e.0; - *__de.d_type.borrow_mut() = __e.2; - { - let mut __nm = __de.d_name.borrow_mut(); - let __n = __e.1.len().min(__nm.len() - 1); - __nm[..__n].copy_from_slice(&__e.1[..__n]); - __nm[__n] = 0; - } - Ptr::alloc(__de) + Ptr::alloc(Dirent::from_entry(__e.0, &__e.1, __e.2)) } }), )); From 1d6add10d1035cccf4d886a87668ad0998f7ed3b Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 17 Jul 2026 11:34:32 +0100 Subject: [PATCH 3/8] Drop the unnecessary_casts --- libcc2rs/src/libc_shims/stat.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index 792bff49..d8541c2a 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -23,22 +23,21 @@ pub struct Stat { } impl Stat { - #[allow(clippy::unnecessary_cast)] pub fn from_libc(s: &::libc::stat) -> Self { Self { - st_dev: Rc::new(RefCell::new(s.st_dev as u64)), - st_ino: Rc::new(RefCell::new(s.st_ino as u64)), - st_nlink: Rc::new(RefCell::new(s.st_nlink as u64)), - st_mode: Rc::new(RefCell::new(s.st_mode as u32)), + st_dev: Rc::new(RefCell::new(s.st_dev)), + st_ino: Rc::new(RefCell::new(s.st_ino)), + st_nlink: Rc::new(RefCell::new(s.st_nlink)), + st_mode: Rc::new(RefCell::new(s.st_mode)), st_uid: Rc::new(RefCell::new(s.st_uid)), st_gid: Rc::new(RefCell::new(s.st_gid)), - st_rdev: Rc::new(RefCell::new(s.st_rdev as u64)), - st_size: Rc::new(RefCell::new(s.st_size as i64)), - st_blksize: Rc::new(RefCell::new(s.st_blksize as i64)), - st_blocks: Rc::new(RefCell::new(s.st_blocks as i64)), - st_atime: Rc::new(RefCell::new(s.st_atime as i64)), - st_mtime: Rc::new(RefCell::new(s.st_mtime as i64)), - st_ctime: Rc::new(RefCell::new(s.st_ctime as i64)), + st_rdev: Rc::new(RefCell::new(s.st_rdev)), + st_size: Rc::new(RefCell::new(s.st_size)), + st_blksize: Rc::new(RefCell::new(s.st_blksize)), + st_blocks: Rc::new(RefCell::new(s.st_blocks)), + st_atime: Rc::new(RefCell::new(s.st_atime)), + st_mtime: Rc::new(RefCell::new(s.st_mtime)), + st_ctime: Rc::new(RefCell::new(s.st_ctime)), } } } From 4e4ba6d95abbb0dee3773eba673c8e57e922a3d5 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 17 Jul 2026 11:37:08 +0100 Subject: [PATCH 4/8] Add conversion from nix::Dir to CDir --- libcc2rs/src/libc_shims/dirent.rs | 23 ++++++++++++++ rules/dirent/tgt_refcount.rs | 26 +--------------- .../unit/out/refcount/libc_char_ptr_field.rs | 30 +------------------ 3 files changed, 25 insertions(+), 54 deletions(-) diff --git a/libcc2rs/src/libc_shims/dirent.rs b/libcc2rs/src/libc_shims/dirent.rs index b8835f96..eeb6cec5 100644 --- a/libcc2rs/src/libc_shims/dirent.rs +++ b/libcc2rs/src/libc_shims/dirent.rs @@ -59,6 +59,29 @@ pub struct CDir { pub pos: Cell, } +impl CDir { + pub fn from_dir(dir: nix::dir::Dir) -> Self { + let mut entries: Vec<(u64, Vec, u8)> = Vec::new(); + for ent in dir.into_iter().flatten() { + let ty = match ent.file_type() { + Some(nix::dir::Type::Fifo) => ::libc::DT_FIFO, + Some(nix::dir::Type::CharacterDevice) => ::libc::DT_CHR, + Some(nix::dir::Type::Directory) => ::libc::DT_DIR, + Some(nix::dir::Type::BlockDevice) => ::libc::DT_BLK, + Some(nix::dir::Type::File) => ::libc::DT_REG, + Some(nix::dir::Type::Symlink) => ::libc::DT_LNK, + Some(nix::dir::Type::Socket) => ::libc::DT_SOCK, + None => ::libc::DT_UNKNOWN, + }; + entries.push((ent.ino(), ent.file_name().to_bytes().to_vec(), ty)); + } + Self { + entries, + pos: Cell::new(0), + } + } +} + impl ByteRepr for CDir {} impl ByteRepr for ::libc::dirent {} diff --git a/rules/dirent/tgt_refcount.rs b/rules/dirent/tgt_refcount.rs index 03457f4b..29f823ee 100644 --- a/rules/dirent/tgt_refcount.rs +++ b/rules/dirent/tgt_refcount.rs @@ -17,31 +17,7 @@ fn f1(a0: Ptr) -> Ptr { nix::fcntl::OFlag::O_RDONLY, nix::sys::stat::Mode::empty(), ) { - Ok(__dir) => { - let mut __entries: Vec<(u64, Vec, u8)> = Vec::new(); - for __e in __dir { - match __e { - Ok(__ent) => { - let __ty = match __ent.file_type() { - Some(nix::dir::Type::Fifo) => ::libc::DT_FIFO, - Some(nix::dir::Type::CharacterDevice) => ::libc::DT_CHR, - Some(nix::dir::Type::Directory) => ::libc::DT_DIR, - Some(nix::dir::Type::BlockDevice) => ::libc::DT_BLK, - Some(nix::dir::Type::File) => ::libc::DT_REG, - Some(nix::dir::Type::Symlink) => ::libc::DT_LNK, - Some(nix::dir::Type::Socket) => ::libc::DT_SOCK, - None => ::libc::DT_UNKNOWN, - }; - __entries.push((__ent.ino(), __ent.file_name().to_bytes().to_vec(), __ty)); - } - Err(_) => {} - } - } - Ptr::alloc(CDir { - entries: __entries, - pos: ::std::cell::Cell::new(0), - }) - } + Ok(__dir) => Ptr::alloc(CDir::from_dir(__dir)), Err(__e) => { libcc2rs::cpp2rust_errno().write(__e as i32); Ptr::null() diff --git a/tests/unit/out/refcount/libc_char_ptr_field.rs b/tests/unit/out/refcount/libc_char_ptr_field.rs index 8cb0c4a3..0fc7df85 100644 --- a/tests/unit/out/refcount/libc_char_ptr_field.rs +++ b/tests/unit/out/refcount/libc_char_ptr_field.rs @@ -30,35 +30,7 @@ fn main_0() -> i32 { nix::fcntl::OFlag::O_RDONLY, nix::sys::stat::Mode::empty(), ) { - Ok(__dir) => { - let mut __entries: Vec<(u64, Vec, u8)> = Vec::new(); - for __e in __dir { - match __e { - Ok(__ent) => { - let __ty = match __ent.file_type() { - Some(nix::dir::Type::Fifo) => ::libc::DT_FIFO, - Some(nix::dir::Type::CharacterDevice) => ::libc::DT_CHR, - Some(nix::dir::Type::Directory) => ::libc::DT_DIR, - Some(nix::dir::Type::BlockDevice) => ::libc::DT_BLK, - Some(nix::dir::Type::File) => ::libc::DT_REG, - Some(nix::dir::Type::Symlink) => ::libc::DT_LNK, - Some(nix::dir::Type::Socket) => ::libc::DT_SOCK, - None => ::libc::DT_UNKNOWN, - }; - __entries.push(( - __ent.ino(), - __ent.file_name().to_bytes().to_vec(), - __ty, - )); - } - Err(_) => {} - } - } - Ptr::alloc(CDir { - entries: __entries, - pos: ::std::cell::Cell::new(0), - }) - } + Ok(__dir) => Ptr::alloc(CDir::from_dir(__dir)), Err(__e) => { libcc2rs::cpp2rust_errno().write(__e as i32); Ptr::null() From 635bbac92cf92c3c3178fcc51c11ccaa597948b6 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 17 Jul 2026 11:40:06 +0100 Subject: [PATCH 5/8] Revert "Drop the unnecessary_casts" This reverts commit 1d6add10d1035cccf4d886a87668ad0998f7ed3b. Useful for macos where the fields have different types than the ones declared in our shim. --- libcc2rs/src/libc_shims/stat.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index d8541c2a..792bff49 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -23,21 +23,22 @@ pub struct Stat { } impl Stat { + #[allow(clippy::unnecessary_cast)] pub fn from_libc(s: &::libc::stat) -> Self { Self { - st_dev: Rc::new(RefCell::new(s.st_dev)), - st_ino: Rc::new(RefCell::new(s.st_ino)), - st_nlink: Rc::new(RefCell::new(s.st_nlink)), - st_mode: Rc::new(RefCell::new(s.st_mode)), + st_dev: Rc::new(RefCell::new(s.st_dev as u64)), + st_ino: Rc::new(RefCell::new(s.st_ino as u64)), + st_nlink: Rc::new(RefCell::new(s.st_nlink as u64)), + st_mode: Rc::new(RefCell::new(s.st_mode as u32)), st_uid: Rc::new(RefCell::new(s.st_uid)), st_gid: Rc::new(RefCell::new(s.st_gid)), - st_rdev: Rc::new(RefCell::new(s.st_rdev)), - st_size: Rc::new(RefCell::new(s.st_size)), - st_blksize: Rc::new(RefCell::new(s.st_blksize)), - st_blocks: Rc::new(RefCell::new(s.st_blocks)), - st_atime: Rc::new(RefCell::new(s.st_atime)), - st_mtime: Rc::new(RefCell::new(s.st_mtime)), - st_ctime: Rc::new(RefCell::new(s.st_ctime)), + st_rdev: Rc::new(RefCell::new(s.st_rdev as u64)), + st_size: Rc::new(RefCell::new(s.st_size as i64)), + st_blksize: Rc::new(RefCell::new(s.st_blksize as i64)), + st_blocks: Rc::new(RefCell::new(s.st_blocks as i64)), + st_atime: Rc::new(RefCell::new(s.st_atime as i64)), + st_mtime: Rc::new(RefCell::new(s.st_mtime as i64)), + st_ctime: Rc::new(RefCell::new(s.st_ctime as i64)), } } } From 4f6bc2fe50a2e7f710701c9582c96c175e7fc41a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 18 Jul 2026 13:07:53 +0100 Subject: [PATCH 6/8] Set errno on getpwuid error --- rules/pwd/tgt_refcount.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rules/pwd/tgt_refcount.rs b/rules/pwd/tgt_refcount.rs index f9ed443f..8257ef1b 100644 --- a/rules/pwd/tgt_refcount.rs +++ b/rules/pwd/tgt_refcount.rs @@ -10,6 +10,10 @@ fn t1() -> libcc2rs::Passwd { fn f1(a0: u32) -> Ptr { match nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(a0)) { Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), - _ => Ptr::null(), + Ok(None) => Ptr::null(), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } } } From 679e2e32a0daa61dfd8db5df349da10120ac01d7 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 18 Jul 2026 13:34:39 +0100 Subject: [PATCH 7/8] Update tests --- tests/unit/out/refcount/libc_char_ptr_field.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/out/refcount/libc_char_ptr_field.rs b/tests/unit/out/refcount/libc_char_ptr_field.rs index 0fc7df85..f68896e5 100644 --- a/tests/unit/out/refcount/libc_char_ptr_field.rs +++ b/tests/unit/out/refcount/libc_char_ptr_field.rs @@ -15,7 +15,11 @@ fn main_0() -> i32 { nix::unistd::geteuid().as_raw(), )) { Ok(Some(__u)) => Ptr::alloc(Passwd::from_user(&__u)), - _ => Ptr::null(), + Ok(None) => Ptr::null(), + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + Ptr::null() + } }, )); if !!(*pw.borrow()).is_null() { From f808c20bb54203daf0873524ca3091899e7d828b Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 18 Jul 2026 14:11:54 +0100 Subject: [PATCH 8/8] Add localization todo --- rules/locale/tgt_refcount.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules/locale/tgt_refcount.rs b/rules/locale/tgt_refcount.rs index bb0921e9..0e432f58 100644 --- a/rules/locale/tgt_refcount.rs +++ b/rules/locale/tgt_refcount.rs @@ -3,6 +3,10 @@ use libcc2rs::*; +// Rust does not have support for localization. +// +// TODO: we need to track ourselves the locale settings and change the behavior of the relevant +// functions based on the set locale. fn f1(a0: i32, a1: Ptr) -> Ptr { Ptr::from_string_literal(b"C") }