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