dwmblocks-statuscmd-20210402-96cbb45.diff (3331B)
1 From 1669878c08607f481e3f879d6914fc4d3c9d7206 Mon Sep 17 00:00:00 2001 2 From: Daniel Bylinka <daniel.bylinka@gmail.com> 3 Date: Fri, 2 Apr 2021 19:20:17 +0200 4 Subject: [PATCH] [statuscmd] Format status text and handle button signals 5 6 --- 7 dwmblocks.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 8 1 file changed, 41 insertions(+), 7 deletions(-) 9 10 diff --git a/dwmblocks.c b/dwmblocks.c 11 index ded717c..78fdeb5 100644 12 --- a/dwmblocks.c 13 +++ b/dwmblocks.c 14 @@ -3,6 +3,7 @@ 15 #include<string.h> 16 #include<unistd.h> 17 #include<signal.h> 18 +#include<sys/wait.h> 19 #ifndef NO_X 20 #include<X11/Xlib.h> 21 #endif 22 @@ -27,14 +28,14 @@ typedef struct { 23 #ifndef __OpenBSD__ 24 void dummysighandler(int num); 25 #endif 26 -void sighandler(int num); 27 void getcmds(int time); 28 void getsigcmds(unsigned int signal); 29 void setupsignals(); 30 -void sighandler(int signum); 31 +void sighandler(int signum, siginfo_t *si, void *ucontext); 32 int getstatus(char *str, char *last); 33 void statusloop(); 34 void termhandler(); 35 +void chldhandler(); 36 void pstdout(); 37 #ifndef NO_X 38 void setroot(); 39 @@ -58,6 +59,8 @@ static int returnStatus = 0; 40 //opens process *cmd and stores output in *output 41 void getcmd(const Block *block, char *output) 42 { 43 + if (block->signal) 44 + *output++ = block->signal; 45 strcpy(output, block->icon); 46 FILE *cmdf = popen(block->command, "r"); 47 if (!cmdf) 48 @@ -102,15 +105,18 @@ void getsigcmds(unsigned int signal) 49 50 void setupsignals() 51 { 52 + struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO }; 53 #ifndef __OpenBSD__ 54 /* initialize all real time signals with dummy handler */ 55 - for (int i = SIGRTMIN; i <= SIGRTMAX; i++) 56 + for (int i = SIGRTMIN; i <= SIGRTMAX; i++) { 57 signal(i, dummysighandler); 58 + sigaddset(&sa.sa_mask, i); 59 + } 60 #endif 61 62 for (unsigned int i = 0; i < LENGTH(blocks); i++) { 63 if (blocks[i].signal > 0) 64 - signal(SIGMINUS+blocks[i].signal, sighandler); 65 + sigaction(SIGMINUS+blocks[i].signal, &sa, NULL); 66 } 67 68 } 69 @@ -178,10 +184,32 @@ void dummysighandler(int signum) 70 } 71 #endif 72 73 -void sighandler(int signum) 74 +void sighandler(int signum, siginfo_t *si, void *ucontext) 75 { 76 - getsigcmds(signum-SIGPLUS); 77 - writestatus(); 78 + if (si->si_value.sival_int) { 79 + pid_t parent = getpid(); 80 + if (fork() == 0) { 81 +#ifndef NO_X 82 + if (dpy) 83 + close(ConnectionNumber(dpy)); 84 +#endif 85 + int i; 86 + for (i = 0; i < LENGTH(blocks) && blocks[i].signal != signum-SIGRTMIN; i++); 87 + 88 + char shcmd[1024]; 89 + sprintf(shcmd, "%s; kill -%d %d", blocks[i].command, SIGRTMIN+blocks[i].signal, parent); 90 + char *cmd[] = { "/bin/sh", "-c", shcmd, NULL }; 91 + char button[2] = { '0' + si->si_value.sival_int, '\0' }; 92 + setenv("BUTTON", button, 1); 93 + setsid(); 94 + execvp(cmd[0], cmd); 95 + perror(cmd[0]); 96 + exit(EXIT_SUCCESS); 97 + } 98 + } else { 99 + getsigcmds(signum-SIGPLUS); 100 + writestatus(); 101 + } 102 } 103 104 void termhandler() 105 @@ -189,6 +217,11 @@ void termhandler() 106 statusContinue = 0; 107 } 108 109 +void chldhandler() 110 +{ 111 + while (0 < waitpid(-1, NULL, WNOHANG)); 112 +} 113 + 114 int main(int argc, char** argv) 115 { 116 for (int i = 0; i < argc; i++) {//Handle command line arguments 117 @@ -205,6 +238,7 @@ int main(int argc, char** argv) 118 delim[delimLen++] = '\0'; 119 signal(SIGTERM, termhandler); 120 signal(SIGINT, termhandler); 121 + signal(SIGCHLD, chldhandler); 122 statusloop(); 123 #ifndef NO_X 124 XCloseDisplay(dpy); 125 -- 126 2.31.0 127