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
1 change: 1 addition & 0 deletions libc-dep/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2024"
[dependencies]
libc = "0.2"
nix = { version = "0.30", features = ["socket", "net", "fs", "poll", "time", "user", "dir", "term", "event", "hostname"] }
jiff = "0.2"
1 change: 1 addition & 0 deletions libcc2rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2024"
libcc2rs-macros = { path = "../libcc2rs-macros", version = "0.1.0" }
libc = "0.2"
nix = { version = "0.30", features = ["socket", "net", "fs", "poll", "time", "user", "dir", "term", "event", "hostname"] }
jiff = "0.2"
34 changes: 34 additions & 0 deletions libcc2rs/src/libc_shims/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,40 @@ pub struct Tm {
pub tm_zone: Value<Ptr<u8>>,
}

impl Tm {
pub fn from_zoned(dt: &jiff::Zoned) -> Self {
let tm = Tm::default();
*tm.tm_sec.borrow_mut() = dt.second() as i32;
*tm.tm_min.borrow_mut() = dt.minute() as i32;
*tm.tm_hour.borrow_mut() = dt.hour() as i32;
*tm.tm_mday.borrow_mut() = dt.day() as i32;
*tm.tm_mon.borrow_mut() = dt.month() as i32 - 1;
*tm.tm_year.borrow_mut() = dt.year() as i32 - 1900;
*tm.tm_wday.borrow_mut() = dt.weekday().to_sunday_zero_offset() as i32;
*tm.tm_yday.borrow_mut() = dt.day_of_year() as i32 - 1;
*tm.tm_isdst.borrow_mut() = 0;
*tm.tm_gmtoff.borrow_mut() = dt.offset().seconds() as i64;
#[cfg(target_os = "linux")]
let zone: &'static [u8] = b"GMT";
#[cfg(target_os = "macos")]
let zone: &'static [u8] = b"UTC";
*tm.tm_zone.borrow_mut() = Ptr::from_string_literal(zone);
tm
}

pub fn to_civil(&self) -> Result<jiff::civil::DateTime, jiff::Error> {
jiff::civil::DateTime::new(
(*self.tm_year.borrow() + 1900) as i16,
(*self.tm_mon.borrow() + 1) as i8,
*self.tm_mday.borrow() as i8,
*self.tm_hour.borrow() as i8,
*self.tm_min.borrow() as i8,
*self.tm_sec.borrow() as i8,
0,
)
}
}

