| 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 |