[LTP] [PATCH v3] clock_settime: Detect external clock adjustments via CLOCK_MONOTONIC
Andrea Cervesato
andrea.cervesato@suse.de
Wed Apr 1 09:21:19 CEST 2026
From: Andrea Cervesato <andrea.cervesato@suse.com>
These tests manipulate CLOCK_REALTIME to verify timer and
clock_nanosleep behavior, but NTP or VM time sync can also adjust
CLOCK_REALTIME during the test, causing timers to fire at wrong times
and producing sporadic failures.
Add pts_mono_time_start()/pts_mono_time_check() helpers to detect
external clock interference using CLOCK_MONOTONIC. When interference
is detected, the test retries up to PTS_MONO_MAX_RETRIES times before
reporting UNTESTED. Guard with _POSIX_MONOTONIC_CLOCK since
CLOCK_MONOTONIC is optional in POSIX.1-2001.
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
I used Claude to generate the right patches to fix sporadic issues in the
clock_settime testing suite. We tried many attempt for fixing it, but the
CLOCK_REALTIME usage seems to be the real issue in here. The idea is that
we use internal Openposix mechanisms to skip tests if CLOCK_MONOTONIC
usage spots a possible interference from external tools.
---
Changes in v3:
- cycle multiple times before failing the tests
- add helpers functions for CLOCK_MONOTONIC checks
- Link to v2: https://lore.kernel.org/r/20260331-clock_settime_fix-v2-1-e222fe379b16@suse.com
Changes in v2:
- print a message if CLOCK_MONOTONIC is not available
- always verify that CLOCK_MONOTONIC is available
- Link to v1: https://lore.kernel.org/r/20260331-clock_settime_fix-v1-1-dfae06df2436@suse.com
---
.../conformance/interfaces/clock_settime/4-1.c | 82 +++++++++-------
.../conformance/interfaces/clock_settime/5-1.c | 67 ++++++++-----
.../conformance/interfaces/clock_settime/5-2.c | 57 +++++++----
.../conformance/interfaces/clock_settime/7-1.c | 90 ++++++++++--------
.../conformance/interfaces/clock_settime/7-2.c | 105 ++++++++++++---------
.../conformance/interfaces/clock_settime/helpers.h | 47 +++++++++
.../conformance/interfaces/nanosleep/7-1.c | 50 +++++-----
7 files changed, 308 insertions(+), 190 deletions(-)
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/4-1.c b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/4-1.c
index f8a3e9c542ca8c9767cdd0057005e519f58b2b55..fd846f6bc9ae9a3fc4f1c51a141ec216b17b5292 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/4-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/4-1.c
@@ -47,7 +47,7 @@ int main(void)
int delta;
int sig;
sigset_t set;
- int flags = 0;
+ int attempt;
/* Check that we're root...can't call clock_settime with CLOCK_REALTIME otherwise */
if (geteuid() != 0) {
@@ -77,49 +77,61 @@ int main(void)
return PTS_UNRESOLVED;
}
- if (clock_gettime(CLOCK_REALTIME, &tpT0) != 0) {
- perror("clock_gettime() was not successful\n");
- return PTS_UNRESOLVED;
- }
-
if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
perror("timer_create() did not return success\n");
return PTS_UNRESOLVED;
}
- flags |= TIMER_ABSTIME;
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 0;
- its.it_value.tv_sec = tpT0.tv_sec + TIMEROFFSET;
- its.it_value.tv_nsec = tpT0.tv_nsec;
- if (timer_settime(tid, flags, &its, NULL) != 0) {
- perror("timer_settime() did not return success\n");
- return PTS_UNRESOLVED;
- }
-
- sleep(SLEEPTIME);
- getBeforeTime(&tpreset);
- if (clock_settime(CLOCK_REALTIME, &tpT0) != 0) {
- perror("clock_settime() was not successful");
- return PTS_UNRESOLVED;
- }
-
- if (sigwait(&set, &sig) == -1) {
- perror("sigwait() was not successful\n");
- return PTS_UNRESOLVED;
+ for (attempt = 0; attempt < PTS_MONO_MAX_RETRIES; attempt++) {
+ if (clock_gettime(CLOCK_REALTIME, &tpT0) != 0) {
+ perror("clock_gettime() was not successful\n");
+ return PTS_UNRESOLVED;
+ }
+
+ pts_mono_time_start();
+
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = tpT0.tv_sec + TIMEROFFSET;
+ its.it_value.tv_nsec = tpT0.tv_nsec;
+ if (timer_settime(tid, TIMER_ABSTIME, &its, NULL) != 0) {
+ perror("timer_settime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
+
+ sleep(SLEEPTIME);
+ getBeforeTime(&tpreset);
+ if (clock_settime(CLOCK_REALTIME, &tpT0) != 0) {
+ perror("clock_settime() was not successful");
+ return PTS_UNRESOLVED;
+ }
+
+ if (sigwait(&set, &sig) == -1) {
+ perror("sigwait() was not successful\n");
+ return PTS_UNRESOLVED;
+ }
+
+ if (clock_gettime(CLOCK_REALTIME, &tpT2) != 0) {
+ printf("clock_gettime() was not successful\n");
+ return PTS_UNRESOLVED;
+ }
+
+ delta = tpT2.tv_sec - its.it_value.tv_sec;
+
+ // add back time waited to reset value and reset time
+ tpreset.tv_sec += tpT2.tv_sec - tpT0.tv_sec;
+ setBackTime(tpreset);
+
+ if (pts_mono_time_check(SLEEPTIME + TIMEROFFSET))
+ break;
}
- if (clock_gettime(CLOCK_REALTIME, &tpT2) != 0) {
- printf("clock_gettime() was not successful\n");
- return PTS_UNRESOLVED;
+ if (attempt == PTS_MONO_MAX_RETRIES) {
+ printf("UNTESTED: persistent clock interference after %d attempts\n",
+ PTS_MONO_MAX_RETRIES);
+ return PTS_UNTESTED;
}
- delta = tpT2.tv_sec - its.it_value.tv_sec;
-
- // add back time waited to reset value and reset time
- tpreset.tv_sec += tpT2.tv_sec - tpT0.tv_sec;
- setBackTime(tpreset);
-
printf("delta: %d\n", delta);
if ((delta <= ACCEPTABLEDELTA) && (delta >= 0)) {
printf("Test PASSED\n");
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-1.c b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-1.c
index 75fa591e014601b2ef9308a118992a704365392b..76aedcf64c1482f030d74f3e3e7baccb3416701f 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-1.c
@@ -49,6 +49,8 @@ int main(void)
struct itimerspec its;
timer_t tid;
sigset_t set;
+ int ns_ret;
+ int attempt;
/* Check that we're root...can't call clock_settime with CLOCK_REALTIME otherwise */
if (getuid() != 0) {
@@ -92,42 +94,59 @@ int main(void)
its.it_value.tv_sec = TIMERSEC;
its.it_value.tv_nsec = 0;
- if (timer_settime(tid, 0, &its, NULL) != 0) {
- perror("timer_settime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ for (attempt = 0; attempt < PTS_MONO_MAX_RETRIES; attempt++) {
+ if (timer_settime(tid, 0, &its, NULL) != 0) {
+ perror("timer_settime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
- if (clock_gettime(CLOCK_REALTIME, &tsclock) != 0) {
- printf("clock_gettime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ pts_mono_time_start();
- tsclock.tv_sec -= CLOCKOFFSET;
- getBeforeTime(&tsreset);
- if (clock_settime(CLOCK_REALTIME, &tsclock) != 0) {
- printf("clock_settime() was not successful\n");
- return PTS_UNRESOLVED;
+ if (clock_gettime(CLOCK_REALTIME, &tsclock) != 0) {
+ printf("clock_gettime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
+
+ tsclock.tv_sec -= CLOCKOFFSET;
+ getBeforeTime(&tsreset);
+ if (clock_settime(CLOCK_REALTIME, &tsclock) != 0) {
+ printf("clock_settime() was not successful\n");
+ return PTS_UNRESOLVED;
+ }
+
+ ts.tv_sec = TIMERSEC + SLEEPDELTA;
+ ts.tv_nsec = 0;
+
+ ns_ret = nanosleep(&ts, &tsleft);
+
+ if (pts_mono_time_check(TIMERSEC)) {
+ tsreset.tv_sec += TIMERSEC;
+ setBackTime(tsreset);
+ break;
+ }
+
+ tsreset.tv_sec += TIMERSEC;
+ setBackTime(tsreset);
}
- ts.tv_sec = TIMERSEC + SLEEPDELTA;
- ts.tv_nsec = 0;
+ if (attempt == PTS_MONO_MAX_RETRIES) {
+ printf("UNTESTED: persistent clock interference after %d attempts\n",
+ PTS_MONO_MAX_RETRIES);
+ return PTS_UNTESTED;
+ }
- if (nanosleep(&ts, &tsleft) != -1) {
+ if (ns_ret != -1) {
printf("nanosleep() not interrupted\n");
return PTS_FAIL;
}
if (labs(tsleft.tv_sec - SLEEPDELTA) <= ACCEPTABLEDELTA) {
printf("Test PASSED\n");
- tsreset.tv_sec += TIMERSEC;
- setBackTime(tsreset);
return PTS_PASS;
- } else {
- printf("Timer did not last for correct amount of time\n");
- printf("timer: %d != correct %d\n",
- (int)ts.tv_sec - (int)tsleft.tv_sec, TIMERSEC);
- return PTS_FAIL;
}
- return PTS_UNRESOLVED;
+ printf("Timer did not last for correct amount of time\n");
+ printf("timer: %d != correct %d\n",
+ (int)ts.tv_sec - (int)tsleft.tv_sec, TIMERSEC);
+ return PTS_FAIL;
}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-2.c b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-2.c
index b8a60028c6d3d1a3c0d75922f39697b57329c440..d1fe7b6e330827474adc398c923b4e7dffb0a3b8 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/5-2.c
@@ -49,6 +49,8 @@ int main(void)
struct itimerspec its;
timer_t tid;
sigset_t set;
+ int ns_ret;
+ int attempt;
/* Check that we're root...can't call clock_settime with CLOCK_REALTIME otherwise */
if (getuid() != 0) {
@@ -92,35 +94,54 @@ int main(void)
its.it_value.tv_sec = TIMERSEC;
its.it_value.tv_nsec = 0;
- if (timer_settime(tid, 0, &its, NULL) != 0) {
- perror("timer_settime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ for (attempt = 0; attempt < PTS_MONO_MAX_RETRIES; attempt++) {
+ if (timer_settime(tid, 0, &its, NULL) != 0) {
+ perror("timer_settime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
- if (clock_gettime(CLOCK_REALTIME, &tsclock) != 0) {
- printf("clock_gettime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ pts_mono_time_start();
- tsclock.tv_sec += CLOCKOFFSET;
- getBeforeTime(&tsreset);
- if (clock_settime(CLOCK_REALTIME, &tsclock) != 0) {
- printf("clock_settime() was not successful\n");
- return PTS_UNRESOLVED;
+ if (clock_gettime(CLOCK_REALTIME, &tsclock) != 0) {
+ printf("clock_gettime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
+
+ tsclock.tv_sec += CLOCKOFFSET;
+ getBeforeTime(&tsreset);
+ if (clock_settime(CLOCK_REALTIME, &tsclock) != 0) {
+ printf("clock_settime() was not successful\n");
+ return PTS_UNRESOLVED;
+ }
+
+ ts.tv_sec = TIMERSEC + SLEEPDELTA;
+ ts.tv_nsec = 0;
+
+ ns_ret = nanosleep(&ts, &tsleft);
+
+ if (pts_mono_time_check(TIMERSEC)) {
+ tsreset.tv_sec += TIMERSEC;
+ setBackTime(tsreset);
+ break;
+ }
+
+ tsreset.tv_sec += TIMERSEC;
+ setBackTime(tsreset);
}
- ts.tv_sec = TIMERSEC + SLEEPDELTA;
- ts.tv_nsec = 0;
+ if (attempt == PTS_MONO_MAX_RETRIES) {
+ printf("UNTESTED: persistent clock interference after %d attempts\n",
+ PTS_MONO_MAX_RETRIES);
+ return PTS_UNTESTED;
+ }
- if (nanosleep(&ts, &tsleft) != -1) {
+ if (ns_ret != -1) {
printf("nanosleep() not interrupted\n");
return PTS_FAIL;
}
if (labs(tsleft.tv_sec - SLEEPDELTA) <= ACCEPTABLEDELTA) {
printf("Test PASSED\n");
- tsreset.tv_sec += TIMERSEC;
- setBackTime(tsreset);
return PTS_PASS;
}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-1.c b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-1.c
index 569eae904ef2eff41441029d3427313107febe53..d05a1ac83debf09d37e7b058699c734e2227c7d9 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-1.c
@@ -35,8 +35,9 @@
int main(void)
{
- struct timespec tsT0, tsT1;
- int pid;
+ struct timespec tsT0, tsT1, tsreset;
+ int pid, child_status;
+ int attempt;
/* Check that we're root...can't call clock_settime with CLOCK_REALTIME otherwise */
if (getuid() != 0) {
@@ -44,50 +45,49 @@ int main(void)
return PTS_UNTESTED;
}
- if (clock_gettime(CLOCK_REALTIME, &tsT0) != 0) {
- perror("clock_gettime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ for (attempt = 0; attempt < PTS_MONO_MAX_RETRIES; attempt++) {
+ if (clock_gettime(CLOCK_REALTIME, &tsT0) != 0) {
+ perror("clock_gettime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
- if ((pid = fork()) == 0) {
- /* child here */
- int flags = 0;
- struct timespec tsT2;
+ pts_mono_time_start();
- tsT1.tv_sec = tsT0.tv_sec + SLEEPOFFSET;
- tsT1.tv_nsec = tsT0.tv_nsec;
+ pid = fork();
+ if (pid == 0) {
+ /* child here */
+ int flags = 0;
+ struct timespec tsT2;
- flags |= TIMER_ABSTIME;
- if (clock_nanosleep(CLOCK_REALTIME, flags, &tsT1, NULL) != 0) {
- printf("clock_nanosleep() did not return success\n");
- return CHILDFAIL;
- }
+ tsT1.tv_sec = tsT0.tv_sec + SLEEPOFFSET;
+ tsT1.tv_nsec = tsT0.tv_nsec;
- if (clock_gettime(CLOCK_REALTIME, &tsT2) != 0) {
- perror("clock_gettime() did not return success\n");
- return CHILDFAIL;
- }
+ flags |= TIMER_ABSTIME;
+ if (clock_nanosleep(CLOCK_REALTIME, flags, &tsT1, NULL) != 0) {
+ printf("clock_nanosleep() did not return success\n");
+ return CHILDFAIL;
+ }
+
+ if (clock_gettime(CLOCK_REALTIME, &tsT2) != 0) {
+ perror("clock_gettime() did not return success\n");
+ return CHILDFAIL;
+ }
+
+ if (tsT2.tv_sec >= tsT1.tv_sec) {
+ if ((tsT2.tv_sec - tsT1.tv_sec) <= ACCEPTABLEDELTA)
+ return CHILDPASS;
- if (tsT2.tv_sec >= tsT1.tv_sec) {
- if ((tsT2.tv_sec - tsT1.tv_sec) <= ACCEPTABLEDELTA) {
- return CHILDPASS;
- } else {
printf("Ended too late. %d >> %d\n",
(int)tsT2.tv_sec, (int)tsT1.tv_sec);
return CHILDFAIL;
}
- } else {
+
printf("Did not sleep for long enough %d < %d\n",
(int)tsT2.tv_sec, (int)tsT1.tv_sec);
return CHILDFAIL;
}
- return CHILDFAIL;
- } else {
/* parent here */
- int i;
- struct timespec tsreset;
-
sleep(SMALLTIME);
if (clock_settime(CLOCK_REALTIME, &tsT0) != 0) {
@@ -95,22 +95,30 @@ int main(void)
return PTS_UNRESOLVED;
}
- if (wait(&i) == -1) {
+ if (wait(&child_status) == -1) {
perror("Error waiting for child to exit\n");
return PTS_UNRESOLVED;
}
- getBeforeTime(&tsreset); // get current time
+ getBeforeTime(&tsreset);
tsreset.tv_sec += SMALLTIME;
setBackTime(tsreset);
- if (WIFEXITED(i) && WEXITSTATUS(i)) {
- printf("Test PASSED\n");
- return PTS_PASS;
- } else {
- printf("Test FAILED\n");
- return PTS_FAIL;
- }
+
+ if (pts_mono_time_check(SMALLTIME + SLEEPOFFSET))
+ break;
+ }
+
+ if (attempt == PTS_MONO_MAX_RETRIES) {
+ printf("UNTESTED: persistent clock interference after %d attempts\n",
+ PTS_MONO_MAX_RETRIES);
+ return PTS_UNTESTED;
+ }
+
+ if (WIFEXITED(child_status) && WEXITSTATUS(child_status)) {
+ printf("Test PASSED\n");
+ return PTS_PASS;
}
- return PTS_UNRESOLVED;
+ printf("Test FAILED\n");
+ return PTS_FAIL;
}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-2.c b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-2.c
index 7c340b6c97ce03a1b04709f06996e5a66e1a653a..18b1f47ba91989570052893e3689f75dbc96a6b2 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/7-2.c
@@ -31,11 +31,13 @@
#define CHILDPASS 1
#define CHILDFAIL 0
+#define CHILDUNTESTED 2
int main(void)
{
- struct timespec tsT0, tsT1, tsT2;
- int pid;
+ struct timespec tsT0, tsT1, tsT2, tsreset;
+ int pid, child_status;
+ int attempt;
/* Check that we're root...can't call clock_settime with CLOCK_REALTIME otherwise */
if (getuid() != 0) {
@@ -43,53 +45,62 @@ int main(void)
return PTS_UNTESTED;
}
- if (clock_gettime(CLOCK_REALTIME, &tsT0) != 0) {
- perror("clock_gettime() did not return success\n");
- return PTS_UNRESOLVED;
- }
+ for (attempt = 0; attempt < PTS_MONO_MAX_RETRIES; attempt++) {
+ if (clock_gettime(CLOCK_REALTIME, &tsT0) != 0) {
+ perror("clock_gettime() did not return success\n");
+ return PTS_UNRESOLVED;
+ }
- tsT1.tv_sec = tsT0.tv_sec + SLEEPOFFSET;
- tsT1.tv_nsec = tsT0.tv_nsec;
+ tsT1.tv_sec = tsT0.tv_sec + SLEEPOFFSET;
+ tsT1.tv_nsec = tsT0.tv_nsec;
- tsT2.tv_sec = tsT1.tv_sec + SMALLTIME;
- tsT2.tv_nsec = tsT1.tv_nsec;
+ tsT2.tv_sec = tsT1.tv_sec + SMALLTIME;
+ tsT2.tv_nsec = tsT1.tv_nsec;
- if ((pid = fork()) == 0) {
- /* child here */
- int flags = 0;
- struct timespec tsT3;
+ pid = fork();
+ if (pid == 0) {
+ /* child here */
+ int flags = 0;
+ struct timespec tsT3;
- flags |= TIMER_ABSTIME;
- if (clock_nanosleep(CLOCK_REALTIME, flags, &tsT1, NULL) != 0) {
- printf("clock_nanosleep() did not return success\n");
- return CHILDFAIL;
- }
+ flags |= TIMER_ABSTIME;
- if (clock_gettime(CLOCK_REALTIME, &tsT3) != 0) {
- perror("clock_gettime() did not return success\n");
- return CHILDFAIL;
- }
+ pts_mono_time_start();
+
+ if (clock_nanosleep(CLOCK_REALTIME, flags, &tsT1, NULL) != 0) {
+ printf("clock_nanosleep() did not return success\n");
+ return CHILDFAIL;
+ }
+
+ /*
+ * The parent sleeps 1s before jumping the clock forward.
+ * If clock_nanosleep returned too quickly, an external
+ * clock adjustment (NTP, VM sync) woke us instead of the
+ * parent's clock_settime.
+ */
+ if (!pts_mono_time_check(1))
+ return CHILDUNTESTED;
+
+ if (clock_gettime(CLOCK_REALTIME, &tsT3) != 0) {
+ perror("clock_gettime() did not return success\n");
+ return CHILDFAIL;
+ }
+
+ if (tsT3.tv_sec >= tsT2.tv_sec) {
+ if ((tsT3.tv_sec - tsT2.tv_sec) <= ACCEPTABLEDELTA)
+ return CHILDPASS;
- if (tsT3.tv_sec >= tsT2.tv_sec) {
- if ((tsT3.tv_sec - tsT2.tv_sec) <= ACCEPTABLEDELTA) {
- return CHILDPASS;
- } else {
printf("Ended too late. %d >> %d\n",
(int)tsT3.tv_sec, (int)tsT2.tv_sec);
return CHILDFAIL;
}
- } else {
+
printf("Did not sleep for long enough %d < %d\n",
(int)tsT3.tv_sec, (int)tsT2.tv_sec);
return CHILDFAIL;
}
- return CHILDFAIL;
- } else {
/* parent here */
- int i;
- struct timespec tsreset;
-
sleep(1);
getBeforeTime(&tsreset);
@@ -98,21 +109,29 @@ int main(void)
return PTS_UNRESOLVED;
}
- if (wait(&i) == -1) {
+ if (wait(&child_status) == -1) {
perror("Error waiting for child to exit\n");
return PTS_UNRESOLVED;
}
- setBackTime(tsreset); //should be ~= before time
+ setBackTime(tsreset);
- if (WIFEXITED(i) && WEXITSTATUS(i)) {
- printf("Test PASSED\n");
- return PTS_PASS;
- } else {
- printf("Test FAILED\n");
- return PTS_FAIL;
- }
+ if (!WIFEXITED(child_status) ||
+ WEXITSTATUS(child_status) != CHILDUNTESTED)
+ break;
+ }
+
+ if (attempt == PTS_MONO_MAX_RETRIES) {
+ printf("UNTESTED: persistent clock interference after %d attempts\n",
+ PTS_MONO_MAX_RETRIES);
+ return PTS_UNTESTED;
+ }
+
+ if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == CHILDPASS) {
+ printf("Test PASSED\n");
+ return PTS_PASS;
}
- return PTS_UNRESOLVED;
+ printf("Test FAILED\n");
+ return PTS_FAIL;
}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/helpers.h b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/helpers.h
index 133a579afa893e90d896d68fc92a93e21ef84efc..66e22d3903a2569ff22cd3e13d3c82e93424cfb9 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/helpers.h
+++ b/testcases/open_posix_testsuite/conformance/interfaces/clock_settime/helpers.h
@@ -12,6 +12,9 @@
* in certain tests, they make use of some libraries already included
* by those tests.
*/
+
+#include <stdlib.h>
+
static int getBeforeTime(struct timespec *tpget)
{
if (clock_gettime(CLOCK_REALTIME, tpget) != 0) {
@@ -32,3 +35,47 @@ static int setBackTime(struct timespec tpset)
return PTS_PASS;
}
+#define PTS_MONO_MAX_RETRIES 3
+
+#ifdef _POSIX_MONOTONIC_CLOCK
+static struct timespec _pts_mono_start;
+
+static inline void pts_mono_time_start(void)
+{
+ clock_gettime(CLOCK_MONOTONIC, &_pts_mono_start);
+}
+
+static inline int pts_mono_time_check(unsigned int expected_secs)
+{
+ struct timespec now;
+ long elapsed;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ elapsed = now.tv_sec - _pts_mono_start.tv_sec;
+
+ if (labs(elapsed - (long)expected_secs) > 1) {
+ printf("Clock adjustment detected (elapsed %lds, expected ~%us)\n",
+ elapsed, expected_secs);
+ return 0;
+ }
+ return 1;
+}
+#else
+static inline void pts_mono_time_start(void)
+{
+ static int warned;
+
+ if (!warned) {
+ printf("CLOCK_MONOTONIC unavailable, "
+ "test may fail due to external clock adjustments\n");
+ warned = 1;
+ }
+}
+
+static inline int pts_mono_time_check(unsigned int expected_secs)
+{
+ (void)expected_secs;
+ return 1;
+}
+#endif
+
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-1.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-1.c
index e9c8ebe51f07b2ac0bd89433b49526d3e08644bb..e67225e841772aec667b33cf1ed07da507be10f5 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-1.c
@@ -29,12 +29,10 @@ int main(void)
{
struct timespec tssleepfor, tsstorage;
int sleepsec = 30;
- int pid;
+ int pid, i;
struct sigaction act;
if ((pid = fork()) == 0) {
- /* child here */
-
act.sa_handler = handler;
act.sa_flags = 0;
if (sigemptyset(&act.sa_mask) == -1) {
@@ -51,40 +49,34 @@ int main(void)
if (EINTR == errno) {
printf("errno == EINTR\n");
return CHILDSUCCESS;
- } else {
- printf("errno != EINTR\n");
- return CHILDFAILURE;
}
- } else {
- printf("nanosleep did not return -1\n");
+
+ printf("errno != EINTR\n");
return CHILDFAILURE;
}
+ printf("nanosleep did not return -1\n");
return CHILDFAILURE;
- } else {
- /* parent here */
- int i;
+ }
- sleep(1);
+ sleep(1);
- if (kill(pid, SIGABRT) != 0) {
- printf("Could not raise signal being tested\n");
- return PTS_UNRESOLVED;
- }
+ if (kill(pid, SIGABRT) != 0) {
+ printf("Could not raise signal being tested\n");
+ return PTS_UNRESOLVED;
+ }
- if (wait(&i) == -1) {
- perror("Error waiting for child to exit\n");
- return PTS_UNRESOLVED;
- }
+ if (wait(&i) == -1) {
+ perror("Error waiting for child to exit\n");
+ return PTS_UNRESOLVED;
+ }
- if (WIFEXITED(i) && WEXITSTATUS(i)) {
- printf("Test PASSED\n");
- return PTS_PASS;
- } else {
- printf("Child did not exit normally.\n");
- printf("Test FAILED\n");
- return PTS_FAIL;
- }
+ if (WIFEXITED(i) && WEXITSTATUS(i)) {
+ printf("Test PASSED\n");
+ return PTS_PASS;
}
- return PTS_UNRESOLVED;
+
+ printf("Child did not exit normally.\n");
+ printf("Test FAILED\n");
+ return PTS_FAIL;
}
---
base-commit: f992f6e25fce22dd37b37ec324aa1b1b26b3204f
change-id: 20260331-clock_settime_fix-8e4117dcb609
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
More information about the ltp
mailing list