X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/7246dc4381c6c95454672a5c1aff65a02d6d3747..951ea4e304cf23f8464a4b6896cfcf4035920249:/components/swap.c

diff --git a/components/swap.c b/components/swap.c
index e4eec64..c005691 100644
--- a/components/swap.c
+++ b/components/swap.c
@@ -1,136 +1,209 @@
 /* See LICENSE file for copyright and license details. */
-#include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "../util.h"
 
-const char *
-swap_free(void)
-{
-	long total, free;
-	FILE *fp;
-	size_t bytes_read;
-	char *match;
-
-	fp = fopen("/proc/meminfo", "r");
-	if (fp == NULL) {
-		warn("Failed to open file /proc/meminfo");
-		return NULL;
+#if defined(__linux__)
+	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';
+
+		return bytes_read;
 	}
 
-	if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) {
-		warn("swap_free: read error");
-		fclose(fp);
-		return NULL;
+	const char *
+	swap_free(void)
+	{
+		long total, free;
+		char *match;
+
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
+			return NULL;
+		}
+
+		if (!(match = strstr(buf, "SwapTotal"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+		if (!(match = strstr(buf, "SwapFree"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapFree: %ld kB\n", &free);
+
+		return fmt_human_2(free * 1024, "B");
 	}
-	fclose(fp);
-
-	if ((match = strstr(buf, "SwapTotal")) == NULL)
-		return NULL;
-	sscanf(match, "SwapTotal: %ld kB\n", &total);
-
-	if ((match = strstr(buf, "SwapFree")) == NULL)
-		return NULL;
-	sscanf(match, "SwapFree: %ld kB\n", &free);
-
-	return bprintf("%f", (float)free / 1024 / 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) {
-		warn("Failed to open file /proc/meminfo");
-		return NULL;
+
+	const char *
+	swap_perc(void)
+	{
+		long total, free, cached;
+		char *match;
+
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
+			return NULL;
+		}
+
+		if (!(match = strstr(buf, "SwapTotal"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+		if (!(match = strstr(buf, "SwapCached"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapCached: %ld kB\n", &cached);
+
+		if (!(match = strstr(buf, "SwapFree"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapFree: %ld kB\n", &free);
+
+		return bprintf("%d%%", 100 * (total - free - cached) / total);
 	}
 
-	if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) {
-		warn("swap_perc: read error");
-		fclose(fp);
-		return NULL;
+	const char *
+	swap_total(void)
+	{
+		long total;
+		char *match;
+
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
+			return NULL;
+		}
+
+		if (!(match = strstr(buf, "SwapTotal"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+		return fmt_human_2(total * 1024, "B");
 	}
-	fclose(fp);
-
-	if ((match = strstr(buf, "SwapTotal")) == NULL)
-		return NULL;
-	sscanf(match, "SwapTotal: %ld kB\n", &total);
-
-	if ((match = strstr(buf, "SwapCached")) == NULL)
-		return NULL;
-	sscanf(match, "SwapCached: %ld kB\n", &cached);
-
-	if ((match = strstr(buf, "SwapFree")) == NULL)
-		return NULL;
-	sscanf(match, "SwapFree: %ld kB\n", &free);
-
-	return bprintf("%d", 100 * (total - free - cached) / total);
-}
-
-const char *
-swap_total(void)
-{
-	long total;
-	FILE *fp;
-	size_t bytes_read;
-	char *match;
-
-	fp = fopen("/proc/meminfo", "r");
-	if (fp == NULL) {
-		warn("Failed to open file /proc/meminfo");
-		return NULL;
+
+	const char *
+	swap_used(void)
+	{
+		long total, free, cached;
+		char *match;
+
+		if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
+			return NULL;
+		}
+
+		if (!(match = strstr(buf, "SwapTotal"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+		if (!(match = strstr(buf, "SwapCached"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapCached: %ld kB\n", &cached);
+
+		if (!(match = strstr(buf, "SwapFree"))) {
+			return NULL;
+		}
+		sscanf(match, "SwapFree: %ld kB\n", &free);
+
+		return fmt_human_2((total - free - cached) * 1024, "B");
 	}
-	if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) {
-		warn("swap_total: read error");
-		fclose(fp);
-		return NULL;
+#elif defined(__OpenBSD__)
+	#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);
 	}
-	fclose(fp);
-
-	if ((match = strstr(buf, "SwapTotal")) == NULL)
-		return NULL;
-	sscanf(match, "SwapTotal: %ld kB\n", &total);
-
-	return bprintf("%f", (float)total / 1024 / 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) {
-		warn("Failed to open file /proc/meminfo");
-		return NULL;
+
+	const char *
+	swap_free(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return fmt_human_2((total - used) * 1024, "B");
 	}
-	if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) {
-		warn("swap_used: read error");
-		fclose(fp);
-		return NULL;
+
+	const char *
+	swap_perc(void)
+	{
+		int total, used;
+
+		getstats(&total, &used);
+
+		return bprintf("%d%%", 100 * used / total);
 	}
-	fclose(fp);
 
-	if ((match = strstr(buf, "SwapTotal")) == NULL)
-		return NULL;
-	sscanf(match, "SwapTotal: %ld kB\n", &total);
+	const char *
+	swap_total(void)
+	{
+		int total, used;
 
-	if ((match = strstr(buf, "SwapCached")) == NULL)
-		return NULL;
-	sscanf(match, "SwapCached: %ld kB\n", &cached);
+		getstats(&total, &used);
 
-	if ((match = strstr(buf, "SwapFree")) == NULL)
-		return NULL;
-	sscanf(match, "SwapFree: %ld kB\n", &free);
+		return fmt_human_2(total * 1024, "B");
+	}
+
+	const char *
+	swap_used(void)
+	{
+		int total, used;
 
-	return bprintf("%f", (float)(total - free - cached) / 1024 / 1024);
-}
+		getstats(&total, &used);
+
+		return fmt_human_2(used * 1024, "B");
+	}
+#endif