nanosleep: clear remainder on successful completion
Also switch to doing everything in terms of struct timespec except for the actual select(2) call.
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2011, 2013, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
|
* Copyright (c) 2009-2011, 2013, 2017-2018, 2023
|
||||||
|
* Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -37,28 +38,36 @@
|
|||||||
#include "sudo_util.h"
|
#include "sudo_util.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_nanosleep(const struct timespec *ts, struct timespec *rts)
|
sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder)
|
||||||
{
|
{
|
||||||
struct timeval timeout, endtime, now;
|
struct timespec endtime, now;
|
||||||
|
struct timeval tv;
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
if (ts->tv_sec == 0 && ts->tv_nsec < 1000) {
|
if (timeout->tv_sec == 0 && timeout->tv_nsec < 1000) {
|
||||||
timeout.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
timeout.tv_usec = 1;
|
tv.tv_usec = 1;
|
||||||
} else {
|
} else {
|
||||||
TIMESPEC_TO_TIMEVAL(&timeout, ts);
|
TIMESPEC_TO_TIMEVAL(&tv, timeout);
|
||||||
}
|
}
|
||||||
if (rts != NULL) {
|
if (remainder != NULL) {
|
||||||
if (gettimeofday(&endtime, NULL) == -1)
|
if (sudo_gettime_real(&endtime) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
sudo_timevaladd(&endtime, &timeout, &endtime);
|
sudo_timespecadd(&endtime, timeout, &endtime);
|
||||||
}
|
}
|
||||||
rval = select(0, NULL, NULL, NULL, &timeout);
|
rval = select(0, NULL, NULL, NULL, &tv);
|
||||||
if (rts != NULL && rval == -1 && errno == EINTR) {
|
if (remainder != NULL) {
|
||||||
if (gettimeofday(&now, NULL) == -1)
|
if (rval == 0) {
|
||||||
return -1;
|
/* Timeout expired, no remaining time. */
|
||||||
sudo_timevalsub(&endtime, &now, &endtime);
|
sudo_timespecclear(remainder);
|
||||||
TIMEVAL_TO_TIMESPEC(&endtime, rts);
|
} else if (errno == EINTR) {
|
||||||
|
/* Interrupted, compute remaining time. */
|
||||||
|
if (sudo_gettime_real(&now) == -1)
|
||||||
|
return -1;
|
||||||
|
sudo_timespecsub(&endtime, &now, remainder);
|
||||||
|
if (remainder->tv_sec < 0 || remainder->tv_nsec < 0)
|
||||||
|
sudo_timespecclear(remainder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user