Refactor swap.c to use getline() instead of buf-filling - slstatus - status mon… | |
git clone git://git.suckless.org/slstatus | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit a18439af114b98ab026921b0cac61164f7a4eea8 | |
parent 5d6415608b37ebed185e00eae01eb743edb555e5 | |
Author: Laslo Hunhold <[email protected]> | |
Date: Mon, 28 May 2018 21:16:02 +0200 | |
Refactor swap.c to use getline() instead of buf-filling | |
This drops a lot of code and even though we are using a common function, | |
the specification of only the needed things keeps it very efficient and | |
even more efficient in memory and time than the previous solution. | |
Diffstat: | |
M components/swap.c | 123 +++++++++++++----------------… | |
1 file changed, 50 insertions(+), 73 deletions(-) | |
--- | |
diff --git a/components/swap.c b/components/swap.c | |
@@ -1,52 +1,71 @@ | |
/* See LICENSE file for copyright and license details. */ | |
#include <errno.h> | |
+#include <stdint.h> | |
#include <stdio.h> | |
+#include <stdlib.h> | |
#include <string.h> | |
#include "../util.h" | |
#if defined(__linux__) | |
- static size_t | |
- pread(const char *path, char *buf, size_t bufsiz) | |
+ static int | |
+ get_swap_info(long *s_total, long *s_free, long *s_cached) | |
{ | |
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; | |
+ struct { | |
+ const char *name; | |
+ const size_t len; | |
+ long *var; | |
+ } ent[] = { | |
+ { "SwapTotal", sizeof("SwapTotal") - 1, s_total }, | |
+ { "SwapFree", sizeof("SwapFree") - 1, s_free }, | |
+ { "SwapCached", sizeof("SwapCached") - 1, s_cached }, | |
+ }; | |
+ size_t line_len = 0, i, left; | |
+ char *line = NULL; | |
+ | |
+ /* get number of fields we want to extract */ | |
+ for (i = 0, left = 0; i < LEN(ent); i++) { | |
+ if (ent[i].var) { | |
+ left++; | |
+ } | |
+ } | |
+ | |
+ if (!(fp = fopen("/proc/meminfo", "r"))) { | |
+ warn("fopen '/proc/meminfo':"); | |
+ return 1; | |
} | |
- fclose(fp); | |
- buf[bytes_read] = '\0'; | |
+ /* read file line by line and extract field information */ | |
+ while (left > 0 && getline(&line, &line_len, fp) >= 0) { | |
+ for (i = 0; i < LEN(ent); i++) { | |
+ if (ent[i].var && | |
+ !strncmp(line, ent[i].name, ent[i].len)) { | |
+ sscanf(line + ent[i].len + 1, "%ld kB\… | |
+ ent[i].var); | |
+ left--; | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ free(line); | |
+ if (ferror(fp)) { | |
+ warn("getline '/proc/meminfo':"); | |
+ return 1; | |
+ } | |
- return bytes_read; | |
+ fclose(fp); | |
+ return 0; | |
} | |
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); | |
+ long free; | |
- if (!(match = strstr(buf, "SwapFree"))) { | |
+ if (get_swap_info(NULL, &free, NULL)) { | |
return NULL; | |
} | |
- sscanf(match, "SwapFree: %ld kB\n", &free); | |
return fmt_human(free * 1024, 1024); | |
} | |
@@ -55,28 +74,8 @@ | |
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); | |
- if (total == 0) { | |
+ if (get_swap_info(&total, &free, &cached) || total == 0) { | |
return NULL; | |
} | |
@@ -87,16 +86,10 @@ | |
swap_total(void) | |
{ | |
long total; | |
- char *match; | |
- | |
- if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) { | |
- return NULL; | |
- } | |
- if (!(match = strstr(buf, "SwapTotal"))) { | |
+ if (get_swap_info(&total, NULL, NULL)) { | |
return NULL; | |
} | |
- sscanf(match, "SwapTotal: %ld kB\n", &total); | |
return fmt_human(total * 1024, 1024); | |
} | |
@@ -105,26 +98,10 @@ | |
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"))) { | |
+ if (get_swap_info(&total, &free, &cached)) { | |
return NULL; | |
} | |
- sscanf(match, "SwapFree: %ld kB\n", &free); | |
return fmt_human((total - free - cached) * 1024, 1024); | |
} |