time-util: continue sleeping when clock_nanosleep() fail with EINTR

The function clock_nanosleep() provides remaining time when failed with
EINTR. Let's continue sleeping in that case.
This commit is contained in:
Yu Watanabe
2025-12-15 17:50:19 +09:00
parent 2960889a2c
commit b8241d3ca5
2 changed files with 31 additions and 13 deletions
+30
View File
@@ -1792,6 +1792,36 @@ bool in_utc_timezone(void) {
return timezone == 0 && daylight == 0;
}
int usleep_safe(usec_t usec) {
int r;
/* usleep() takes useconds_t that is (typically?) uint32_t. Also, usleep() may only support the
* range [0, 1000000]. See usleep(3). Let's override usleep() with clock_nanosleep().
*
* ⚠️ Note we are not using plain nanosleep() here, since that operates on CLOCK_REALTIME, not
* CLOCK_MONOTONIC! */
if (usec == 0)
return 0;
struct timespec t;
timespec_store(&t, usec);
for (;;) {
struct timespec remaining;
/* `clock_nanosleep()` does not use `errno`, but returns positive error codes. */
r = -clock_nanosleep(CLOCK_MONOTONIC, /* flags= */ 0, &t, &remaining);
if (r == -EINTR) {
/* Interrupted. Continue sleeping for the remaining time. */
t = remaining;
continue;
}
return r;
}
}
int time_change_fd(void) {
/* We only care for the cancellation event, hence we set the timeout to the latest possible value. */