Refactor swap.c to use getline() instead of buf-filling - slstatus - status monitor
 (HTM) git clone git://git.suckless.org/slstatus
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a18439af114b98ab026921b0cac61164f7a4eea8
 (DIR) parent 5d6415608b37ebed185e00eae01eb743edb555e5
 (HTM) Author: Laslo Hunhold <dev@frign.de>
       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(-)
       ---
 (DIR) 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\n",
       +                                               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);
                }