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:
		
				
					committed by
					
						
						Aaron Marcher
					
				
			
			
				
	
			
			
			
						parent
						
							5d6415608b
						
					
				
				
					commit
					a18439af11
				
			@@ -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__)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user