@@ -4485,6 +4485,8 @@ long syscall(long number, ...) {
44854485 }
44864486#endif
44874487// static int (*real_clock_gettime) (clockid_t clk_id, struct timespec *tp);
4488+ /* Intercept clock_gettime syscall if available */
4489+ #ifdef __NR_clock_gettime
44884490 if (number == __NR_clock_gettime && (getenv ("FAKETIME" ) || getenv ("FAKETIME_TIMESTAMP_FILE" ))) {
44894491 clockid_t clk_id ;
44904492 struct timespec * tp ;
@@ -4493,6 +4495,87 @@ long syscall(long number, ...) {
44934495 va_end (ap );
44944496 return clock_gettime (clk_id , tp );
44954497 }
4498+ #endif
4499+
4500+ #ifdef FAKE_SLEEP
4501+ #ifdef __NR_clock_nanosleep
4502+ /* Intercept raw clock_nanosleep syscall */
4503+ if (number == __NR_clock_nanosleep && (getenv ("FAKETIME" ) || getenv ("FAKETIME_TIMESTAMP_FILE" )))
4504+ {
4505+ clockid_t clk_id ;
4506+ int flags ;
4507+ const struct timespec * req ;
4508+ struct timespec * rem ;
4509+
4510+ clk_id = va_arg (ap , clockid_t );
4511+ flags = va_arg (ap , int );
4512+ req = va_arg (ap , const struct timespec * );
4513+ rem = va_arg (ap , struct timespec * );
4514+ va_end (ap );
4515+
4516+ if (req == NULL )
4517+ {
4518+ /* Pass through invalid input to maintain behavior */
4519+ return real_syscall (number , clk_id , flags , req , rem );
4520+ }
4521+
4522+ struct timespec real_req ;
4523+
4524+ if (flags & TIMER_ABSTIME )
4525+ {
4526+ /* Sleep until absolute fake time 'req': convert to corresponding real abstime */
4527+ struct timespec tdiff , timeadj ;
4528+ /* time difference between target fake abstime and fake base */
4529+ timespecsub (req , & user_faked_time_timespec , & timeadj );
4530+ if (user_rate_set ) {
4531+ timespecmul (& timeadj , 1.0 / user_rate , & tdiff );
4532+ } else {
4533+ tdiff = timeadj ;
4534+ }
4535+
4536+ if (clk_id == CLOCK_REALTIME )
4537+ {
4538+ timespecadd (& ftpl_starttime .real , & tdiff , & real_req );
4539+ } else if (clk_id == CLOCK_MONOTONIC )
4540+ {
4541+ get_fake_monotonic_setting (& fake_monotonic_clock );
4542+ if (fake_monotonic_clock ) {
4543+ timespecadd (& ftpl_starttime .mon , & tdiff , & real_req );
4544+ } else {
4545+ /* leave untouched if monotonic faking disabled */
4546+ real_req = * req ;
4547+ }
4548+ } else {
4549+ /* other clocks: leave untouched */
4550+ real_req = * req ;
4551+ }
4552+ } else
4553+ {
4554+ /* Relative sleep: scale by 1/rate for realtime/monotonic when faking */
4555+ if (user_rate_set && !dont_fake && ((clk_id == CLOCK_REALTIME ) || (clk_id == CLOCK_MONOTONIC )))
4556+ {
4557+ timespecmul (req , 1.0 / user_rate , & real_req );
4558+ } else {
4559+ real_req = * req ;
4560+ }
4561+ }
4562+
4563+ long rc = real_syscall (number , clk_id , flags , & real_req , rem );
4564+ if (rc != 0 )
4565+ {
4566+ return rc ;
4567+ }
4568+ if (rem != NULL && (rem -> tv_sec != 0 || rem -> tv_nsec != 0 ))
4569+ {
4570+ if (user_rate_set && !dont_fake )
4571+ {
4572+ timespecmul (rem , user_rate , rem );
4573+ }
4574+ }
4575+ return rc ;
4576+ }
4577+ #endif /* __NR_clock_nanosleep */
4578+ #endif /* FAKE_SLEEP */
44964579
44974580#ifdef INTERCEPT_FUTEX
44984581 if (number == __NR_futex ) {
0 commit comments