commit ac49fc10ff3095febc4a609e98a56ff246c834c9
Author: sewn <s...@disroot.org>
Date:   Thu May 2 12:03:33 2024 +0300

    [slstatus] add signals patch

diff --git a/tools.suckless.org/slstatus/patches/signals/index.md 
b/tools.suckless.org/slstatus/patches/signals/index.md
new file mode 100644
index 00000000..88f0555c
--- /dev/null
+++ 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 <s...@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
new file mode 100644
index 00000000..12bfb071
--- /dev/null
+++ 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 <s...@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] = '++ for (i = 0; i < LEN(args); i++)
++              strcat(status, statuses[i]);
++      status[strlen(status)] = '++
++      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] = '+-         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, &current) < 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
+


Reply via email to