1b8a62b91Sopenharmony_ci/// Test that `Timespec` and `Secs` support a 64-bit number of seconds, 2b8a62b91Sopenharmony_ci/// avoiding the y2038 bug. 3b8a62b91Sopenharmony_ci/// 4b8a62b91Sopenharmony_ci/// The Rust Musl target and libc crate are currently using Musl 1.1. It is 5b8a62b91Sopenharmony_ci/// expected to update to Musl 1.2 at some point, at which point it'll gain a 6b8a62b91Sopenharmony_ci/// 64-bit `time_t`. 7b8a62b91Sopenharmony_ci/// 8b8a62b91Sopenharmony_ci/// 32-bit Android is [not y2038 compatible]. In theory we could use 9b8a62b91Sopenharmony_ci/// `libc::syscall` and call the new syscalls ourselves, however that doesn't 10b8a62b91Sopenharmony_ci/// seem worth the effort on a platform that will likely never support add 11b8a62b91Sopenharmony_ci/// such support itself. 12b8a62b91Sopenharmony_ci/// 13b8a62b91Sopenharmony_ci/// [not y2038 compatible]: https://android.googlesource.com/platform/bionic/+/refs/heads/master/docs/32-bit-abi.md#is-32_bit-on-lp32-y2038 14b8a62b91Sopenharmony_ci#[cfg(not(all(target_env = "musl", target_pointer_width = "32")))] 15b8a62b91Sopenharmony_ci#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] 16b8a62b91Sopenharmony_ci#[cfg(not(all(target_os = "emscripten", target_pointer_width = "32")))] 17b8a62b91Sopenharmony_ci#[cfg(not(all(target_os = "linux", target_arch = "sparc")))] 18b8a62b91Sopenharmony_ci#[test] 19b8a62b91Sopenharmony_cifn test_y2038() { 20b8a62b91Sopenharmony_ci use rustix::time::{Secs, Timespec}; 21b8a62b91Sopenharmony_ci 22b8a62b91Sopenharmony_ci let tv_sec: i64 = 0; 23b8a62b91Sopenharmony_ci let _ = Timespec { tv_sec, tv_nsec: 0 }; 24b8a62b91Sopenharmony_ci let _: Secs = tv_sec; 25b8a62b91Sopenharmony_ci 26b8a62b91Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] 27b8a62b91Sopenharmony_ci { 28b8a62b91Sopenharmony_ci use rustix::time::Itimerspec; 29b8a62b91Sopenharmony_ci 30b8a62b91Sopenharmony_ci let _ = Itimerspec { 31b8a62b91Sopenharmony_ci it_interval: Timespec { tv_sec, tv_nsec: 0 }, 32b8a62b91Sopenharmony_ci it_value: Timespec { tv_sec, tv_nsec: 0 }, 33b8a62b91Sopenharmony_ci }; 34b8a62b91Sopenharmony_ci } 35b8a62b91Sopenharmony_ci} 36b8a62b91Sopenharmony_ci 37b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] 38b8a62b91Sopenharmony_ci#[test] 39b8a62b91Sopenharmony_cifn test_y2038_with_timerfd() { 40b8a62b91Sopenharmony_ci use rustix::time::{ 41b8a62b91Sopenharmony_ci timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags, 42b8a62b91Sopenharmony_ci TimerfdTimerFlags, Timespec, 43b8a62b91Sopenharmony_ci }; 44b8a62b91Sopenharmony_ci 45b8a62b91Sopenharmony_ci let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); 46b8a62b91Sopenharmony_ci 47b8a62b91Sopenharmony_ci let set = Itimerspec { 48b8a62b91Sopenharmony_ci it_interval: Timespec { 49b8a62b91Sopenharmony_ci tv_sec: (1_u64 << 32) as _, 50b8a62b91Sopenharmony_ci tv_nsec: 20, 51b8a62b91Sopenharmony_ci }, 52b8a62b91Sopenharmony_ci it_value: Timespec { 53b8a62b91Sopenharmony_ci tv_sec: (1_u64 << 32) as _, 54b8a62b91Sopenharmony_ci tv_nsec: 21, 55b8a62b91Sopenharmony_ci }, 56b8a62b91Sopenharmony_ci }; 57b8a62b91Sopenharmony_ci let _old: Itimerspec = match timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set) { 58b8a62b91Sopenharmony_ci Ok(i) => i, 59b8a62b91Sopenharmony_ci 60b8a62b91Sopenharmony_ci // On 32-bit and mips64 platforms, accept `EOVERFLOW`, meaning that 61b8a62b91Sopenharmony_ci // y2038 support in `timerfd` APIs is not available on this platform 62b8a62b91Sopenharmony_ci // or this version of the platform. 63b8a62b91Sopenharmony_ci #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] 64b8a62b91Sopenharmony_ci Err(rustix::io::Errno::OVERFLOW) => return, 65b8a62b91Sopenharmony_ci 66b8a62b91Sopenharmony_ci Err(err) => panic!("unexpected error: {:?}", err), 67b8a62b91Sopenharmony_ci }; 68b8a62b91Sopenharmony_ci 69b8a62b91Sopenharmony_ci let new = timerfd_gettime(&fd).unwrap(); 70b8a62b91Sopenharmony_ci 71b8a62b91Sopenharmony_ci // The timer counts down. 72b8a62b91Sopenharmony_ci assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); 73b8a62b91Sopenharmony_ci assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); 74b8a62b91Sopenharmony_ci assert!(new.it_value.tv_sec <= set.it_value.tv_sec); 75b8a62b91Sopenharmony_ci assert!( 76b8a62b91Sopenharmony_ci new.it_value.tv_nsec < set.it_value.tv_nsec || new.it_value.tv_sec < set.it_value.tv_sec 77b8a62b91Sopenharmony_ci ); 78b8a62b91Sopenharmony_ci} 79