sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

slstatus-signals-1.0.patch (4999B)


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