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