diff --git a/dwmblocks.c b/dwmblocks.c index 3f7f568..0342970 100644 --- a/dwmblocks.c +++ b/dwmblocks.c @@ -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), "");