commit ac49fc10ff3095febc4a609e98a56ff246c834c9
parent a69026574ed8e7dcbc4f82ea753e06495acd5dee
Author: sewn <sewn@disroot.org>
Date: Thu, 2 May 2024 12:03:33 +0300
[slstatus] add signals patch
Diffstat:
2 files changed, 224 insertions(+), 0 deletions(-)
diff --git a/tools.suckless.org/slstatus/patches/signals/index.md b/tools.suckless.org/slstatus/patches/signals/index.md
@@ -0,0 +1,17 @@
+signals
+======
+
+Description
+-----------
+This patch lets slstatus handle signals and use intervals
+to update modules in the status text.
+
+This behavior is similar to that of [dwmblocks](https://github.com/torrinfail/dwmblocks).
+
+Download
+--------
+* [slstatus-signals-1.0.patch](slstatus-signals-1.0.patch)
+
+Authors
+-------
+* sewn <sewn@disroot.org>
diff --git a/tools.suckless.org/slstatus/patches/signals/slstatus-signals-1.0.patch b/tools.suckless.org/slstatus/patches/signals/slstatus-signals-1.0.patch
@@ -0,0 +1,207 @@
+From 048bac828383fd30232e4b8aeb764e0de7754f7f Mon Sep 17 00:00:00 2001
+From: sewn <sewn@disroot.org>
+Date: Thu, 2 May 2024 11:59:01 +0300
+Subject: [PATCH] implement signals & intervals
+
+---
+ config.def.h | 11 +++--
+ slstatus.c | 111 +++++++++++++++++++++++++++++++++------------------
+ 2 files changed, 79 insertions(+), 43 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index d805331..a36cdb7 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -6,8 +6,8 @@ const unsigned int interval = 1000;
+ /* text to show if no value can be retrieved */
+ static const char unknown_str[] = "n/a";
+
+-/* maximum output string length */
+-#define MAXLEN 2048
++/* maximum command output length */
++#define CMDLEN 128
+
+ /*
+ * function description argument (example)
+@@ -64,6 +64,9 @@ static const char unknown_str[] = "n/a";
+ * wifi_perc WiFi signal in percent interface name (wlan0)
+ */
+ static const struct arg args[] = {
+- /* function format argument */
+- { datetime, "%s", "%F %T" },
++ /* function format argument interval signal */
++ { datetime, "%s", "%F %T", 1, 0 },
+ };
++
++/* maximum output string length */
++#define MAXLEN CMDLEN * LEN(args)
+diff --git a/slstatus.c b/slstatus.c
+index fd31313..ae12e7d 100644
+--- a/slstatus.c
++++ b/slstatus.c
+@@ -15,20 +15,19 @@ struct arg {
+ const char *(*func)(const char *);
+ const char *fmt;
+ const char *args;
++ unsigned int interval;
++ unsigned int signal;
+ };
+
+ char buf[1024];
++static int sflag = 0;
+ static volatile sig_atomic_t done;
+ static Display *dpy;
+
+ #include "config.h"
++#define MAXLEN CMDLEN * LEN(args)
+
+-static void
+-terminate(const int signo)
+-{
+- if (signo != SIGUSR1)
+- done = 1;
+-}
++static char statuses[LEN(args)][CMDLEN] = {0};
+
+ static void
+ difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
+@@ -44,17 +43,69 @@ usage(void)
+ die("usage: %s [-v] [-s] [-1]", argv0);
+ }
+
++static void
++printstatus(int it, unsigned int upsig)
++{
++ size_t i;
++ int update;
++ char status[MAXLEN];
++ const char *res;
++
++ for (i = 0; i < LEN(args); i++) {
++ if ((upsig == 0 || upsig != args[i].signal) &&
++ ((args[i].interval == 0 || it % args[i].interval != 0 || upsig != 0) &&
++ it != -1))
++ continue;
++
++ update = 1;
++
++ if (!(res = args[i].func(args[i].args)))
++ res = unknown_str;
++
++ if (esnprintf(statuses[i], sizeof(statuses[i]), args[i].fmt, res) < 0)
++ break;
++ }
++
++ status[0] = '\0';
++ for (i = 0; i < LEN(args); i++)
++ strcat(status, statuses[i]);
++ status[strlen(status)] = '\0';
++
++ if (!update)
++ return;
++
++ if (sflag) {
++ puts(status);
++ fflush(stdout);
++ if (ferror(stdout))
++ die("puts:");
++ } else {
++ if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0)
++ die("XStoreName: Allocation failed");
++ XFlush(dpy);
++ }
++}
++
++
++static void
++sighandler(const int signo)
++{
++ if (signo <= SIGRTMAX && signo >= SIGRTMIN)
++ printstatus(0, signo - SIGRTMIN);
++ else if (signo == SIGUSR1)
++ printstatus(-1, 0);
++ else
++ done = 1;
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+ struct sigaction act;
+ struct timespec start, current, diff, intspec, wait;
+- size_t i, len;
+- int sflag, ret;
+- char status[MAXLEN];
+- const char *res;
++ size_t i;
++ int ret, time = -1;
+
+- sflag = 0;
+ ARGBEGIN {
+ case 'v':
+ die("slstatus-"VERSION);
+@@ -72,11 +123,13 @@ main(int argc, char *argv[])
+ usage();
+
+ memset(&act, 0, sizeof(act));
+- act.sa_handler = terminate;
++ act.sa_handler = sighandler;
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+- act.sa_flags |= SA_RESTART;
+ sigaction(SIGUSR1, &act, NULL);
++ for (i = 0; i < LEN(args); i++)
++ if (args[i].signal > 0)
++ sigaction(SIGRTMIN+args[i].signal, &act, NULL);
+
+ if (!sflag && !(dpy = XOpenDisplay(NULL)))
+ die("XOpenDisplay: Failed to open display");
+@@ -85,28 +138,7 @@ main(int argc, char *argv[])
+ if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
+ die("clock_gettime:");
+
+- status[0] = '\0';
+- for (i = len = 0; i < LEN(args); i++) {
+- if (!(res = args[i].func(args[i].args)))
+- res = unknown_str;
+-
+- if ((ret = esnprintf(status + len, sizeof(status) - len,
+- args[i].fmt, res)) < 0)
+- break;
+-
+- len += ret;
+- }
+-
+- if (sflag) {
+- puts(status);
+- fflush(stdout);
+- if (ferror(stdout))
+- die("puts:");
+- } else {
+- if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0)
+- die("XStoreName: Allocation failed");
+- XFlush(dpy);
+- }
++ printstatus(time++, 0);
+
+ if (!done) {
+ if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0)
+@@ -117,10 +149,11 @@ main(int argc, char *argv[])
+ intspec.tv_nsec = (interval % 1000) * 1E6;
+ difftimespec(&wait, &intspec, &diff);
+
+- if (wait.tv_sec >= 0 &&
+- nanosleep(&wait, NULL) < 0 &&
+- errno != EINTR)
+- die("nanosleep:");
++ do
++ ret = nanosleep(&wait, &wait);
++ while (wait.tv_sec >= 0 && ret < 0 && errno == EINTR);
++ if (ret < 0)
++ die("nanosleep:");
+ }
+ } while (!done);
+
+--
+2.44.0
+