slstatus

status monitor
git clone git://git.suckless.org/slstatus
Log | Files | Refs | README | LICENSE

swap.c (4914B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <stdint.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include "../util.h"
      8 
      9 #if defined(__linux__)
     10 	static int
     11 	get_swap_info(long *s_total, long *s_free, long *s_cached)
     12 	{
     13 		FILE *fp;
     14 		struct {
     15 			const char *name;
     16 			const size_t len;
     17 			long *var;
     18 		} ent[] = {
     19 			{ "SwapTotal",  sizeof("SwapTotal") - 1,  s_total  },
     20 			{ "SwapFree",   sizeof("SwapFree") - 1,   s_free   },
     21 			{ "SwapCached", sizeof("SwapCached") - 1, s_cached },
     22 		};
     23 		size_t line_len = 0, i, left;
     24 		char *line = NULL;
     25 
     26 		/* get number of fields we want to extract */
     27 		for (i = 0, left = 0; i < LEN(ent); i++) {
     28 			if (ent[i].var) {
     29 				left++;
     30 			}
     31 		}
     32 
     33 		if (!(fp = fopen("/proc/meminfo", "r"))) {
     34 			warn("fopen '/proc/meminfo':");
     35 			return 1;
     36 		}
     37 
     38 		/* read file line by line and extract field information */
     39 		while (left > 0 && getline(&line, &line_len, fp) >= 0) {
     40 			for (i = 0; i < LEN(ent); i++) {
     41 				if (ent[i].var &&
     42 				    !strncmp(line, ent[i].name, ent[i].len)) {
     43 					sscanf(line + ent[i].len + 1,
     44 					       "%ld kB\n", ent[i].var);
     45 					left--;
     46 					break;
     47 				}
     48 			}
     49 		}
     50 		free(line);
     51 		if (ferror(fp)) {
     52 			warn("getline '/proc/meminfo':");
     53 			return 1;
     54 		}
     55 
     56 		fclose(fp);
     57 		return 0;
     58 	}
     59 
     60 	const char *
     61 	swap_free(void)
     62 	{
     63 		long free;
     64 
     65 		if (get_swap_info(NULL, &free, NULL)) {
     66 			return NULL;
     67 		}
     68 
     69 		return fmt_human(free * 1024, 1024);
     70 	}
     71 
     72 	const char *
     73 	swap_perc(void)
     74 	{
     75 		long total, free, cached;
     76 
     77 		if (get_swap_info(&total, &free, &cached) || total == 0) {
     78 			return NULL;
     79 		}
     80 
     81 		return bprintf("%d", 100 * (total - free - cached) / total);
     82 	}
     83 
     84 	const char *
     85 	swap_total(void)
     86 	{
     87 		long total;
     88 
     89 		if (get_swap_info(&total, NULL, NULL)) {
     90 			return NULL;
     91 		}
     92 
     93 		return fmt_human(total * 1024, 1024);
     94 	}
     95 
     96 	const char *
     97 	swap_used(void)
     98 	{
     99 		long total, free, cached;
    100 
    101 		if (get_swap_info(&total, &free, &cached)) {
    102 			return NULL;
    103 		}
    104 
    105 		return fmt_human((total - free - cached) * 1024, 1024);
    106 	}
    107 #elif defined(__OpenBSD__)
    108 	#include <stdlib.h>
    109 	#include <sys/swap.h>
    110 	#include <sys/types.h>
    111 	#include <unistd.h>
    112 
    113 	static int
    114 	getstats(int *total, int *used)
    115 	{
    116 		struct swapent *sep, *fsep;
    117 		int rnswap, nswap, i;
    118 
    119 		if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) < 1) {
    120 			warn("swaptctl 'SWAP_NSWAP':");
    121 			return 1;
    122 		}
    123 		if (!(fsep = sep = calloc(nswap, sizeof(*sep)))) {
    124 			warn("calloc 'nswap':");
    125 			return 1;
    126 		}
    127 		if ((rnswap = swapctl(SWAP_STATS, (void *)sep, nswap)) < 0) {
    128 			warn("swapctl 'SWAP_STATA':");
    129 			return 1;
    130 		}
    131 		if (nswap != rnswap) {
    132 			warn("getstats: SWAP_STATS != SWAP_NSWAP");
    133 			return 1;
    134 		}
    135 
    136 		*total = 0;
    137 		*used = 0;
    138 
    139 		for (i = 0; i < rnswap; i++) {
    140 			*total += sep->se_nblks >> 1;
    141 			*used += sep->se_inuse >> 1;
    142 		}
    143 
    144 		free(fsep);
    145 
    146 		return 0;
    147 	}
    148 
    149 	const char *
    150 	swap_free(void)
    151 	{
    152 		int total, used;
    153 
    154 		if (getstats(&total, &used)) {
    155 			return NULL;
    156 		}
    157 
    158 		return fmt_human((total - used) * 1024, 1024);
    159 	}
    160 
    161 	const char *
    162 	swap_perc(void)
    163 	{
    164 		int total, used;
    165 
    166 		if (getstats(&total, &used)) {
    167 			return NULL;
    168 		}
    169 
    170 		if (total == 0) {
    171 			return NULL;
    172 		}
    173 
    174 		return bprintf("%d", 100 * used / total);
    175 	}
    176 
    177 	const char *
    178 	swap_total(void)
    179 	{
    180 		int total, used;
    181 
    182 		if (getstats(&total, &used)) {
    183 			return NULL;
    184 		}
    185 
    186 		return fmt_human(total * 1024, 1024);
    187 	}
    188 
    189 	const char *
    190 	swap_used(void)
    191 	{
    192 		int total, used;
    193 
    194 		if (getstats(&total, &used)) {
    195 			return NULL;
    196 		}
    197 
    198 		return fmt_human(used * 1024, 1024);
    199 	}
    200 #elif defined(__FreeBSD__)
    201 	#include <stdlib.h>
    202 	#include <sys/types.h>
    203 	#include <fcntl.h>
    204 	#include <unistd.h>
    205 	#include <kvm.h>
    206 
    207 	static int getswapinfo(struct kvm_swap *swap_info, size_t size)
    208 	{
    209 		kvm_t *kd;
    210 
    211 		kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL);
    212 		if(kd == NULL) {
    213 			warn("kvm_openfiles '/dev/null':");
    214 			return 0;
    215 		}
    216 
    217 		if(kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) == -1) {
    218 			warn("kvm_getswapinfo:");
    219 			kvm_close(kd);
    220 			return 0;
    221 		}
    222 
    223 		kvm_close(kd);
    224 		return 1;
    225 	}
    226 
    227 	const char *
    228 	swap_free(void)
    229 	{
    230 		struct kvm_swap swap_info[1];
    231 		long used, total;
    232 
    233 		if(!getswapinfo(swap_info, 1))
    234 			return NULL;
    235 
    236 		total = swap_info[0].ksw_total;
    237 		used = swap_info[0].ksw_used;
    238 
    239 		return fmt_human((total - used) * getpagesize(), 1024);
    240 	}
    241 
    242 	const char *
    243 	swap_perc(void)
    244 	{
    245 		struct kvm_swap swap_info[1];
    246 		long used, total;
    247 
    248 		if(!getswapinfo(swap_info, 1))
    249 			return NULL;
    250 
    251 		total = swap_info[0].ksw_total;
    252 		used = swap_info[0].ksw_used;
    253 
    254 		return bprintf("%d", used * 100 / total);
    255 	}
    256 
    257 	const char *
    258 	swap_total(void)
    259 	{
    260 		struct kvm_swap swap_info[1];
    261 		long total;
    262 
    263 		if(!getswapinfo(swap_info, 1))
    264 			return NULL;
    265 
    266 		total = swap_info[0].ksw_total;
    267 
    268 		return fmt_human(total * getpagesize(), 1024);
    269 	}
    270 
    271 	const char *
    272 	swap_used(void)
    273 	{
    274 		struct kvm_swap swap_info[1];
    275 		long used;
    276 
    277 		if(!getswapinfo(swap_info, 1))
    278 			return NULL;
    279 
    280 		used = swap_info[0].ksw_used;
    281 
    282 		return fmt_human(used * getpagesize(), 1024);
    283 	}
    284 #endif