Improved signal handling by implementing signal blocking

This commit is contained in:
Ashish Kumar Yadav 2020-07-26 00:22:08 +05:30
parent 9c4a0a37d3
commit 1e83bd57c9

View file

@ -29,7 +29,6 @@ typedef struct {
static void buttonhandler(int signal, siginfo_t *si, void *ucontext);
static void getcmd(Block *block, int sigval);
static void setroot();
static void setupsignals();
static void sighandler(int signal, siginfo_t *si, void *ucontext);
static void statusloop();
@ -41,6 +40,7 @@ static int statuscontinue = 1;
static char statusstr[STTLENGTH];
static size_t delimlength;
static Display *dpy;
static sigset_t blocksigmask;
void
buttonhandler(int signal, siginfo_t *si, void *ucontext)
@ -111,44 +111,45 @@ getcmd(Block *block, int sigval)
}
}
void
setroot()
{
if (updatestatus()) {
XStoreName(dpy, DefaultRootWindow(dpy), statusstr);
XFlush(dpy);
}
}
void
setupsignals()
{
struct sigaction sa;
sigemptyset(&sa.sa_mask);
/* to handle HUP, INT and TERM */
sa.sa_flags = SA_RESTART;
/* to handle INT, HUP and TERM */
sigemptyset(&sa.sa_mask);
sa.sa_handler = termhandler;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* to ignore unused realtime signals */
// sa.sa_flags = SA_RESTART;
// sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_IGN;
for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
for (int i = SIGRTMIN + 1; i <= SIGRTMAX; i++)
sigaction(i, &sa, NULL);
/* to prevent forked children from becoming zombies */
sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART;
// sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* to handle signals generated by dwm on click events */
sa.sa_flags = SA_RESTART | SA_SIGINFO;
// sigemptyset(&sa.sa_mask);
sa.sa_sigaction = buttonhandler;
sigaction(SIGRTMIN, &sa, NULL);
/* to handle update signals for individual blocks */
sa.sa_flags |= SA_NODEFER;
sa.sa_mask = blocksigmask;
sa.sa_sigaction = sighandler;
for (Block *current = blocks; current->pathu; current++)
if (current->signal > 0)
sigaction(SIGRTMIN + current->signal, &sa, NULL);
/* to prevent forked children from becoming zombies */
sa.sa_flags = SA_NOCLDWAIT | SA_RESTART;
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
}
void
@ -158,26 +159,40 @@ sighandler(int signal, siginfo_t *si, void *ucontext)
for (Block *current = blocks; current->pathu; current++)
if (current->signal == signal)
getcmd(current, si->si_value.sival_int);
setroot();
if (updatestatus()) {
XStoreName(dpy, DefaultRootWindow(dpy), statusstr);
XSync(dpy, False);
}
}
void
statusloop()
{
int i;
int i = 0;
setupsignals();
/* first run */
for (Block *current = blocks; current->pathu; current++)
if (current->interval >= 0)
if (current->interval >= 0) {
sigprocmask(SIG_BLOCK, &blocksigmask, NULL);
getcmd(current, NILL);
setroot();
sleep(SLEEPINTERVAL);
i = SLEEPINTERVAL;
sigprocmask(SIG_UNBLOCK, &blocksigmask, NULL);
}
goto enterloop;
/* main loop */
while (statuscontinue) {
for (Block *current = blocks; current->pathu; current++)
if (current->interval > 0 && i % current->interval == 0)
if (current->interval > 0 && i % current->interval == 0) {
sigprocmask(SIG_BLOCK, &blocksigmask, NULL);
getcmd(current, NILL);
setroot();
sigprocmask(SIG_UNBLOCK, &blocksigmask, NULL);
}
enterloop:
if (updatestatus()) {
sigprocmask(SIG_BLOCK, &blocksigmask, NULL);
XStoreName(dpy, DefaultRootWindow(dpy), statusstr);
XSync(dpy, False);
sigprocmask(SIG_UNBLOCK, &blocksigmask, NULL);
}
sleep(SLEEPINTERVAL);
i += SLEEPINTERVAL;
}
@ -295,6 +310,14 @@ main(int argc, char *argv[])
fputs("Error: could not open display.\n", stderr);
return 1;
}
sigemptyset(&blocksigmask);
sigaddset(&blocksigmask, SIGHUP);
sigaddset(&blocksigmask, SIGINT);
sigaddset(&blocksigmask, SIGTERM);
for (Block *current = blocks; current->pathu; current++)
if (current->signal > 0)
sigaddset(&blocksigmask, SIGRTMIN + current->signal);
setupsignals();
statusloop();
unlink(LOCKFILE);
XStoreName(dpy, DefaultRootWindow(dpy), "");