about summary refs log tree commit diff
path: root/library/std/src/sys/unix/time.rs
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2022-03-09 12:41:47 -0800
committerJosh Stone <jistone@redhat.com>2022-05-06 08:50:53 -0700
commit97b49a0cc5bea5845dc89c1598a32d7f9fea985a (patch)
tree45f43bc1b74cc408abb852fcf7e4e4e64ed6bdb2 /library/std/src/sys/unix/time.rs
parentbee923f0df0e4a568811e24dc74af77c464d10f3 (diff)
downloadrust-97b49a0cc5bea5845dc89c1598a32d7f9fea985a.tar.gz
rust-97b49a0cc5bea5845dc89c1598a32d7f9fea985a.zip
Use __clock_gettime64 on 32-bit linux-gnu
Diffstat (limited to 'library/std/src/sys/unix/time.rs')
-rw-r--r--library/std/src/sys/unix/time.rs27
1 files changed, 27 insertions, 0 deletions
diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs
index 6cf06848399..20d061206be 100644
--- a/library/std/src/sys/unix/time.rs
+++ b/library/std/src/sys/unix/time.rs
@@ -339,6 +339,33 @@ mod inner {
 
     impl Timespec {
         pub fn now(clock: clock_t) -> Timespec {
+            // Try to use 64-bit time in preparation for Y2038.
+            #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))]
+            {
+                use crate::sys::weak::weak;
+
+                // __clock_gettime64 was added to 32-bit arches in glibc 2.34,
+                // and it handles both vDSO calls and ENOSYS fallbacks itself.
+                weak!(fn __clock_gettime64(libc::clockid_t, *mut __timespec64) -> libc::c_int);
+
+                #[repr(C)]
+                struct __timespec64 {
+                    tv_sec: i64,
+                    #[cfg(target_endian = "big")]
+                    _padding: i32,
+                    tv_nsec: i32,
+                    #[cfg(target_endian = "little")]
+                    _padding: i32,
+                }
+
+                if let Some(clock_gettime64) = __clock_gettime64.get() {
+                    let mut t = MaybeUninit::uninit();
+                    cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
+                    let t = unsafe { t.assume_init() };
+                    return Timespec { tv_sec: t.tv_sec, tv_nsec: t.tv_nsec as i64 };
+                }
+            }
+
             let mut t = MaybeUninit::uninit();
             cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap();
             Timespec::from(unsafe { t.assume_init() })