impl Clone for Tm {
fn clone(&self) -> Self {
Self {
Expand Down
9 changes: 8 additions & 1 deletion rule-preprocessor/src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ fn build_rustc_args(crate_root: &Path) -> Vec<String> {
args.push("-L".to_string());
args.push(format!("dependency={}", deps.display()));

for dep in &["libcc2rs", "libc", "brotli_sys", "rustls_ffi", "nix"] {
for dep in &[
"libcc2rs",
"libc",
"brotli_sys",
"rustls_ffi",
"nix",
"jiff",
] {
if let Some(rlib) = find_rlib(deps.as_path(), dep) {
args.push("--extern".to_string());
args.push(format!("{}={}", dep, rlib.display()));
Expand Down
1 change: 1 addition & 0 deletions rules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ libcc2rs = { version = "0.1.0", path = "../libcc2rs" }
brotli-sys = "0.3"
rustls-ffi = { version = "0.15.3", default-features = false }
nix = { version = "0.30", features = ["socket", "net", "fs", "poll", "time", "user", "dir", "term", "event", "hostname"] }
jiff = "0.2"
4 changes: 4 additions & 0 deletions rules/time/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ int f8(struct timeval *tv, void *tz) {
#else
#error "Unsupported platform for gettimeofday"
#endif

clockid_t f9() {
return CLOCK_REALTIME;
}
136 changes: 136 additions & 0 deletions rules/time/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,139 @@ fn t2() -> libcc2rs::Timeval {
fn t3() -> libcc2rs::Timespec {
Default::default()
}

fn f1(a0: Ptr<::libc::time_t>) -> ::libc::time_t {
let __out = a0;
match nix::time::clock_gettime(nix::time::ClockId::CLOCK_REALTIME) {
Ok(__ts) => {
let __s = __ts.tv_sec();
if !__out.is_null() {
__out.write(__s);
}
__s
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}

fn f2(a0: nix::time::ClockId, a1: Ptr<Timespec>) -> i32 {
match nix::time::clock_gettime(a0) {
Ok(__ts) => {
a1.with_mut(|__t| {
*__t.tv_sec.borrow_mut() = __ts.tv_sec() as i64;
*__t.tv_nsec.borrow_mut() = __ts.tv_nsec() as i64;
});
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}

fn f4(a0: Ptr<::libc::time_t>, a1: Ptr<Tm>) -> Ptr<Tm> {
let __res = a1.clone();
match jiff::Timestamp::from_second(a0.read()) {
Ok(__ts) => {
let __dt = __ts.to_zoned(jiff::tz::TimeZone::UTC);
__res.with_mut(|__tm| *__tm = Tm::from_zoned(&__dt));
__res
}
Err(_) => {
libcc2rs::cpp2rust_errno().write(::libc::EOVERFLOW);
Ptr::null()
}
}
}

fn f6(a0: Ptr<u8>, a1: usize, a2: Ptr<u8>, a3: Ptr<Tm>) -> usize {
let __dt = a3.with(|__tm| __tm.to_civil());
let __text = match __dt {
Ok(__d) => {
jiff::fmt::strtime::format(a2.to_rust_string().as_str(), __d).unwrap_or_default()
}
Err(_) => String::new(),
};
if __text.is_empty() || __text.len() + 1 > a1 {
0
} else {
let mut __dst = a0.clone();
for __b in __text.as_bytes() {
__dst.write(*__b);
__dst += 1;
}
__dst.write(0);
__text.len()
}
}

fn f7(a0: Ptr<u8>, a1: Ptr<Timeval>) -> i32 {
let __times = a1;
let __at = __times.with(|__tv| {
nix::sys::time::TimeVal::new(
*__tv.tv_sec.borrow() as ::libc::time_t,
*__tv.tv_usec.borrow() as ::libc::suseconds_t,
)
});
let __mt = __times.offset(1).with(|__tv| {
nix::sys::time::TimeVal::new(
*__tv.tv_sec.borrow() as ::libc::time_t,
*__tv.tv_usec.borrow() as ::libc::suseconds_t,
)
});
match nix::sys::stat::utimes(a0.to_rust_string().as_str(), &__at, &__mt) {
Ok(()) => 0,
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}

// a1 is ignored intentionally, see: https://man7.org/linux/man-pages/man2/gettimeofday.2.html
//
// "The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL."
#[cfg(target_os = "linux")]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the implementation seems to be the same in linux and mac; why do we need both?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the signature is different between linux and macos. Linux receives a struct timezone pointer, macos receives a void pointer:

https://man7.org/linux/man-pages/man2/gettimeofday.2.html
https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/gettimeofday.2.html

fn f8(a0: Ptr<Timeval>, a1: Ptr<::libc::timezone>) -> i32 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with this 2nd parameter?

match nix::time::clock_gettime(nix::time::ClockId::CLOCK_REALTIME) {
Ok(__ts) => {
a0.with_mut(|__tv| {
*__tv.tv_sec.borrow_mut() = __ts.tv_sec() as i64;
*__tv.tv_usec.borrow_mut() = (__ts.tv_nsec() / 1000) as i64;
});
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}

// a1 is ignored intentionally, see: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/gettimeofday.2.html
//
// "Note: timezone is no longer used; this information is kept outside the kernel."
#[cfg(target_os = "macos")]
fn f8(a0: Ptr<Timeval>, a1: AnyPtr) -> i32 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is ignoring the 2nd parameter. At least it should have a TODO.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both man pages (linux and macos) say that the second param is obsolete. I will add a comment about that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment about that

match nix::time::clock_gettime(nix::time::ClockId::CLOCK_REALTIME) {
Ok(__ts) => {
a0.with_mut(|__tv| {
*__tv.tv_sec.borrow_mut() = __ts.tv_sec() as i64;
*__tv.tv_usec.borrow_mut() = (__ts.tv_nsec() / 1000) as i64;
});
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}

unsafe fn f9() -> nix::time::ClockId {
nix::time::ClockId::CLOCK_REALTIME
}
4 changes: 4 additions & 0 deletions rules/time/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ unsafe fn f8(a0: *mut libc::timeval, a1: *mut libc::timezone) -> i32 {
unsafe fn f8(a0: *mut libc::timeval, a1: *mut libc::c_void) -> i32 {
libc::gettimeofday(a0, a1)
}

unsafe fn f9() -> libc::clockid_t {
libc::CLOCK_REALTIME
}
6 changes: 6 additions & 0 deletions tests/lit/lit/formats/Cpp2RustTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ def build_rust(self):
libc_dep_deps.glob("libnix-*.rlib"),
key=lambda p: p.stat().st_mtime,
)
jiff_rlib = max(
libc_dep_deps.glob("libjiff-*.rlib"),
key=lambda p: p.stat().st_mtime,
)
cmd = [
"rustc",
"+" + read_rust_version(),
Expand Down Expand Up @@ -240,6 +244,8 @@ def build_rust(self):
f"libc={libc_rlib}",
"--extern",
f"nix={nix_rlib}",
"--extern",
f"jiff={jiff_rlib}",
]
_, err, returncode = lit.util.executeCommand(cmd, str(self.tmp_dir))
if exp.should_not_compile:
Expand Down
Loading
Loading