[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