Fix separate USR1 handling & time display logic
Make remaining_time() more atomic, in order to avoid receiving a signal during execution of this function. Receiving a signal during a signal handler is an undefined behavior.
This commit is contained in:
parent
50ed6952f2
commit
3678854ad1
36
spt.c
36
spt.c
|
@ -24,14 +24,15 @@ typedef struct {
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static int i, timecount, suspend;
|
volatile static sig_atomic_t display, suspend;
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
static void die(const char *errstr, ...);
|
static void die(const char *errstr, ...);
|
||||||
static void spawn(char *cmd, char *cmt);
|
static void spawn(char *cmd, char *cmt);
|
||||||
static void notify_send(char *cmt);
|
static void notify_send(char *cmt);
|
||||||
static void remaining_time(int sigint);
|
static void display_time(int timecount);
|
||||||
static void toggle(int sigint);
|
static void toggle_display(int sigint);
|
||||||
|
static void toggle_suspend(int sigint);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
|
||||||
/* functions implementations */
|
/* functions implementations */
|
||||||
|
@ -78,21 +79,27 @@ notify_send(char *cmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
remaining_time(int sigint)
|
display_time(int timecount)
|
||||||
{
|
{
|
||||||
char buf[17];
|
char buf[17];
|
||||||
|
|
||||||
// FIXME: signal handlers should only do very few things, like
|
|
||||||
// setting volatile sig_atomic_t
|
|
||||||
snprintf(buf, 17, "Remaining: %02d:%02d\n",
|
snprintf(buf, 17, "Remaining: %02d:%02d\n",
|
||||||
(timers[i].tmr - timecount) / 60,
|
timecount / 60,
|
||||||
(timers[i].tmr - timecount) % 60);
|
timecount % 60);
|
||||||
|
|
||||||
notify_send(buf);
|
notify_send(buf);
|
||||||
|
display = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
toggle(int sigint) {
|
toggle_display(int sigint)
|
||||||
|
{
|
||||||
|
display = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toggle_suspend(int sigint)
|
||||||
|
{
|
||||||
suspend ^= 1;
|
suspend ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +114,7 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sigset_t emptymask;
|
sigset_t emptymask;
|
||||||
|
int i, timecount;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -124,7 +132,7 @@ main(int argc, char *argv[])
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
/* add SIGUSR1 handler: remaining_time */
|
/* add SIGUSR1 handler: remaining_time */
|
||||||
sa.sa_handler = remaining_time;
|
sa.sa_handler = toggle_display;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
|
|
||||||
|
@ -132,7 +140,7 @@ main(int argc, char *argv[])
|
||||||
die("cannot associate SIGUSR1 to handler\n");
|
die("cannot associate SIGUSR1 to handler\n");
|
||||||
|
|
||||||
/* add SIGUSR2 handler: toggle */
|
/* add SIGUSR2 handler: toggle */
|
||||||
sa.sa_handler = toggle;
|
sa.sa_handler = toggle_suspend;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
|
|
||||||
|
@ -142,13 +150,17 @@ main(int argc, char *argv[])
|
||||||
for (i = 0; ; i = (i + 1) % LEN(timers)) {
|
for (i = 0; ; i = (i + 1) % LEN(timers)) {
|
||||||
notify_send(timers[i].cmt);
|
notify_send(timers[i].cmt);
|
||||||
timecount = 0;
|
timecount = 0;
|
||||||
while (timecount < timers[i].tmr)
|
while (timecount < timers[i].tmr) {
|
||||||
|
if (display)
|
||||||
|
display_time(timecount);
|
||||||
|
|
||||||
if (suspend)
|
if (suspend)
|
||||||
sigsuspend(&emptymask);
|
sigsuspend(&emptymask);
|
||||||
else {
|
else {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
timecount++;
|
timecount++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user