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 changed files with 49 additions and 72 deletions
|
@ -1,53 +1,72 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
static size_t
|
static int
|
||||||
pread(const char *path, char *buf, size_t bufsiz)
|
get_swap_info(long *s_total, long *s_free, long *s_cached)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
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"))) {
|
/* get number of fields we want to extract */
|
||||||
warn("fopen '%s':", path);
|
for (i = 0, left = 0; i < LEN(ent); i++) {
|
||||||
return 0;
|
if (ent[i].var) {
|
||||||
|
left++;
|
||||||
}
|
}
|
||||||
if (!(bytes_read = fread(buf, sizeof(char), bufsiz, fp))) {
|
}
|
||||||
warn("fread '%s':", path);
|
|
||||||
|
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);
|
fclose(fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
buf[bytes_read] = '\0';
|
|
||||||
|
|
||||||
return bytes_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
swap_free(void)
|
swap_free(void)
|
||||||
{
|
{
|
||||||
long total, free;
|
long free;
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
if (get_swap_info(NULL, &free, NULL)) {
|
||||||
return 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);
|
return fmt_human(free * 1024, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,28 +74,8 @@
|
||||||
swap_perc(void)
|
swap_perc(void)
|
||||||
{
|
{
|
||||||
long total, free, cached;
|
long total, free, cached;
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
if (get_swap_info(&total, &free, &cached) || total == 0) {
|
||||||
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) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,17 +86,11 @@
|
||||||
swap_total(void)
|
swap_total(void)
|
||||||
{
|
{
|
||||||
long total;
|
long total;
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
if (get_swap_info(&total, NULL, NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(match = strstr(buf, "SwapTotal"))) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
sscanf(match, "SwapTotal: %ld kB\n", &total);
|
|
||||||
|
|
||||||
return fmt_human(total * 1024, 1024);
|
return fmt_human(total * 1024, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,27 +98,11 @@
|
||||||
swap_used(void)
|
swap_used(void)
|
||||||
{
|
{
|
||||||
long total, free, cached;
|
long total, free, cached;
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
|
if (get_swap_info(&total, &free, &cached)) {
|
||||||
return NULL;
|
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);
|
return fmt_human((total - free - cached) * 1024, 1024);
|
||||||
}
|
}
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
|
|
Loading…
Reference in a new issue