X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/914440b4fc3c5ecb7d9eedf4da6f2a1c7ec2e7a9..9c9ce8a125f35bab61c829bdd58bdf77b8352d5e:/slstatus.c

diff --git a/slstatus.c b/slstatus.c
index 89a3268..9bd9e81 100644
--- a/slstatus.c
+++ b/slstatus.c
@@ -1,7 +1,5 @@
 /* See LICENSE file for copyright and license details. */
-#include <err.h>
 #include <errno.h>
-#include <locale.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -19,9 +17,8 @@ struct arg {
 	const char *args;
 };
 
-char *argv0;
 char buf[1024];
-static unsigned short int done;
+static int done;
 static Display *dpy;
 
 #include "config.h"
@@ -45,8 +42,7 @@ difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
 static void
 usage(void)
 {
-	fprintf(stderr, "usage: %s [-s]\n", argv0);
-	exit(1);
+	die("usage: %s [-so]", argv0);
 }
 
 int
@@ -55,13 +51,18 @@ main(int argc, char *argv[])
 	struct sigaction act;
 	struct timespec start, current, diff, intspec, wait;
 	size_t i, len;
-	int sflag = 0;
+	int sflag, oflag, ret;
 	char status[MAXLEN];
+	const char *res;
 
+	sflag = oflag = 0;
 	ARGBEGIN {
 		case 's':
 			sflag = 1;
 			break;
+		case 'o':
+			oflag = 1;
+			break;
 		default:
 			usage();
 	} ARGEND
@@ -70,40 +71,55 @@ main(int argc, char *argv[])
 		usage();
 	}
 
-	setlocale(LC_ALL, "");
-
 	memset(&act, 0, sizeof(act));
 	act.sa_handler = terminate;
 	sigaction(SIGINT,  &act, NULL);
 	sigaction(SIGTERM, &act, NULL);
 
+	if (sflag) {
+		setbuf(stdout, NULL);
+	}
+
 	if (!sflag && !(dpy = XOpenDisplay(NULL))) {
-		fprintf(stderr, "slstatus: cannot open display");
-		return 1;
+		die("XOpenDisplay: Failed to open display");
 	}
 
 	while (!done) {
-		clock_gettime(CLOCK_MONOTONIC, &start);
+		if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) {
+			die("clock_gettime:");
+		}
 
 		status[0] = '\0';
 		for (i = len = 0; i < LEN(args); i++) {
-			len += snprintf(status + len, sizeof(status) - len,
-			                args[i].fmt, args[i].func(args[i].args));
-
-			if (len >= sizeof(status)) {
-				status[sizeof(status) - 1] = '\0';
+			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) {
-			printf("%s\n", status);
+			if (printf("%s\n", status) < 0) {
+				die("printf:");
+			}
 		} else {
-			XStoreName(dpy, DefaultRootWindow(dpy), status);
-			XSync(dpy, False);
+			if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) {
+				die("XStoreName: Allocation failed");
+			}
+			XFlush(dpy);
+		}
+
+		if (oflag) {
+			done = 1;
 		}
 
 		if (!done) {
-			clock_gettime(CLOCK_MONOTONIC, &current);
+			if (clock_gettime(CLOCK_MONOTONIC, &current) < 0) {
+				die("clock_gettime:");
+			}
 			difftimespec(&diff, &current, &start);
 
 			intspec.tv_sec = interval / 1000;
@@ -111,14 +127,19 @@ main(int argc, char *argv[])
 			difftimespec(&wait, &intspec, &diff);
 
 			if (wait.tv_sec >= 0) {
-				nanosleep(&wait, NULL);
+				if (nanosleep(&wait, NULL) < 0 &&
+				    errno != EINTR) {
+					die("nanosleep:");
+				}
 			}
 		}
 	}
 
 	if (!sflag) {
 		XStoreName(dpy, DefaultRootWindow(dpy), NULL);
-		XCloseDisplay(dpy);
+		if (XCloseDisplay(dpy) < 0) {
+			die("XCloseDisplay: Failed to close display");
+		}
 	}
 
 	return 0;