slstatus-signals-1.0.patch - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
slstatus-signals-1.0.patch (5019B)
---
1 From fabec4fb9f3cb749f33dc97188106c73a20ca7db Mon Sep 17 00:00:00 2001
2 From: sewn <sewn@disroot.org>
3 Date: Wed, 5 Feb 2025 16:00:52 +0300
4 Subject: [PATCH] implement signals & turns
5
6 ---
7 config.def.h | 11 ++++--
8 slstatus.c | 107 ++++++++++++++++++++++++++++++++-------------------
9 2 files changed, 74 insertions(+), 44 deletions(-)
10
11 diff --git a/config.def.h b/config.def.h
12 index d805331..a89127b 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 turn 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..b3dbae8 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 turn;
47 + int signal;
48 };
49
50 char buf[1024];
51 -static volatile sig_atomic_t done;
52 +static int sflag = 0;
53 +static volatile sig_atomic_t done, upsigno;
54 static Display *dpy;
55
56 #include "config.h"
57 +#define MAXLEN CMDLEN * LEN(args)
58
59 -static void
60 -terminate(const int signo)
61 -{
62 - if (signo != SIGUSR1)
63 - done = 1;
64 -}
65 +static char statuses[LEN(args)][CMDLEN] = {0};
66
67 static void
68 difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
69 @@ -44,17 +43,61 @@ usage(void)
70 die("usage: %s [-v] [-s] [-1]", argv0);
71 }
72
73 +static void
74 +printstatus(unsigned int iter)
75 +{
76 + size_t i;
77 + char status[MAXLEN];
78 + const char *res;
79 +
80 + for (i = 0; i < LEN(args); i++) {
81 + if (!((!iter && !upsigno) || upsigno == SIGUSR1 ||
82 + (!upsigno && args[i].turn > 0 && !(iter % args[i].turn)) ||
83 + (args[i].signal >= 0 && upsigno - SIGRTMIN == args[i].signal)))
84 + continue;
85 +
86 + if (!(res = args[i].func(args[i].args)))
87 + res = unknown_str;
88 +
89 + if (esnprintf(statuses[i], sizeof(statuses[i]), args[i].fmt, res) < 0)
90 + break;
91 + }
92 +
93 + status[0] = '\0';
94 + for (i = 0; i < LEN(args); i++)
95 + strcat(status, statuses[i]);
96 + status[strlen(status)] = '\0';
97 +
98 + if (sflag) {
99 + puts(status);
100 + fflush(stdout);
101 + if (ferror(stdout))
102 + die("puts:");
103 + } else {
104 + if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0)
105 + die("XStoreName: Allocation failed");
106 + XFlush(dpy);
107 + }
108 +}
109 +
110 +
111 +static void
112 +sighandler(const int signo)
113 +{
114 + if ((signo <= SIGRTMAX && signo >= SIGRTMIN) || signo == SIGUSR1)
115 + upsigno = signo;
116 + else
117 + done = 1;
118 +}
119 +
120 int
121 main(int argc, char *argv[])
122 {
123 struct sigaction act;
124 struct timespec start, current, diff, intspec, wait;
125 - size_t i, len;
126 - int sflag, ret;
127 - char status[MAXLEN];
128 - const char *res;
129 + unsigned int iter = 0;
130 + int i, ret;
131
132 - sflag = 0;
133 ARGBEGIN {
134 case 'v':
135 die("slstatus-"VERSION);
136 @@ -72,11 +115,12 @@ main(int argc, char *argv[])
137 usage();
138
139 memset(&act, 0, sizeof(act));
140 - act.sa_handler = terminate;
141 + act.sa_handler = sighandler;
142 sigaction(SIGINT, &act, NULL);
143 sigaction(SIGTERM, &act, NULL);
144 - act.sa_flags |= SA_RESTART;
145 sigaction(SIGUSR1, &act, NULL);
146 + for (i = SIGRTMIN; i <= SIGRTMAX; i++)
147 + sigaction(i, &act, NULL);
148
149 if (!sflag && !(dpy = XOpenDisplay(NULL)))
150 die("XOpenDisplay: Failed to open display");
151 @@ -85,28 +129,7 @@ main(int argc, char *argv[])
152 if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
153 die("clock_gettime:");
154
155 - status[0] = '\0';
156 - for (i = len = 0; i < LEN(args); i++) {
157 - if (!(res = args[i].func(args[i].args)))
158 - res = unknown_str;
159 -
160 - if ((ret = esnprintf(status + len, sizeof(status) - len,
161 - args[i].fmt, res)) < 0)
162 - break;
163 -
164 - len += ret;
165 - }
166 -
167 - if (sflag) {
168 - puts(status);
169 - fflush(stdout);
170 - if (ferror(stdout))
171 - die("puts:");
172 - } else {
173 - if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0)
174 - die("XStoreName: Allocation failed");
175 - XFlush(dpy);
176 - }
177 + printstatus(iter++);
178
179 if (!done) {
180 if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0)
181 @@ -117,10 +140,14 @@ main(int argc, char *argv[])
182 intspec.tv_nsec = (interval % 1000) * 1E6;
183 difftimespec(&wait, &intspec, &diff);
184
185 - if (wait.tv_sec >= 0 &&
186 - nanosleep(&wait, NULL) < 0 &&
187 - errno != EINTR)
188 - die("nanosleep:");
189 + while(wait.tv_sec >= 0 &&
190 + (ret = nanosleep(&wait, &wait)) < 0 &&
191 + errno == EINTR && !done) {
192 + printstatus(0);
193 + errno = upsigno = 0;
194 + }
195 + if (ret < 0 && errno != EINTR)
196 + die("nanosleep:");
197 }
198 } while (!done);
199
200 --
201 2.47.1
202