[libc-commits] [libc] [libc] Fix alarm layout mismatch on 32-bit time64 (PR #201276)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Tue Jun 2 23:47:54 PDT 2026
https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/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.
>From 6e9d755f76d0fbfe255f5f46514ea2a6bbebde6d Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Wed, 3 Jun 2026 07:35:36 +0100
Subject: [PATCH] [libc] Fix alarm layout mismatch on 32-bit time64
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.
---
libc/src/unistd/linux/alarm.cpp | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
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