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
+