[libc-commits] [libc] [libc][POSIX] Add clock_settime() function for Linux (PR #161729)

Anton Shepelev via libc-commits libc-commits at lists.llvm.org
Mon Oct 27 22:39:47 PDT 2025


https://github.com/amemov updated https://github.com/llvm/llvm-project/pull/161729

>From 2c0ef107eea86381f17015fcd57c0b17d3c3cd22 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Thu, 2 Oct 2025 13:21:18 -0700
Subject: [PATCH 1/6] - Implemented a clock_settime syscall wrapper for Linux -
 Implemented unit-tests for the feature

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 libc/config/linux/riscv/entrypoints.txt       |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/docs/headers/time.rst                    |  2 +-
 libc/include/time.yaml                        |  7 +++
 libc/src/__support/time/CMakeLists.txt        |  7 +++
 libc/src/__support/time/clock_settime.h       | 22 ++++++++
 libc/src/__support/time/linux/CMakeLists.txt  | 15 ++++++
 .../__support/time/linux/clock_settime.cpp    | 53 +++++++++++++++++++
 libc/src/time/CMakeLists.txt                  |  8 +++
 libc/src/time/clock_settime.h                 | 22 ++++++++
 libc/src/time/linux/CMakeLists.txt            | 13 +++++
 libc/src/time/linux/clock_settime.cpp         | 30 +++++++++++
 libc/test/src/time/CMakeLists.txt             | 15 ++++++
 libc/test/src/time/clock_settime_test.cpp     | 31 +++++++++++
 15 files changed, 227 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/__support/time/clock_settime.h
 create mode 100644 libc/src/__support/time/linux/clock_settime.cpp
 create mode 100644 libc/src/time/clock_settime.h
 create mode 100644 libc/src/time/linux/clock_settime.cpp
 create mode 100644 libc/test/src/time/clock_settime_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 00c4b2ec0f828..605b76718fd64 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1142,6 +1142,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.ctime_r
     libc.src.time.clock
     libc.src.time.clock_gettime
+    libc.src.time.clock_settime
     libc.src.time.difftime
     libc.src.time.gettimeofday
     libc.src.time.gmtime
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 89e3653186d13..97cd7fdef7a07 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1267,6 +1267,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.ctime_r
     libc.src.time.clock
     libc.src.time.clock_gettime
+    libc.src.time.clock_settime
     libc.src.time.difftime
     libc.src.time.gettimeofday
     libc.src.time.gmtime
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0bb8a683c5b01..59357822ec537 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1305,6 +1305,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.time.ctime_r
     libc.src.time.clock
     libc.src.time.clock_gettime
+    libc.src.time.clock_settime
     libc.src.time.difftime
     libc.src.time.gettimeofday
     libc.src.time.gmtime
diff --git a/libc/docs/headers/time.rst b/libc/docs/headers/time.rst
index 55bc1a17ee285..00b0dd472de5c 100644
--- a/libc/docs/headers/time.rst
+++ b/libc/docs/headers/time.rst
@@ -71,7 +71,7 @@ Implementation Status
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | clock_nanosleep     |         |         |         |                 |         |         |         |         |         |         |         |         |         |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| clock_settime       |         |         |         |                 |         |         |         |         |         |         |         |         |         |
+| clock_settime       | |check| | |check| |         |     |check|     |         |         |         |         |         |         |         |         |         |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | ctime               | |check| | |check| |         |     |check|     |         |         |         |         |         |         |         |         |         |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
diff --git a/libc/include/time.yaml b/libc/include/time.yaml
index 2f8024298fad1..7b86838a7dca2 100644
--- a/libc/include/time.yaml
+++ b/libc/include/time.yaml
@@ -67,6 +67,13 @@ functions:
     arguments:
       - type: clockid_t
       - type: struct timespec *
+  - name: clock_settime
+    standard:
+      - POSIX
+    return_type: int
+    arguments:
+      - type: clockid_t
+      - type: const struct timespec *
   - name: difftime
     standard:
       - stdc
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 8247e792e8410..8dbcb914fcc5b 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -19,3 +19,10 @@ add_object_library(
   DEPENDS
     libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
 )
+
+add_object_library(
+  clock_settime
+  ALIAS
+  DEPENDS
+    libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
+)
diff --git a/libc/src/__support/time/clock_settime.h b/libc/src/__support/time/clock_settime.h
new file mode 100644
index 0000000000000..d8d305cadf4b9
--- /dev/null
+++ b/libc/src/__support/time/clock_settime.h
@@ -0,0 +1,22 @@
+//===--- clock_settime linux implementation ---------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_SETTIME_H
+#define LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_SETTIME_H
+
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/error_or.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+ErrorOr<int> clock_settime(clockid_t clockid, const timespec *ts);
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_SETTIME_H
diff --git a/libc/src/__support/time/linux/CMakeLists.txt b/libc/src/__support/time/linux/CMakeLists.txt
index 6fec7eeba99ad..478529502b403 100644
--- a/libc/src/__support/time/linux/CMakeLists.txt
+++ b/libc/src/__support/time/linux/CMakeLists.txt
@@ -14,6 +14,21 @@ add_object_library(
     libc.src.__support.OSUtil.linux.vdso
 )
 
+add_object_library(
+  clock_settime
+  HDRS
+    ../clock_settime.h
+  SRCS
+    clock_settime.cpp
+  DEPENDS
+    libc.include.sys_syscall
+    libc.hdr.types.struct_timespec
+    libc.hdr.types.clockid_t
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.OSUtil.osutil
+)
+
 add_header_library(
   clock_conversion
   HDRS
diff --git a/libc/src/__support/time/linux/clock_settime.cpp b/libc/src/__support/time/linux/clock_settime.cpp
new file mode 100644
index 0000000000000..d81889ebc469d
--- /dev/null
+++ b/libc/src/__support/time/linux/clock_settime.cpp
@@ -0,0 +1,53 @@
+//===--- clock_settime linux implementation ---------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/time/clock_settime.h"
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+#if defined(SYS_clock_settime64)
+#include <linux/time_types.h>
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+ErrorOr<int> clock_settime(clockid_t clockid, const timespec *ts) {
+  int ret;
+#if defined(SYS_clock_settime)
+  ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_settime,
+                                          static_cast<long>(clockid),
+                                          reinterpret_cast<long>(ts));
+#elif defined(SYS_clock_settime64)
+  static_assert(
+      sizeof(time_t) == sizeof(int64_t),
+      "SYS_clock_settime64 requires struct timespec with 64-bit members.");
+
+  __kernel_timespec ts64{};
+
+  ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_settime64,
+                                          static_cast<long>(clockid),
+                                          reinterpret_cast<long>(&ts64));
+  if (ret == 0) {
+    ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
+    ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
+  }
+#else
+#error "SYS_clock_settime and SYS_clock_settime64 syscalls not available."
+#endif
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index ec942e38d1af5..4d647c22c3239 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -245,3 +245,11 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.clock_getres
 )
