Page MenuHomeFreeBSD

D60799.1794346306.diff
No OneTemporary

Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None

D60799.1794346306.diff

diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -483,6 +483,7 @@
posix_spawnattr_getprocdescp_np;
posix_spawnattr_setexecfd_np;
posix_spawnattr_setprocdescp_np;
+ timespec_getres;
uexterr_set;
};
diff --git a/lib/libc/gen/timespec_getres.3 b/lib/libc/gen/timespec_getres.3
--- a/lib/libc/gen/timespec_getres.3
+++ b/lib/libc/gen/timespec_getres.3
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd May 14, 2026
+.Dd October 20, 2026
.Dt TIMESPEC_GETRES 3
.Os
.Sh NAME
@@ -43,7 +43,11 @@
.St -isoC-2023 .
.Sh HISTORY
This interface first appeared in
-.Fx 14 .
+.Fx 14.0 ,
+but it was not exported from the shared C library until
+.Fx 14.6
+and
+.Fx 15.2 .
.Sh AUTHORS
The
.Nm
diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile
--- a/lib/libc/tests/gen/Makefile
+++ b/lib/libc/tests/gen/Makefile
@@ -42,6 +42,7 @@
.endif
ATF_TESTS_C+= sig2str_test
ATF_TESTS_C+= sigsetops_test
+ATF_TESTS_C+= timespec_getres_test
ATF_TESTS_C+= wordexp_test
# TODO: t_closefrom, t_fmtcheck, t_randomid,
diff --git a/lib/libc/tests/gen/timespec_getres_test.c b/lib/libc/tests/gen/timespec_getres_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/gen/timespec_getres_test.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2026 Faraz Vahedi <kfv@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * Tests for timespec_getres() as per ISO/IEC 9899:2024 §7.29.2.7.
+ */
+
+#include <sys/param.h>
+#include <limits.h>
+#include <time.h>
+
+#include <atf-c.h>
+
+static const struct {
+ int base;
+ clockid_t clock;
+} bases[] = {
+ { TIME_UTC, CLOCK_REALTIME },
+ { TIME_MONOTONIC, CLOCK_MONOTONIC },
+};
+
+static const int bad_bases[] = {
+ INT_MIN, -1, 0, INT_MAX,
+};
+
+static void
+check_res(const struct timespec *ts)
+{
+ ATF_CHECK(ts->tv_sec >= 0);
+ ATF_CHECK(ts->tv_nsec >= 0 && ts->tv_nsec < 1000000000);
+ ATF_CHECK(ts->tv_sec != 0 || ts->tv_nsec != 0);
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_supported);
+ATF_TC_BODY(timespec_getres_supported, tc)
+{
+ struct timespec ts;
+
+ for (size_t i = 0; i < nitems(bases); i++) {
+ ATF_CHECK_EQ(timespec_getres(&ts, bases[i].base),
+ bases[i].base);
+ check_res(&ts);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_clock);
+ATF_TC_BODY(timespec_getres_clock, tc)
+{
+ struct timespec ts, cts;
+
+ for (size_t i = 0; i < nitems(bases); i++) {
+ ATF_REQUIRE_EQ(timespec_getres(&ts, bases[i].base),
+ bases[i].base);
+ ATF_REQUIRE_EQ(clock_getres(bases[i].clock, &cts), 0);
+ ATF_CHECK_EQ(ts.tv_sec, cts.tv_sec);
+ ATF_CHECK_EQ(ts.tv_nsec, cts.tv_nsec);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_null);
+ATF_TC_BODY(timespec_getres_null, tc)
+{
+ for (size_t i = 0; i < nitems(bases); i++)
+ ATF_CHECK_EQ(timespec_getres(NULL, bases[i].base),
+ bases[i].base);
+ for (size_t i = 0; i < nitems(bad_bases); i++)
+ ATF_CHECK_EQ(timespec_getres(NULL, bad_bases[i]), 0);
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_unsupported);
+ATF_TC_BODY(timespec_getres_unsupported, tc)
+{
+ struct timespec ts;
+
+ for (size_t i = 0; i < nitems(bad_bases); i++) {
+ ts.tv_sec = -1;
+ ts.tv_nsec = -1;
+ ATF_CHECK_EQ(timespec_getres(&ts, bad_bases[i]), 0);
+ ATF_CHECK_EQ(ts.tv_sec, -1);
+ ATF_CHECK_EQ(ts.tv_nsec, -1);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_timespec_get);
+ATF_TC_BODY(timespec_getres_timespec_get, tc)
+{
+ struct timespec ts;
+
+ for (int base = -1; base <= TIME_MONOTONIC + 8; base++)
+ ATF_CHECK_EQ_MSG(timespec_getres(&ts, base) != 0,
+ timespec_get(&ts, base) != 0, "base %d", base);
+}
+
+ATF_TC_WITHOUT_HEAD(timespec_getres_stable);
+ATF_TC_BODY(timespec_getres_stable, tc)
+{
+ struct timespec first, ts;
+
+ for (size_t i = 0; i < nitems(bases); i++) {
+ ATF_REQUIRE_EQ(timespec_getres(&first, bases[i].base),
+ bases[i].base);
+ for (int n = 0; n < 100; n++) {
+ ATF_REQUIRE_EQ(timespec_getres(&ts, bases[i].base),
+ bases[i].base);
+ ATF_CHECK_EQ(ts.tv_sec, first.tv_sec);
+ ATF_CHECK_EQ(ts.tv_nsec, first.tv_nsec);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, timespec_getres_supported);
+ ATF_TP_ADD_TC(tp, timespec_getres_clock);
+ ATF_TP_ADD_TC(tp, timespec_getres_null);
+ ATF_TP_ADD_TC(tp, timespec_getres_unsupported);
+ ATF_TP_ADD_TC(tp, timespec_getres_timespec_get);
+ ATF_TP_ADD_TC(tp, timespec_getres_stable);
+
+ return (atf_no_error());
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 10, 9:31 PM (14 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41646752
Default Alt Text
D60799.1794346306.diff (4 KB)

Event Timeline