Also add some tests.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- tools/include/nolibc/time.h | 34 ++++++++++++++++++++++++++++ tools/testing/selftests/nolibc/nolibc-test.c | 1 + 2 files changed, 35 insertions(+)
diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h index fc387940d51f389d4233bd5712588dced31ae6e5..d02bc44d2643a5e39afa808841f7175bfab5ff7e 100644 --- a/tools/include/nolibc/time.h +++ b/tools/include/nolibc/time.h @@ -36,6 +36,8 @@ void __nolibc_timespec_kernel_to_user(const struct __kernel_timespec *kts, struc * int clock_getres(clockid_t clockid, struct timespec *res); * int clock_gettime(clockid_t clockid, struct timespec *tp); * int clock_settime(clockid_t clockid, const struct timespec *tp); + * int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, + * struct timespec *rmtp) */
static __attribute__((unused)) @@ -107,6 +109,32 @@ int clock_settime(clockid_t clockid, struct timespec *tp) return __sysret(sys_clock_settime(clockid, tp)); }
+static __attribute__((unused)) +int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, + struct timespec *rmtp) +{ +#if defined(__NR_clock_nanosleep) + return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp); +#elif defined(__NR_clock_nanosleep_time64) + struct __kernel_timespec krqtp, krmtp; + int ret; + + __nolibc_timespec_user_to_kernel(rqtp, &krqtp); + ret = my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, &krqtp, &krmtp); + if (rmtp) + __nolibc_timespec_kernel_to_user(&krmtp, rmtp); + return ret; +#else + return __nolibc_enosys(__func__, clockid, flags, rqtp, rmtp); +#endif +} + +static __attribute__((unused)) +int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, + struct timespec *rmtp) +{ + return __sysret(sys_clock_nanosleep(clockid, flags, rqtp, rmtp)); +}
static __inline__ double difftime(time_t time1, time_t time2) @@ -114,6 +142,12 @@ double difftime(time_t time1, time_t time2) return time1 - time2; }
+static __inline__ +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + return clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rmtp); +} +
static __attribute__((unused)) time_t time(time_t *tptr) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index b5bca1dcf36e95a576ca9ffba4f7c213978a3f35..315229233930265501296dfeb9bc2838bb6fef84 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1363,6 +1363,7 @@ int run_syscall(int min, int max) CASE_TEST(mmap_bad); EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break; CASE_TEST(munmap_bad); EXPECT_SYSER(1, munmap(NULL, 0), -1, EINVAL); break; CASE_TEST(mmap_munmap_good); EXPECT_SYSZR(1, test_mmap_munmap()); break; + CASE_TEST(nanosleep); ts.tv_nsec = -1; EXPECT_SYSER(1, nanosleep(&ts, NULL), -1, EINVAL); break; CASE_TEST(open_tty); EXPECT_SYSNE(1, tmp = open("/dev/null", O_RDONLY), -1); if (tmp != -1) close(tmp); break; CASE_TEST(open_blah); EXPECT_SYSER(1, tmp = open("/proc/self/blah", O_RDONLY), -1, ENOENT); if (tmp != -1) close(tmp); break; CASE_TEST(openat_dir); EXPECT_SYSZR(1, test_openat()); break;
--- base-commit: 1536aa0fb1e09cb50f401ec4852c60f38173d751 change-id: 20250704-nolibc-nanosleep-2476b806b0d5
Best regards,
Hi Thomas,
On Fri, Jul 04, 2025 at 04:19:48PM +0200, Thomas Weißschuh wrote:
+static __attribute__((unused)) +int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
struct timespec *rmtp)
+{ +#if defined(__NR_clock_nanosleep)
- return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
+#elif defined(__NR_clock_nanosleep_time64)
- struct __kernel_timespec krqtp, krmtp;
- int ret;
- __nolibc_timespec_user_to_kernel(rqtp, &krqtp);
- ret = my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, &krqtp, &krmtp);
- if (rmtp)
__nolibc_timespec_kernel_to_user(&krmtp, rmtp);
- return ret;
+#else
- return __nolibc_enosys(__func__, clockid, flags, rqtp, rmtp);
+#endif
I don't know which archs do not have clock_nanosleep, but if it becomes needed on some of them, we could probably fall back to pslelect() if available, of course, and ignore the clockid.
Acked-by: Willy Tarreau w@1wt.eu
Cheers, Willy
On 2025-07-06 08:26:33+0200, Willy Tarreau wrote:
On Fri, Jul 04, 2025 at 04:19:48PM +0200, Thomas Weißschuh wrote:
+static __attribute__((unused)) +int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
struct timespec *rmtp)
+{ +#if defined(__NR_clock_nanosleep)
- return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
+#elif defined(__NR_clock_nanosleep_time64)
- struct __kernel_timespec krqtp, krmtp;
- int ret;
- __nolibc_timespec_user_to_kernel(rqtp, &krqtp);
- ret = my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, &krqtp, &krmtp);
- if (rmtp)
__nolibc_timespec_kernel_to_user(&krmtp, rmtp);
- return ret;
+#else
- return __nolibc_enosys(__func__, clockid, flags, rqtp, rmtp);
+#endif
I don't know which archs do not have clock_nanosleep, but if it becomes needed on some of them, we could probably fall back to pslelect() if available, of course, and ignore the clockid.
No architecture should ever run into the #else. It is mostly for completeness and consistency with other architectures. As for falling back to pselect(), the clockid is indeed important :-)
Acked-by: Willy Tarreau w@1wt.eu
Thanks!
linux-kselftest-mirror@lists.linaro.org