According to the sleep()
manpage...
NOTES
On Linux, sleep() is implemented via nanosleep(2). See the nanosleep(2) man page for a discussion of the
clock used.
So I have rewritten your program to use nanosleep. As you are working with WSL, I've dropped any reference to Win32, only Linux. Well, the thing is that this program exits nanosleep() prematurely, with an "Invalid argument" error. I cannot see why is that.
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
void timeDelay (time_t no_of_seconds)
{
struct timespec req, rem;
int res;
req.tv_sec = no_of_seconds;
req.tv_nsec = 0;
do
{
rem.tv_sec = 0;
rem.tv_nsec = 0;
res = nanosleep (&req, &rem);
req = rem;
}
while (res == EINTR);
if (res)
perror("nanosleep");
}
void somefunction()
{
printf("\t\t Load ... \n\t\t");
fflush(stdout);
for (int i = 1; i <= 60; i++)
{
fflush(stdout);
timeDelay(1);
putchar('*');
}
}
int main()
{
somefunction();
return 0;
}
I've also tried with NULL
instead of rem
, and reissuing nanosleep()
with the original time instead of the remaining time, and putting the test and the perror() within the loop to print all possible errors from nanosleep. No matter what I do, I always receive an EINVAL
from the first call to nanosleep()
So, there seems to be a real problema with nanosleep()
on WSL. See https://github.com/microsoft/WSL/issues/4898 . It mentions a problem for WSL being unable to read the realtime clock from a certain version of glibc. I tried this in my WSL terminal:
$ sleep 1
sleep: cannot read realtime clock: Invalid argument
There is a mention of a workaround here:
https://github.com/microsoft/WSL/issues/4898#issuecomment-612622828
I've tried with another approach: using clock_nanosleep()
so I can choose another source for the clock: in the above program, just change the call to nanosleep()
with this other to clock_nanosleep()
clock_nanosleep (CLOCK_MONOTONIC, 0, &req, &rem);
There is no problem with CLOCK_MONOTONIC, and now the program works!