Xinqi Bao's Git

465ffd4fc1f412f117a68517cc28bed5b655faf4
[slstatus.git] / components / swap.c
1 /* See LICENSE file for copyright and license details. */
2 #include <errno.h>
3 #include <stdio.h>
4 #include <string.h>
5
6 #include "../util.h"
7
8 #if defined(__linux__)
9 static size_t
10 pread(const char *path, char *buf, size_t bufsiz)
11 {
12 FILE *fp;
13 size_t bytes_read;
14
15 if (!(fp = fopen(path, "r"))) {
16 warn("fopen '%s':", path);
17 return 0;
18 }
19 if (!(bytes_read = fread(buf, sizeof(char), bufsiz, fp))) {
20 warn("fread '%s':", path);
21 fclose(fp);
22 return 0;
23 }
24 fclose(fp);
25
26 buf[bytes_read] = '\0';
27
28 return bytes_read;
29 }
30
31 const char *
32 swap_free(void)
33 {
34 long total, free;
35 char *match;
36
37 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
38 return NULL;
39 }
40
41 if (!(match = strstr(buf, "SwapTotal"))) {
42 return NULL;
43 }
44 sscanf(match, "SwapTotal: %ld kB\n", &total);
45
46 if (!(match = strstr(buf, "SwapFree"))) {
47 return NULL;
48 }
49 sscanf(match, "SwapFree: %ld kB\n", &free);
50
51 return fmt_human_2(free * 1024, "B");
52 }
53
54 const char *
55 swap_perc(void)
56 {
57 long total, free, cached;
58 char *match;
59
60 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
61 return NULL;
62 }
63
64 if (!(match = strstr(buf, "SwapTotal"))) {
65 return NULL;
66 }
67 sscanf(match, "SwapTotal: %ld kB\n", &total);
68
69 if (!(match = strstr(buf, "SwapCached"))) {
70 return NULL;
71 }
72 sscanf(match, "SwapCached: %ld kB\n", &cached);
73
74 if (!(match = strstr(buf, "SwapFree"))) {
75 return NULL;
76 }
77 sscanf(match, "SwapFree: %ld kB\n", &free);
78
79 if (total == 0) {
80 return NULL;
81 }
82
83 return bprintf("%d%%", 100 * (total - free - cached) / total);
84 }
85
86 const char *
87 swap_total(void)
88 {
89 long total;
90 char *match;
91
92 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
93 return NULL;
94 }
95
96 if (!(match = strstr(buf, "SwapTotal"))) {
97 return NULL;
98 }
99 sscanf(match, "SwapTotal: %ld kB\n", &total);
100
101 return fmt_human_2(total * 1024, "B");
102 }
103
104 const char *
105 swap_used(void)
106 {
107 long total, free, cached;
108 char *match;
109
110 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
111 return NULL;
112 }
113
114 if (!(match = strstr(buf, "SwapTotal"))) {
115 return NULL;
116 }
117 sscanf(match, "SwapTotal: %ld kB\n", &total);
118
119 if (!(match = strstr(buf, "SwapCached"))) {
120 return NULL;
121 }
122 sscanf(match, "SwapCached: %ld kB\n", &cached);
123
124 if (!(match = strstr(buf, "SwapFree"))) {
125 return NULL;
126 }
127 sscanf(match, "SwapFree: %ld kB\n", &free);
128
129 return fmt_human_2((total - free - cached) * 1024, "B");
130 }
131 #elif defined(__OpenBSD__)
132 #include <stdlib.h>
133 #include <sys/param.h> /* dbtob */
134 #include <sys/swap.h>
135 #include <sys/types.h>
136 #include <unistd.h>
137
138 static void
139 getstats(int *total, int *used)
140 {
141 struct swapent *sep, *fsep;
142 int rnswap, nswap, i;
143
144 nswap = swapctl(SWAP_NSWAP, 0, 0);
145 if (nswap < 1) {
146 warn("swaptctl 'SWAP_NSWAP':");
147 }
148
149 fsep = sep = calloc(nswap, sizeof(*sep));
150 if (!sep) {
151 warn("calloc 'nswap':");
152 }
153
154 rnswap = swapctl(SWAP_STATS, (void *)sep, nswap);
155 if (rnswap < 0) {
156 warn("swapctl 'SWAP_STATA':");
157 }
158
159 if (nswap != rnswap) {
160 warn("getstats: SWAP_STATS != SWAP_NSWAP");
161 }
162
163 *total = 0;
164 *used = 0;
165
166 for (i = 0; i < rnswap; i++) {
167 *total += sep->se_nblks >> 1;
168 *used += sep->se_inuse >> 1;
169 }
170
171 free(fsep);
172 }
173
174 const char *
175 swap_free(void)
176 {
177 int total, used;
178
179 getstats(&total, &used);
180
181 return fmt_human_2((total - used) * 1024, "B");
182 }
183
184 const char *
185 swap_perc(void)
186 {
187 int total, used;
188
189 getstats(&total, &used);
190
191 return bprintf("%d%%", 100 * used / total);
192 }
193
194 const char *
195 swap_total(void)
196 {
197 int total, used;
198
199 getstats(&total, &used);
200
201 return fmt_human_2(total * 1024, "B");
202 }
203
204 const char *
205 swap_used(void)
206 {
207 int total, used;
208
209 getstats(&total, &used);
210
211 return fmt_human_2(used * 1024, "B");
212 }
213 #endif