I've written a utility to talk to TomTom GPS watches over Bluetooth, and am trying to make it run nicely as a run-and-forget background daemon.
The program periodically communicates with the GPS device and then sleep
s for a while until it's needed again.
I've noticed that sleep()
interacts strangely with system suspend: when I enter system suspend (laptop running Linux 3.16.0 kernel) and then wake the computer back up, sleep
doesn't appear to notice the suspend time. For example, take the following sleep.c
:
#include <time.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char**argv)
{
time_t t=time(NULL);
printf("sleep at: %s", ctime(&t));
sleep(atoi(argv[1]));
t=time(NULL);
printf("wake at: %s", ctime(&t));
}
dlenski@dlenski-ultra:~$
Compile, run, and sleep halfway through;
$ gcc sleep.c -o sleep
$ ./sleep 30
sleep at: Fri Aug 21 21:05:36 2015
<suspend computer for 17 seconds>
wake at: Fri Aug 21 21:06:23 2015
Is there a correct way to suspend program execution in a way that's clock-time-aware rather than system-uptime-aware?
(I've also tried usleep
, nanosleep
, and alarm
and found that they behave similarly.)
UPDATE: setitimer
, as suggested by @HuStmpHrrr, sounded quite promising... but appears to have the same problem.
This version pauses for more than the requested 30s when I suspend in the middle of it...
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
void sighandler() {}
int main(int argc, char**argv)
{
time_t t=time(NULL);
printf("sleep at: %s", ctime(&t));
signal(SIGALRM, sighandler);
struct itimerval timer = {.it_interval={0,0},
.it_value={atoi(argv[1]),0}};
setitimer(ITIMER_REAL, &timer, NULL);
pause();
t=time(NULL);
printf("wake at: %s", ctime(&t));
}