Reputation: 3035
I'm trying to learn how to use sigtimedwait(), but I find that it's not waiting for the timeout to complete. Below it seems to return EAGAIN 4s faster than it should (1s faster per 1min of timeout):
#include <signal.h>
#include <syslog.h>
#include <stdarg.h>
#include <stddef.h>
#include <errno.h>
int main(int argc, char* argv[]) {
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog ("SIG_TIMED_WAITER", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
syslog (LOG_NOTICE, "Started");
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
struct timespec to;
to.tv_sec = 240;
to.tv_nsec = 0;
int ret = sigtimedwait(&set, NULL, &to);
if(ret < 0) {
if (errno == EAGAIN) {
syslog (LOG_NOTICE, "EAGAIN: TimedWait complete...");
} else {
syslog (LOG_NOTICE, "ERROR!");
}
} else {
syslog (LOG_NOTICE, "Interrupted by signum: %d.", ret);
}
syslog (LOG_NOTICE, "Terminated.");
closelog();
}
And here's the output:
$ tail -f /var/log/syslog|grep "SIG_TIMED_WAITER"
Jan 7 15:39:41 localhost SIG_TIMED_WAITER[13275]: Started
Jan 7 15:43:36 localhost SIG_TIMED_WAITER[13275]: EAGAIN: TimedWait complete...
Jan 7 15:43:36 localhost SIG_TIMED_WAITER[13275]: Terminated.
I had expected to see "EAGAIN: TimedWait complete..." logged four seconds later.
Is there something wrong with my code, or is this due to some other reason? Note that I do not see this with, for example, a select() that waits for four minutes.
Upvotes: 4
Views: 685
Reputation: 16540
the LOG_LOCAL1
is a reserved item,. I.E. do not use it
Instead use LOG_USER
It is easier to follow the action if the options parameter also has LOG_PERROR
Then the output will also be logged on stderr
.
Here is a corrected/working version of the program.
#define _GNU_SOURCE
#include <signal.h>
#include <syslog.h>
#include <stdarg.h>
#include <stddef.h>
#include <errno.h>
int main( void )
{
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog ("SIG_TIMED_WAITER", LOG_CONS | LOG_PID | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
syslog (LOG_NOTICE, "Started");
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
struct timespec to;
to.tv_sec = 240;
to.tv_nsec = 0;
int ret = sigtimedwait(&set, NULL, &to);
if(ret < 0)
{
if (errno == EAGAIN)
{
syslog (LOG_NOTICE, "EAGAIN: TimedWait complete...");
}
else
{
syslog (LOG_NOTICE, "ERROR!");
}
}
else
{
syslog (LOG_NOTICE, "Interrupted by signum: %d.", ret);
}
syslog (LOG_NOTICE, "Terminated.");
closelog();
return 0;
} // end function: main
I'm running ubuntu linux 14.04
(in this case, the 15212
is the PID of the console /terminal where the program was run.)
from the console/terminal (from the stderr output)
SIG_TIMED_WAITER[15212]: Started
SIG_TIMED_WAITER[15212]: EAGAIN: TimedWait complete...
SIG_TIMED_WAITER[15212]: Terminated.
from /var/log/syslog:
Jan 7 05:50:07 rkwill-desktop SIG_TIMED_WAITER[15212]: Started
Jan 7 05:54:07 rkwill-desktop SIG_TIMED_WAITER[15212]: EAGAIN: TimedWait complete...
Jan 7 05:54:07 rkwill-desktop SIG_TIMED_WAITER[15212]: Terminated.
Notice: The time between the initial output and the EAGAIN
output was 4 minutes (240 seconds)
Upvotes: 1