[libc-commits] [libc] 57b0939 - [libc] Fix alarm layout mismatch on 32-bit time64 (#201276)

via libc-commits libc-commits at lists.llvm.org
Wed Jun 3 00:40:10 PDT 2026


Author: Jeff Bailey
Date: 2026-06-03T08:40:04+01:00
New Revision: 57b09398b60d6bc95993435e51989bfcc032ad49

URL: https://github.com/llvm/llvm-project/commit/57b09398b60d6bc95993435e51989bfcc032ad49
DIFF: https://github.com/llvm/llvm-project/commit/57b09398b60d6bc95993435e51989bfcc032ad49.diff

LOG: [libc] Fix alarm layout mismatch on 32-bit time64 (#201276)

Fixed alarm implementation on 32-bit architectures with 64-bit time_t
(like RISC-V 32-bit). The SYS_setitimer syscall on these platforms
expects the legacy 32-bit struct itimerval (with 32-bit tv_sec and
tv_usec). Convert the arguments to this layout before invoking the
syscall to avoid the kernel misinterpreting the timeout.

Assisted-by: Automated tooling, human reviewed.

Added: 
    

Modified: 
    libc/src/unistd/linux/alarm.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/unistd/linux/alarm.cpp b/libc/src/unistd/linux/alarm.cpp
index b4c80bb484c71..f849e487a3f96 100644
--- a/libc/src/unistd/linux/alarm.cpp
+++ b/libc/src/unistd/linux/alarm.cpp
@@ -30,16 +30,29 @@ LLVM_LIBC_FUNCTION(unsigned int, alarm, (unsigned int seconds)) {
   return static_cast<unsigned int>(
       LIBC_NAMESPACE::syscall_impl<long>(SYS_alarm, seconds));
 #elif defined(SYS_setitimer)
-  struct itimerval itv, old_itv;
-  itv.it_interval.tv_sec = 0;
-  itv.it_interval.tv_usec = 0;
-  itv.it_value.tv_sec = seconds;
-  itv.it_value.tv_usec = 0;
-  if (LIBC_NAMESPACE::syscall_impl<int>(SYS_setitimer, 0 /* ITIMER_REAL */,
-                                        &itv, &old_itv) < 0)
-    return 0;
-  return static_cast<unsigned int>(old_itv.it_value.tv_sec +
-                                   (old_itv.it_value.tv_usec > 0 ? 1 : 0));
+  // On 32-bit architectures with 64-bit time_t, SYS_setitimer still expects
+  // 32-bit fields. We must convert itimerval to use 32-bit fields.
+  if constexpr (sizeof(time_t) > sizeof(long)) {
+    long itv32[4] = {0, 0, static_cast<long>(seconds), 0};
+    long old_itv32[4];
+    long ret = LIBC_NAMESPACE::syscall_impl<long>(
+        SYS_setitimer, 0 /* ITIMER_REAL */, itv32, old_itv32);
+    if (ret < 0)
+      return 0;
+    return static_cast<unsigned int>(old_itv32[2] + (old_itv32[3] > 0 ? 1 : 0));
+  } else {
+    struct itimerval itv, old_itv;
+    itv.it_interval.tv_sec = 0;
+    itv.it_interval.tv_usec = 0;
+    itv.it_value.tv_sec = seconds;
+    itv.it_value.tv_usec = 0;
+    long ret = LIBC_NAMESPACE::syscall_impl<long>(
+        SYS_setitimer, 0 /* ITIMER_REAL */, &itv, &old_itv);
+    if (ret < 0)
+      return 0;
+    return static_cast<unsigned int>(old_itv.it_value.tv_sec +
+                                     (old_itv.it_value.tv_usec > 0 ? 1 : 0));
+  }
 #else
 #error "alarm implementation not available for this architecture"
 #endif


        


More information about the libc-commits mailing list