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