slstatus-signals-1.0.patch (4999B)
1 From 08c9d252bb855b5a77b9bbcd29b31b71219d0e72 Mon Sep 17 00:00:00 2001 2 From: sewn <sewn@disroot.org> 3 Date: Thu, 2 May 2024 15:53:30 +0300 4 Subject: [PATCH] implement signals & intervals 5 6 --- 7 config.def.h | 11 ++++-- 8 slstatus.c | 110 +++++++++++++++++++++++++++++++++------------------ 9 2 files changed, 78 insertions(+), 43 deletions(-) 10 11 diff --git a/config.def.h b/config.def.h 12 index d805331..7fbd164 100644 13 --- a/config.def.h 14 +++ b/config.def.h 15 @@ -6,8 +6,8 @@ const unsigned int interval = 1000; 16 /* text to show if no value can be retrieved */ 17 static const char unknown_str[] = "n/a"; 18 19 -/* maximum output string length */ 20 -#define MAXLEN 2048 21 +/* maximum command output length */ 22 +#define CMDLEN 128 23 24 /* 25 * function description argument (example) 26 @@ -64,6 +64,9 @@ static const char unknown_str[] = "n/a"; 27 * wifi_perc WiFi signal in percent interface name (wlan0) 28 */ 29 static const struct arg args[] = { 30 - /* function format argument */ 31 - { datetime, "%s", "%F %T" }, 32 + /* function format argument interval signal */ 33 + { datetime, "%s", "%F %T", 1, -1 }, 34 }; 35 + 36 +/* maximum output string length */ 37 +#define MAXLEN CMDLEN * LEN(args) 38 diff --git a/slstatus.c b/slstatus.c 39 index fd31313..2c953cc 100644 40 --- a/slstatus.c 41 +++ b/slstatus.c 42 @@ -15,20 +15,19 @@ struct arg { 43 const char *(*func)(const char *); 44 const char *fmt; 45 const char *args; 46 + unsigned int interval; 47 + int signal; 48 }; 49 50 char buf[1024]; 51 +static int sflag = 0; 52 static volatile sig_atomic_t done; 53 static Display *dpy; 54 55 #include "config.h" 56 +#define MAXLEN CMDLEN * LEN(args) 57 58 -static void 59 -terminate(const int signo) 60 -{ 61 - if (signo != SIGUSR1) 62 - done = 1; 63 -} 64 +static char statuses[LEN(args)][CMDLEN] = {0}; 65 66 static void 67 difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) 68 @@ -44,17 +43,67 @@ usage(void) 69 die("usage: %s [-v] [-s] [-1]", argv0); 70 } 71 72 +static void 73 +printstatus(int it, int upsig) 74 +{ 75 + size_t i; 76 + int update = 0; 77 + char status[MAXLEN]; 78 + const char *res; 79 + 80 + for (i = 0; i < LEN(args); i++) { 81 + if (!(((args[i].interval > 0 && it > 0 && !(it % args[i].interval)) && upsig < 0) || 82 + (upsig > -1 && args[i].signal == upsig) || (it == -1 && upsig == -1))) 83 + continue; 84 + 85 + update = 1; 86 + 87 + if (!(res = args[i].func(args[i].args))) 88 + res = unknown_str; 89 + 90 + if (esnprintf(statuses[i], sizeof(statuses[i]), args[i].fmt, res) < 0) 91 + break; 92 + } 93 + 94 + if (!update) 95 + return; 96 + 97 + status[0] = '\0'; 98 + for (i = 0; i < LEN(args); i++) 99 + strcat(status, statuses[i]); 100 + status[strlen(status)] = '\0'; 101 + 102 + if (sflag) { 103 + puts(status); 104 + fflush(stdout); 105 + if (ferror(stdout)) 106 + die("puts:"); 107 + } else { 108 + if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) 109 + die("XStoreName: Allocation failed"); 110 + XFlush(dpy); 111 + } 112 +} 113 + 114 + 115 +static void 116 +sighandler(const int signo) 117 +{ 118 + if (signo <= SIGRTMAX && signo >= SIGRTMIN) 119 + printstatus(-1, signo - SIGRTMIN); 120 + else if (signo == SIGUSR1) 121 + printstatus(-1, -1); 122 + else 123 + done = 1; 124 +} 125 + 126 int 127 main(int argc, char *argv[]) 128 { 129 struct sigaction act; 130 struct timespec start, current, diff, intspec, wait; 131 - size_t i, len; 132 - int sflag, ret; 133 - char status[MAXLEN]; 134 - const char *res; 135 + int i, ret, time = 0; 136 137 - sflag = 0; 138 ARGBEGIN { 139 case 'v': 140 die("slstatus-"VERSION); 141 @@ -72,41 +121,23 @@ main(int argc, char *argv[]) 142 usage(); 143 144 memset(&act, 0, sizeof(act)); 145 - act.sa_handler = terminate; 146 + act.sa_handler = sighandler; 147 sigaction(SIGINT, &act, NULL); 148 sigaction(SIGTERM, &act, NULL); 149 - act.sa_flags |= SA_RESTART; 150 sigaction(SIGUSR1, &act, NULL); 151 + for (i = SIGRTMIN; i <= SIGRTMAX; i++) 152 + sigaction(i, &act, NULL); 153 154 if (!sflag && !(dpy = XOpenDisplay(NULL))) 155 die("XOpenDisplay: Failed to open display"); 156 157 + printstatus(-1, -1); 158 + 159 do { 160 if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) 161 die("clock_gettime:"); 162 163 - status[0] = '\0'; 164 - for (i = len = 0; i < LEN(args); i++) { 165 - if (!(res = args[i].func(args[i].args))) 166 - res = unknown_str; 167 - 168 - if ((ret = esnprintf(status + len, sizeof(status) - len, 169 - args[i].fmt, res)) < 0) 170 - break; 171 - 172 - len += ret; 173 - } 174 - 175 - if (sflag) { 176 - puts(status); 177 - fflush(stdout); 178 - if (ferror(stdout)) 179 - die("puts:"); 180 - } else { 181 - if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) 182 - die("XStoreName: Allocation failed"); 183 - XFlush(dpy); 184 - } 185 + printstatus(time++, -1); 186 187 if (!done) { 188 if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0) 189 @@ -117,10 +148,11 @@ main(int argc, char *argv[]) 190 intspec.tv_nsec = (interval % 1000) * 1E6; 191 difftimespec(&wait, &intspec, &diff); 192 193 - if (wait.tv_sec >= 0 && 194 - nanosleep(&wait, NULL) < 0 && 195 - errno != EINTR) 196 - die("nanosleep:"); 197 + do 198 + ret = nanosleep(&wait, &wait); 199 + while (wait.tv_sec >= 0 && ret < 0 && errno != EINTR && !done); 200 + if (ret < 0 && errno != EINTR) 201 + die("nanosleep:"); 202 } 203 } while (!done); 204 205 -- 206 2.44.0 207