X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/9750a3d731cd381e832bcacf1d03e48ddb46cc16..0383146e5e616e81c13b23a127ecfa697feac7db:/components/swap.c

diff --git a/components/swap.c b/components/swap.c
index 08a97de..73d24df 100644
--- a/components/swap.c
+++ b/components/swap.c
@@ -1,80 +1,79 @@
 /* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../util.h"
+
 #if defined(__linux__)
-	#include <errno.h>
-	#include <stdio.h>
-	#include <string.h>
+	static size_t
+	pread(const char *path, char *buf, size_t bufsiz)
+	{
+		FILE *fp;
+		size_t bytes_read;
+
+		if (!(fp = fopen(path, "r"))) {
+			warn("fopen '%s':", path);
+			return 0;
+		}
+		if (!(bytes_read = fread(buf, sizeof(char), bufsiz, fp))) {
+			warn("fread '%s':", path);
+			fclose(fp);
+			return 0;
+		}
+		fclose(fp);
+
+		buf[bytes_read] = '\0';
 
-	#include "../util.h"
+		return bytes_read;
+	}
 
 	const char *
 	swap_free(void)
 	{
 		long total, free;
-		FILE *fp;
-		size_t bytes_read;
 		char *match;
 
-		fp = fopen("/proc/meminfo", "r");
-		if (fp == NULL) {
-			fprintf(stderr, "fopen '/proc/meminfo': %s\n",
-			        strerror(errno));
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
 			return NULL;
 		}
 
-		if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1,
-		                        fp)) == 0) {
-			fprintf(stderr, "fread '/proc/meminfo': %s\n",
-			        strerror(errno));
-			fclose(fp);
+		if (!(match = strstr(buf, "SwapTotal"))) {
 			return NULL;
 		}
-		fclose(fp);
-
-		if ((match = strstr(buf, "SwapTotal")) == NULL)
-			return NULL;
 		sscanf(match, "SwapTotal: %ld kB\n", &total);
 
-		if ((match = strstr(buf, "SwapFree")) == NULL)
+		if (!(match = strstr(buf, "SwapFree"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapFree: %ld kB\n", &free);
 
-		return bprintf("%f", (float)free / 1024 / 1024);
+		return fmt_scaled(free * 1024);
 	}
 
 	const char *
 	swap_perc(void)
 	{
 		long total, free, cached;
-		FILE *fp;
-		size_t bytes_read;
 		char *match;
 
-		fp = fopen("/proc/meminfo", "r");
-		if (fp == NULL) {
-			fprintf(stderr, "fopen '/proc/meminfo': %s\n",
-			        strerror(errno));
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
 			return NULL;
 		}
 
-		if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1,
-		                        fp)) == 0) {
-			fprintf(stderr, "fread '/proc/meminfo': %s\n",
-			        strerror(errno));
-			fclose(fp);
+		if (!(match = strstr(buf, "SwapTotal"))) {
 			return NULL;
 		}
-		fclose(fp);
-
-		if ((match = strstr(buf, "SwapTotal")) == NULL)
-			return NULL;
 		sscanf(match, "SwapTotal: %ld kB\n", &total);
 
-		if ((match = strstr(buf, "SwapCached")) == NULL)
+		if (!(match = strstr(buf, "SwapCached"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapCached: %ld kB\n", &cached);
 
-		if ((match = strstr(buf, "SwapFree")) == NULL)
+		if (!(match = strstr(buf, "SwapFree"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapFree: %ld kB\n", &free);
 
 		return bprintf("%d", 100 * (total - free - cached) / total);
@@ -84,69 +83,127 @@
 	swap_total(void)
 	{
 		long total;
-		FILE *fp;
-		size_t bytes_read;
 		char *match;
 
-		fp = fopen("/proc/meminfo", "r");
-		if (fp == NULL) {
-			fprintf(stderr, "fopen '/proc/meminfo': %s\n",
-			        strerror(errno));
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
 			return NULL;
 		}
-		if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1,
-		                        fp)) == 0) {
-			fprintf(stderr, "fread '/proc/meminfo': %s\n",
-			        strerror(errno));
-			fclose(fp);
-			return NULL;
-		}
-		fclose(fp);
 
-		if ((match = strstr(buf, "SwapTotal")) == NULL)
+		if (!(match = strstr(buf, "SwapTotal"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapTotal: %ld kB\n", &total);
 
-		return bprintf("%f", (float)total / 1024 / 1024);
+		return fmt_scaled(total * 1024);
 	}
 
 	const char *
 	swap_used(void)
 	{
 		long total, free, cached;
-		FILE *fp;
-		size_t bytes_read;
 		char *match;
 
-		fp = fopen("/proc/meminfo", "r");
-		if (fp == NULL) {
-			fprintf(stderr, "fopen '/proc/meminfo': %s\n",
-			        strerror(errno));
-			return NULL;
-		}
-		if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1,
-		                        fp)) == 0) {
-			fprintf(stderr, "fread '/proc/meminfo': %s\n",
-			        strerror(errno));
-			fclose(fp);
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
 			return NULL;
 		}
-		fclose(fp);
 
-		if ((match = strstr(buf, "SwapTotal")) == NULL)
+		if (!(match = strstr(buf, "SwapTotal"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapTotal: %ld kB\n", &total);
 
-		if ((match = strstr(buf, "SwapCached")) == NULL)
+		if (!(match = strstr(buf, "SwapCached"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapCached: %ld kB\n", &cached);
 
-		if ((match = strstr(buf, "SwapFree")) == NULL)
+		if (!(match = strstr(buf, "SwapFree"))) {
 			return NULL;
+		}
 		sscanf(match, "SwapFree: %ld kB\n", &free);
 
-		return bprintf("%f", (float)(total - free - cached) / 1024 / 1024);
+		return fmt_scaled((total - free - cached) * 1024);
 	}
 #elif defined(__OpenBSD__)
-	/* unimplemented */
+	#include <stdlib.h>
+	#include <sys/param.h> /* dbtob */
+	#include <sys/swap.h>
+	#include <sys/types.h>
+	#include <unistd.h>
+
+	static void
+	getstats(int *total, int *used)
+	{
+		struct swapent *sep, *fsep;
+		int rnswap, nswap, i;
+
+		nswap = swapctl(SWAP_NSWAP, 0, 0);
+		if (nswap < 1) {
+			warn("swaptctl 'SWAP_NSWAP':");
+		}
+
+		fsep = sep = calloc(nswap, sizeof(*sep));
+		if (!sep) {
+			warn("calloc 'nswap':");
+		}
+
+		rnswap = swapctl(SWAP_STATS, (void *)sep, nswap);
+		if (rnswap < 0) {
+			warn("swapctl 'SWAP_STATA':");
+		}
+
+		if (nswap != rnswap) {
+			warn("getstats: SWAP_STATS != SWAP_NSWAP");
+		}
+
+		*total = 0;
+		*used = 0;
+
+		for (i = 0; i < rnswap; i++) {
+			*total += sep->se_nblks >> 1;
+			*used += sep->se_inuse >> 1;
+		}
+
+		free(fsep);
+	}
+
+	const char *
+	swap_free(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return fmt_scaled((total - used) * 1024);
+	}
+
+	const char *
+	swap_perc(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return bprintf("%d", 100 * used / total);
+	}
+
+	const char *
+	swap_total(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return fmt_scaled(total * 1024);
+	}
+
+	const char *
+	swap_used(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return fmt_scaled(used * 1024);
+	}
 #endif