slstatus-signals-1.0.patch - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
slstatus-signals-1.0.patch (5019B) | |
--- | |
1 From fabec4fb9f3cb749f33dc97188106c73a20ca7db Mon Sep 17 00:00:00 2001 | |
2 From: sewn <[email protected]> | |
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 (exampl… | |
26 @@ -64,6 +64,9 @@ static const char unknown_str[] = "n/a"; | |
27 * wifi_perc WiFi signal in percent interface name (… | |
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 … | |
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[… | |
83 + (args[i].signal >= 0 && upsigno - SIGRTMIN == a… | |
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]… | |
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 == SIGUSR… | |
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(statu… | |
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), sta… | |
174 - die("XStoreName: Allocation failed"); | |
175 - XFlush(dpy); | |
176 - } | |
177 + printstatus(iter++); | |
178 | |
179 if (!done) { | |
180 if (clock_gettime(CLOCK_MONOTONIC, ¤t) < … | |
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 |