+
+add_entrypoint_object(
+  clock_settime
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.clock_settime
+)
+
diff --git a/libc/src/time/clock_settime.h b/libc/src/time/clock_settime.h
new file mode 100644
index 0000000000000..9321dd1074101
--- /dev/null
+++ b/libc/src/time/clock_settime.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for clock_settime function --------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_TIME_CLOCK_SETTIME_H
+#define LLVM_LIBC_SRC_TIME_CLOCK_SETTIME_H
+
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int clock_settime(clockid_t clockid, const timespec *tp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_TIME_CLOCK_SETTIME_H
diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index a6ec7c7c06963..6ea04597063cb 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -54,6 +54,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  clock_settime
+  SRCS
+    clock_settime.cpp
+  HDRS
+    ../clock_settime.h
+  DEPENDS
+    libc.hdr.types.clockid_t
+    libc.hdr.types.struct_timespec
+    libc.src.__support.time.clock_settime
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   gettimeofday
   SRCS
diff --git a/libc/src/time/linux/clock_settime.cpp b/libc/src/time/linux/clock_settime.cpp
new file mode 100644
index 0000000000000..1f39ca6efa02d
--- /dev/null
+++ b/libc/src/time/linux/clock_settime.cpp
@@ -0,0 +1,30 @@
+//===---------- Linux implementation of the POSIX clock_settime function --===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock_settime.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/time/clock_settime.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, clock_settime,
+                   (clockid_t clockid, const struct timespec *ts)) {
+  auto result = internal::clock_settime(clockid, ts);
+
+  // A negative return value indicates an error with the magnitude of the
+  // value being the error code.
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 03e5428292418..c8e113f06d50b 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -124,6 +124,21 @@ add_libc_test(
     libc.src.time.clock_getres
 )
 
+add_libc_test(
+  clock_settime_test
+  SUITE
+    libc_time_unittests
+  SRCS
+    clock_settime_test.cpp
+  DEPENDS
+    libc.src.time.clock_settime
+    libc.hdr.types.time_t
+    libc.hdr.types.struct_timespec
+    libc.hdr.time_macros
+    libc.hdr.errno_macros
+    libc.test.UnitTest.ErrnoCheckingTest
+)
+
 add_libc_unittest(
   difftime_test
   SUITE
diff --git a/libc/test/src/time/clock_settime_test.cpp b/libc/test/src/time/clock_settime_test.cpp
new file mode 100644
index 0000000000000..881db1f75120d
--- /dev/null
+++ b/libc/test/src/time/clock_settime_test.cpp
@@ -0,0 +1,31 @@
+//===-- Unittests for clock_settime ---------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/time/clock_settime.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcClockSetTime = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+#ifdef CLOCK_MONOTONIC
+TEST_F(LlvmLibcClockSetTime, MonotonicIsNotSettable) {
+  timespec ts = {0, 0};
+  int result = LIBC_NAMESPACE::clock_settime(CLOCK_MONOTONIC, &ts);
+  ASSERT_EQ(result, -1);
+  ASSERT_ERRNO_EQ(EINVAL);
+}
+#endif // CLOCK_MONOTONIC
+
+TEST_F(LlvmLibcClockSetTime, InvalidClockId) {
+  timespec ts = {0, 0};
+  int result = LIBC_NAMESPACE::clock_settime(static_cast<clockid_t>(-1), &ts);
+  ASSERT_EQ(result, -1);
+  ASSERT_ERRNO_EQ(EINVAL);
+}

>From 06ac55c61287325c50011720b1be285cd7bee310 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Thu, 2 Oct 2025 13:49:43 -0700
Subject: [PATCH 2/6] - Fixed CMake to include the implementation only on Linux
 for now

---
 libc/src/__support/time/CMakeLists.txt | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 8dbcb914fcc5b..04744da3fc981 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -20,9 +20,11 @@ add_object_library(
     libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
 )
 
-add_object_library(
-  clock_settime
-  ALIAS
-  DEPENDS
-    libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
-)
+if(LIBC_TARGET_OS_IS_LINUX)
+  add_object_library(
+    clock_settime
+    ALIAS
+    DEPENDS
+      libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
+  )
+endif()

>From 7105bef4ec67c3f3a433005370591ca9bf79d31d Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Fri, 3 Oct 2025 09:04:17 -0700
Subject: [PATCH 3/6] - Changed CMake for clock_settime() to be more flexible
 for future targets

---
 libc/src/__support/time/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 04744da3fc981..3851037e4161f 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -20,7 +20,7 @@ add_object_library(
     libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
 )
 
-if(LIBC_TARGET_OS_IS_LINUX)
+if(TARGET libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime)  
   add_object_library(
     clock_settime
     ALIAS

>From 366ad9ac759cb84764595f790c5f83f8323c6343 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Fri, 3 Oct 2025 09:28:17 -0700
Subject: [PATCH 4/6] - Removed redundant 'struct' keyword

---
 libc/src/time/linux/clock.cpp         | 2 +-
 libc/src/time/linux/clock_gettime.cpp | 2 +-
 libc/src/time/linux/clock_settime.cpp | 2 +-
 libc/src/time/linux/nanosleep.cpp     | 2 +-
 libc/src/time/linux/timespec_get.cpp  | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libc/src/time/linux/clock.cpp b/libc/src/time/linux/clock.cpp
index c38697cd0668e..c560bd10be83c 100644
--- a/libc/src/time/linux/clock.cpp
+++ b/libc/src/time/linux/clock.cpp
@@ -19,7 +19,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(clock_t, clock, ()) {
   using namespace time_units;
-  struct timespec ts;
+  timespec ts;
   auto result = internal::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
   if (!result.has_value()) {
     libc_errno = result.error();
diff --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp
index b3fcd2b22f9da..a77d92e05474c 100644
--- a/libc/src/time/linux/clock_gettime.cpp
+++ b/libc/src/time/linux/clock_gettime.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 // TODO(michaelrj): Move this into time/linux with the other syscalls.
 LLVM_LIBC_FUNCTION(int, clock_gettime,
-                   (clockid_t clockid, struct timespec *ts)) {
+                   (clockid_t clockid, timespec *ts)) {
   auto result = internal::clock_gettime(clockid, ts);
 
   // A negative return value indicates an error with the magnitude of the
diff --git a/libc/src/time/linux/clock_settime.cpp b/libc/src/time/linux/clock_settime.cpp
index 1f39ca6efa02d..3c582cf0b4646 100644
--- a/libc/src/time/linux/clock_settime.cpp
+++ b/libc/src/time/linux/clock_settime.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, clock_settime,
-                   (clockid_t clockid, const struct timespec *ts)) {
+                   (clockid_t clockid, const timespec *ts)) {
   auto result = internal::clock_settime(clockid, ts);
 
   // A negative return value indicates an error with the magnitude of the
diff --git a/libc/src/time/linux/nanosleep.cpp b/libc/src/time/linux/nanosleep.cpp
index e5df1585df988..7b0a4a3efd719 100644
--- a/libc/src/time/linux/nanosleep.cpp
+++ b/libc/src/time/linux/nanosleep.cpp
@@ -19,7 +19,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, nanosleep,
-                   (const struct timespec *req, struct timespec *rem)) {
+                   (const timespec *req, timespec *rem)) {
 #if SYS_nanosleep
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_nanosleep, req, rem);
 #elif defined(SYS_clock_nanosleep_time64)
diff --git a/libc/src/time/linux/timespec_get.cpp b/libc/src/time/linux/timespec_get.cpp
index a4d4372332732..e90f492b65e8f 100644
--- a/libc/src/time/linux/timespec_get.cpp
+++ b/libc/src/time/linux/timespec_get.cpp
@@ -15,7 +15,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) {
+LLVM_LIBC_FUNCTION(int, timespec_get, (timespec *ts, int base)) {
   clockid_t clockid;
   switch (base) {
   case TIME_UTC:

>From bd265d2e7eece441530867b6e3a07066e96af7a4 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Fri, 3 Oct 2025 09:35:07 -0700
Subject: [PATCH 5/6] clang-format

---
 libc/src/time/linux/clock_gettime.cpp | 3 +--
 libc/src/time/linux/nanosleep.cpp     | 3 +--
 libc/src/time/linux/timespec_get.cpp  | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp
index a77d92e05474c..52ace2a743dd4 100644
--- a/libc/src/time/linux/clock_gettime.cpp
+++ b/libc/src/time/linux/clock_gettime.cpp
@@ -15,8 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 // TODO(michaelrj): Move this into time/linux with the other syscalls.
-LLVM_LIBC_FUNCTION(int, clock_gettime,
-                   (clockid_t clockid, timespec *ts)) {
+LLVM_LIBC_FUNCTION(int, clock_gettime, (clockid_t clockid, timespec *ts)) {
   auto result = internal::clock_gettime(clockid, ts);
 
   // A negative return value indicates an error with the magnitude of the
diff --git a/libc/src/time/linux/nanosleep.cpp b/libc/src/time/linux/nanosleep.cpp
index 7b0a4a3efd719..a30b97de40492 100644
--- a/libc/src/time/linux/nanosleep.cpp
+++ b/libc/src/time/linux/nanosleep.cpp
@@ -18,8 +18,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, nanosleep,
-                   (const timespec *req, timespec *rem)) {
+LLVM_LIBC_FUNCTION(int, nanosleep, (const timespec *req, timespec *rem)) {
 #if SYS_nanosleep
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_nanosleep, req, rem);
 #elif defined(SYS_clock_nanosleep_time64)
diff --git a/libc/src/time/linux/timespec_get.cpp b/libc/src/time/linux/timespec_get.cpp
index e90f492b65e8f..031cb9f83b1c3 100644
--- a/libc/src/time/linux/timespec_get.cpp
+++ b/libc/src/time/linux/timespec_get.cpp
@@ -15,7 +15,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, timespec_get, (timespec *ts, int base)) {
+LLVM_LIBC_FUNCTION(int, timespec_get, (timespec * ts, int base)) {
   clockid_t clockid;
   switch (base) {
   case TIME_UTC:

>From 36a3f80c0d3484ef17d1f59480e73b9d17360531 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Mon, 27 Oct 2025 22:39:33 -0700
Subject: [PATCH 6/6] - Added positive path for clock_settime test - Fixed
 error in clock_settime struct setup - Upd the time.rst doc with up to date
 info

---
 libc/docs/headers/time.rst                    |  2 +-
 .../__support/time/linux/clock_settime.cpp    |  8 +++----
 libc/test/src/time/clock_settime_test.cpp     | 23 +++++++++++++++++++
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/libc/docs/headers/time.rst b/libc/docs/headers/time.rst
index 00b0dd472de5c..f07e0d93a4ce6 100644
--- a/libc/docs/headers/time.rst
+++ b/libc/docs/headers/time.rst
@@ -67,7 +67,7 @@ Implementation Status
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | clock_getres        |         |         |         |                 |         |         |         |         |         |         |         |         |         |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| clock_gettime       | |check| | |check| |         |     |check|     |         |         |         |         |         |         |         |         |         |
+| clock_gettime       | |check| | |check| |         |     |check|     |         |         |         |         |         |         |         | |check| | |check| |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | clock_nanosleep     |         |         |         |                 |         |         |         |         |         |         |         |         |         |
 +---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
diff --git a/libc/src/__support/time/linux/clock_settime.cpp b/libc/src/__support/time/linux/clock_settime.cpp
index d81889ebc469d..dd42610adb031 100644
--- a/libc/src/__support/time/linux/clock_settime.cpp
+++ b/libc/src/__support/time/linux/clock_settime.cpp
@@ -34,13 +34,13 @@ ErrorOr<int> clock_settime(clockid_t clockid, const timespec *ts) {
 
   __kernel_timespec ts64{};
 
+  // Populate the 64-bit kernel structure from the user-provided timespec
+  ts64.tv_sec = static_cast<decltype(ts64.tv_sec)>(ts->tv_sec);
+  ts64.tv_nsec = static_cast<decltype(ts64.tv_nsec)>(ts->tv_nsec);
+
   ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_settime64,
                                           static_cast<long>(clockid),
                                           reinterpret_cast<long>(&ts64));
-  if (ret == 0) {
-    ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
-    ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
-  }
 #else
 #error "SYS_clock_settime and SYS_clock_settime64 syscalls not available."
 #endif
diff --git a/libc/test/src/time/clock_settime_test.cpp b/libc/test/src/time/clock_settime_test.cpp
index 881db1f75120d..ccbad9ed2e847 100644
--- a/libc/test/src/time/clock_settime_test.cpp
+++ b/libc/test/src/time/clock_settime_test.cpp
@@ -29,3 +29,26 @@ TEST_F(LlvmLibcClockSetTime, InvalidClockId) {
   ASSERT_EQ(result, -1);
   ASSERT_ERRNO_EQ(EINVAL);
 }
+
+TEST_F(LlvmLibcClockSetTime, InvalidTimespecNsec) {
+  timespec ts = {0, 1000000000L};
+  int result = LIBC_NAMESPACE::clock_settime(CLOCK_REALTIME, &ts);
+  ASSERT_EQ(result, -1);
+  ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST_F(LlvmLibcClockSetTime, NullPointerIsEFAULT) {
+  int result = LIBC_NAMESPACE::clock_settime(CLOCK_REALTIME, nullptr);
+  ASSERT_EQ(result, -1);
+  ASSERT_ERRNO_EQ(EFAULT);
+}
+
+TEST_F(LlvmLibcClockSetTime, ClockIsSet) {
+  timespec ts = {0, 0};
+  int result = LIBC_NAMESPACE::clock_settime(CLOCK_REALTIME, &ts);
+  if (result == 0) {
+    ASSERT_ERRNO_SUCCESS();
+  } else {
+    ASSERT_ERRNO_EQ(EPERM);
+  }
+}



More information about the libc-commits mailing list