[libc-commits] [libc] [libc] Assorted improvements to [gs]etitimer (PR #206974)

via libc-commits libc-commits at lists.llvm.org
Wed Jul 1 06:07:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Pavel Labath (labath)

<details>
<summary>Changes</summary>

This started out as a patch adding a syscall wrapper for the two functions. It still does that, but along the way I (or rather AI) discovered an edge case in the truncation of microsecond values, where we could turn bogus values into seemingly valid ones by throwing away the high-order bits.

Additionally, when writing a test case, I noticed that the (64-bit) kernel returns EINVAL for these out-or-range values. Our check returns EOVERFLOW in this case, so I also change our error code in order to provide an uniform behavior for the test case.

Neither of these (the check and the EINVAL error code) are present in glibc (which lets truncated usec values through and returns EOVERFLOW on second truncation), but I think it's better to be consistent with the 64-bit behavior. The EOVERFLOW error also has no foundation in POSIX whereas EINVAL is mentioned as an error for invalid microseconds.

While in there, I also define ITIMER_REAL, ITIMER_VIRTUAL, and ITIMER_PROF in linux/sys-time-macros.h and update code to use them instead of raw numbers.

Assisted by Gemini.

---

Patch is 23.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/206974.diff


16 Files Affected:

- (modified) libc/hdr/CMakeLists.txt (+9) 
- (added) libc/hdr/sys_time_macros.h (+22) 
- (modified) libc/include/llvm-libc-macros/linux/sys-time-macros.h (+5) 
- (modified) libc/include/sys/time.yaml (+6) 
- (modified) libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt (+43) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h (+49) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h (+55) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h (+82) 
- (modified) libc/src/sys/time/linux/CMakeLists.txt (+2-2) 
- (modified) libc/src/sys/time/linux/getitimer.cpp (+5-26) 
- (modified) libc/src/sys/time/linux/setitimer.cpp (+5-48) 
- (modified) libc/src/unistd/linux/CMakeLists.txt (+1-3) 
- (modified) libc/src/unistd/linux/alarm.cpp (+5-38) 
- (modified) libc/test/src/sys/time/CMakeLists.txt (+2) 
- (modified) libc/test/src/sys/time/getitimer_test.cpp (+2-1) 
- (modified) libc/test/src/sys/time/setitimer_test.cpp (+27-2) 


``````````diff
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index cf3e76d5c005b..4476638c36f52 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -212,6 +212,15 @@ add_proxy_header_library(
     libc.include.llvm-libc-macros.sys_ptrace_macros
 )
 
+add_proxy_header_library(
+  sys_time_macros
+  HDRS
+    sys_time_macros.h
+  FULL_BUILD_DEPENDS
+    libc.include.sys_time
+    libc.include.llvm-libc-macros.sys_time_macros
+)
+
 add_header_library(unistd_overlay HDRS unistd_overlay.h)
 add_proxy_header_library(
   unistd_macros
diff --git a/libc/hdr/sys_time_macros.h b/libc/hdr/sys_time_macros.h
new file mode 100644
index 0000000000000..e54a659bce29a
--- /dev/null
+++ b/libc/hdr/sys_time_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros from sys/time.h ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_SYS_TIME_MACROS_H
+#define LLVM_LIBC_HDR_SYS_TIME_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/sys-time-macros.h"
+
+#else // Overlay mode
+
+#include <sys/time.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_SYS_TIME_MACROS_H
diff --git a/libc/include/llvm-libc-macros/linux/sys-time-macros.h b/libc/include/llvm-libc-macros/linux/sys-time-macros.h
index e97819594adcb..677eab50ba098 100644
--- a/libc/include/llvm-libc-macros/linux/sys-time-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-time-macros.h
@@ -9,6 +9,11 @@
 #ifndef LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
 #define LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H
 
+// Timer types for setitimer(2).
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
 // Add two timevals and put the result in timeval_ptr_result. If the resulting
 // usec value is greater than 999,999 then the microseconds are turned into full
 // seconds (1,000,000 is subtracted from usec and 1 is added to sec).
diff --git a/libc/include/sys/time.yaml b/libc/include/sys/time.yaml
index f1dcdff354652..5869646a003cd 100644
--- a/libc/include/sys/time.yaml
+++ b/libc/include/sys/time.yaml
@@ -2,6 +2,12 @@ header: sys/time.h
 standards:
   - posix
 macros:
+  - macro_name: ITIMER_REAL
+    macro_header: sys-time-macros.h
+  - macro_name: ITIMER_VIRTUAL
+    macro_header: sys-time-macros.h
+  - macro_name: ITIMER_PROF
+    macro_header: sys-time-macros.h
   - macro_name: timeradd
     macro_header: sys-time-macros.h
 types:
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index f3282c315d9a9..1ce1862df1895 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -1,3 +1,18 @@
+add_header_library(
+  alarm
+  HDRS
+    alarm.h
+  DEPENDS
+    libc.hdr.sys_time_macros
+    libc.hdr.types.struct_itimerval
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+)
+
 add_header_library(
   getrandom
   HDRS
@@ -245,6 +260,34 @@ add_header_library(
     libc.include.sys_syscall
 )
 
+add_header_library(
+  getitimer
+  HDRS
+    getitimer.h
+  DEPENDS
+    libc.hdr.types.struct_itimerval
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+)
+
+add_header_library(
+  setitimer
+  HDRS
+    setitimer.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.types.struct_itimerval
+    libc.include.sys_syscall
+    libc.src.__support.CPP.limits
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+)
+
 add_header_library(
   setsockopt
   HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h
new file mode 100644
index 0000000000000..68a1ba5e69447
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h
@@ -0,0 +1,49 @@
+//===-- Implementation header for alarm -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for alarm.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H
+
+#include "hdr/sys_time_macros.h"
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<unsigned int> alarm(unsigned int seconds) {
+#ifdef SYS_alarm
+  return syscall_checked<unsigned int>(SYS_alarm, seconds);
+#elif defined(SYS_setitimer)
+  struct itimerval old_itv;
+  struct itimerval itv = {};
+  itv.it_value.tv_sec = seconds;
+  ErrorOr<int> ret = setitimer(ITIMER_REAL, &itv, &old_itv);
+  if (!ret)
+    return Error(ret.error());
+  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
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h
new file mode 100644
index 0000000000000..c9c5384d0b6a9
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h
@@ -0,0 +1,55 @@
+//===-- Implementation header for getitimer ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getitimer.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H
+
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> getitimer(int which, struct itimerval *curr_val) {
+  if constexpr (sizeof(time_t) == sizeof(long)) {
+    return syscall_checked<int>(SYS_getitimer, which, curr_val);
+  } else {
+    // There is no SYS_getitimer_time64 call, so we can't use time_t directly,
+    // and need to convert from long first.
+    long curr_val32[4];
+    long *curr_val32_ptr = curr_val ? curr_val32 : nullptr;
+
+    ErrorOr<int> ret =
+        syscall_checked<int>(SYS_getitimer, which, curr_val32_ptr);
+
+    if (!ret)
+      return ret;
+
+    if (curr_val) {
+      curr_val->it_interval.tv_sec = curr_val32[0];
+      curr_val->it_interval.tv_usec = curr_val32[1];
+      curr_val->it_value.tv_sec = curr_val32[2];
+      curr_val->it_value.tv_usec = curr_val32[3];
+    }
+    return ret;
+  }
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h
new file mode 100644
index 0000000000000..48f1887bc29ab
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h
@@ -0,0 +1,82 @@
+//===-- Implementation header for setitimer ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setitimer.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setitimer(int which, const struct itimerval *new_val,
+                                   struct itimerval *old_val) {
+  if constexpr (sizeof(time_t) == sizeof(long)) {
+    return syscall_checked<int>(SYS_setitimer, which, new_val, old_val);
+  } else {
+    // There is no SYS_setitimer_time64 call, so we can't use time_t directly,
+    // and need to convert it to long first.
+    long old_val32[4];
+    long *old_val32_ptr = old_val ? old_val32 : nullptr;
+    long new_val32[4];
+    long *new_val32_ptr = nullptr;
+
+    if (new_val) {
+      // Check for overflow before casting to 32-bit long. We'll let the kernel
+      // do the final validation. We're just making sure the truncation does not
+      // change the value.
+      auto fits_long = [](auto val) {
+        return val <= cpp::numeric_limits<long>::max() &&
+               val >= cpp::numeric_limits<long>::min();
+      };
+      if (!fits_long(new_val->it_interval.tv_sec) ||
+          !fits_long(new_val->it_value.tv_sec) ||
+          !fits_long(new_val->it_interval.tv_usec) ||
+          !fits_long(new_val->it_value.tv_usec)) {
+        return Error(EINVAL);
+      }
+
+      new_val32[0] = static_cast<long>(new_val->it_interval.tv_sec);
+      new_val32[1] = static_cast<long>(new_val->it_interval.tv_usec);
+      new_val32[2] = static_cast<long>(new_val->it_value.tv_sec);
+      new_val32[3] = static_cast<long>(new_val->it_value.tv_usec);
+      new_val32_ptr = new_val32;
+    }
+
+    ErrorOr<int> ret = syscall_checked<int>(SYS_setitimer, which, new_val32_ptr,
+                                            old_val32_ptr);
+
+    if (!ret)
+      return ret;
+
+    if (old_val) {
+      old_val->it_interval.tv_sec = old_val32[0];
+      old_val->it_interval.tv_usec = old_val32[1];
+      old_val->it_value.tv_sec = old_val32[2];
+      old_val->it_value.tv_usec = old_val32[3];
+    }
+    return ret;
+  }
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H
diff --git a/libc/src/sys/time/linux/CMakeLists.txt b/libc/src/sys/time/linux/CMakeLists.txt
index 60fbd14f73174..36452dfdea5b6 100644
--- a/libc/src/sys/time/linux/CMakeLists.txt
+++ b/libc/src/sys/time/linux/CMakeLists.txt
@@ -24,7 +24,7 @@ add_entrypoint_object(
     ../setitimer.h
   DEPENDS
     libc.hdr.types.struct_itimerval
-    libc.include.sys_syscall
+    libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer
     libc.src.__support.OSUtil.osutil
     libc.src.__support.common 
     libc.src.errno.errno
@@ -38,7 +38,7 @@ add_entrypoint_object(
     ../getitimer.h
   DEPENDS
     libc.hdr.types.struct_itimerval
-    libc.include.sys_syscall
+    libc.src.__support.OSUtil.linux.syscall_wrappers.getitimer
     libc.src.__support.OSUtil.osutil
     libc.src.__support.common 
     libc.src.errno.errno
diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp
index 2a40491bc95fb..f875bc9b13b7e 100644
--- a/libc/src/sys/time/linux/getitimer.cpp
+++ b/libc/src/sys/time/linux/getitimer.cpp
@@ -7,38 +7,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/sys/time/getitimer.h"
-#include "hdr/types/struct_itimerval.h"
-#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getitimer.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
-#include <sys/syscall.h>
+#include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) {
-  long ret = 0;
-  if constexpr (sizeof(time_t) > sizeof(long)) {
-    // There is no SYS_getitimer_time64 call, so we can't use time_t directly.
-    if (curr_value) {
-      long curr_value32[4];
-      ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which,
-                                               curr_value32);
-      if (!ret) {
-        curr_value->it_interval.tv_sec = curr_value32[0];
-        curr_value->it_interval.tv_usec = curr_value32[1];
-        curr_value->it_value.tv_sec = curr_value32[2];
-        curr_value->it_value.tv_usec = curr_value32[3];
-      }
-    } else {
-      ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, nullptr);
-    }
-  } else {
-    ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
-  }
-
-  // On failure, return -1 and set errno.
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  ErrorOr<int> ret = linux_syscalls::getitimer(which, curr_value);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp
index 2c2f0d7198204..07cb9180a7f7e 100644
--- a/libc/src/sys/time/linux/setitimer.cpp
+++ b/libc/src/sys/time/linux/setitimer.cpp
@@ -6,62 +6,19 @@
 //
 //===----------------------------------------------------------------------===//
 #include "src/sys/time/setitimer.h"
-#include "hdr/errno_macros.h"
-#include "hdr/types/struct_itimerval.h"
-#include "src/__support/CPP/limits.h"
-#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
-#include <sys/syscall.h>
+#include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, setitimer,
                    (int which, const struct itimerval *new_value,
                     struct itimerval *old_value)) {
-  long ret = 0;
-  if constexpr (sizeof(time_t) > sizeof(long)) {
-    // There is no SYS_setitimer_time64 call, so we can't use time_t directly,
-    // and need to convert it to long first.
-    long old_value32[4];
-    long *old_value32_ptr = old_value ? old_value32 : nullptr;
-
-    if (new_value) {
-      // Check for overflow before casting to 32-bit long.
-      if (new_value->it_interval.tv_sec > cpp::numeric_limits<long>::max() ||
-          new_value->it_interval.tv_sec < cpp::numeric_limits<long>::min() ||
-          new_value->it_value.tv_sec > cpp::numeric_limits<long>::max() ||
-          new_value->it_value.tv_sec < cpp::numeric_limits<long>::min()) {
-        libc_errno = EOVERFLOW;
-        return -1;
-      }
-
-      long new_value32[4] = {static_cast<long>(new_value->it_interval.tv_sec),
-                             static_cast<long>(new_value->it_interval.tv_usec),
-                             static_cast<long>(new_value->it_value.tv_sec),
-                             static_cast<long>(new_value->it_value.tv_usec)};
-
-      ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which,
-                                               new_value32, old_value32_ptr);
-    } else {
-      ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, nullptr,
-                                               old_value32_ptr);
-    }
-
-    if (!ret && old_value) {
-      old_value->it_interval.tv_sec = old_value32[0];
-      old_value->it_interval.tv_usec = old_value32[1];
-      old_value->it_value.tv_sec = old_value32[2];
-      old_value->it_value.tv_usec = old_value32[3];
-    }
-  } else {
-    ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
-                                             old_value);
-  }
-
-  // On failure, return -1 and set errno.
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  ErrorOr<int> ret = linux_syscalls::setitimer(which, new_value, old_value);
+  if (!ret) {
+    libc_errno = ret.error();
     return -1;
   }
   return 0;
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index af385e9bbed72..168b61bede853 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -5,9 +5,7 @@ add_entrypoint_object(
   HDRS
     ../alarm.h
   DEPENDS
-    libc.hdr.types.struct_itimerval
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.linux.syscall_wrappers.alarm
     libc.src.__support.common
     libc.src.__support.macros.config
 )
diff --git a/libc/src/unistd/linux/alarm.cpp b/libc/src/unistd/linux/alarm.cpp
index f849e487a3f96..bc2febff0248f 100644
--- a/libc/src/unistd/linux/alarm.cpp
+++ b/libc/src/unistd/linux/alarm.cpp
@@ -12,50 +12,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/unistd/alarm.h"
-
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/linux/syscall_wrappers/alarm.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 
-#include <sys/syscall.h> // For syscall numbers.
-
-#ifndef SYS_alarm
-#include "hdr/types/struct_itimerval.h"
-#endif
-
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(unsigned int, alarm, (unsigned int seconds)) {
-#ifdef SYS_alarm
-  return static_cast<unsigned int>(
-      LIBC_NAMESPACE::syscall_impl<long>(SYS_alarm, seconds));
-#elif defined(SYS_setitimer)
-  // 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
+  ErrorOr<unsigned int> ret = linux_syscalls::alarm(seconds);
+  if (!ret)
+    return 0;
+  return ret.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/sys/time/CMakeLists.txt b/libc/test/src/sys/time/CMakeLists.txt
index 2468b4ae2cc34..eb9753bb5bf2d 100644
--- a/libc/test/src/sys/time/CMakeLists.txt
+++ b/libc/test/src/sys/time/CMakeLists.txt
@@ -27,6 +27,7 @@ ad...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/206974


More information about the libc-commits mailing list