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.
This commit is contained in:
parent
5d6415608b
commit
a18439af11
@ -1,53 +1,72 @@
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
warn("fopen '%s':", path);
|
||||
return 0;
|
||||
/* get number of fields we want to extract */
|
||||
for (i = 0, left = 0; i < LEN(ent); i++) {
|
||||
if (ent[i].var) {
|
||||
left++;
|
||||
}
|
||||
}
|
||||
if (!(bytes_read = fread(buf, sizeof(char), bufsiz, fp))) {
|
||||
warn("fread '%s':", path);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
||||
if (!(fp = fopen("/proc/meminfo", "r"))) {
|
||||
warn("fopen '/proc/meminfo':");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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\n",
|
||||
ent[i].var);
|
||||
left--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
if (ferror(fp)) {
|
||||
warn("getline '/proc/meminfo':");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
buf[bytes_read] = '\0';
|
||||
|
||||
return bytes_read;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
swap_free(void)
|
||||
{
|
||||
long total, free;
|
||||
char *match;
|
||||
long free;
|
||||
|
||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
||||
if (get_swap_info(NULL, &free, NULL)) {
|
||||
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(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,17 +86,11 @@
|
||||
swap_total(void)
|
||||
{
|
||||
long total;
|
||||
char *match;
|
||||
|
||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
||||
if (get_swap_info(&total, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(match = strstr(buf, "SwapTotal"))) {
|
||||
return NULL;
|
||||
}
|
||||
sscanf(match, "SwapTotal: %ld kB\n", &total);
|
||||
|
||||
return fmt_human(total * 1024, 1024);
|
||||
}
|
||||
|
||||
@ -105,27 +98,11 @@
|
||||
swap_used(void)
|
||||
{
|
||||
long total, free, cached;
|
||||
char *match;
|
||||
|
||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
||||
if (get_swap_info(&total, &free, &cached)) {
|
||||
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((total - free - cached) * 1024, 1024);
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
|
Loading…
Reference in New Issue
Block a user