Xinqi Bao's Git

swap_*: Port to OpenBSD
[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 fprintf(stderr, "fopen '%s': %s\n", path,
17 strerror(errno));
18 return 0;
19 }
20 if ((bytes_read = fread(buf, sizeof(char), bufsiz, fp)) == 0) {
21 fprintf(stderr, "fread '%s': %s\n", path,
22 strerror(errno));
23 fclose(fp);
24 return 0;
25 }
26 fclose(fp);
27
28 buf[bytes_read] = '\0';
29
30 return bytes_read;
31 }
32
33 const char *
34 swap_free(void)
35 {
36 long total, free;
37 char *match;
38
39 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
40 return NULL;
41 }
42
43 if ((match = strstr(buf, "SwapTotal")) == NULL)
44 return NULL;
45 sscanf(match, "SwapTotal: %ld kB\n", &total);
46
47 if ((match = strstr(buf, "SwapFree")) == NULL)
48 return NULL;
49 sscanf(match, "SwapFree: %ld kB\n", &free);
50
51 return bprintf("%f", (float)free / 1024 / 1024);
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")) == NULL)
65 return NULL;
66 sscanf(match, "SwapTotal: %ld kB\n", &total);
67
68 if ((match = strstr(buf, "SwapCached")) == NULL)
69 return NULL;
70 sscanf(match, "SwapCached: %ld kB\n", &cached);
71
72 if ((match = strstr(buf, "SwapFree")) == NULL)
73 return NULL;
74 sscanf(match, "SwapFree: %ld kB\n", &free);
75
76 return bprintf("%d", 100 * (total - free - cached) / total);
77 }
78
79 const char *
80 swap_total(void)
81 {
82 long total;
83 char *match;
84
85 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
86 return NULL;
87 }
88
89 if ((match = strstr(buf, "SwapTotal")) == NULL)
90 return NULL;
91 sscanf(match, "SwapTotal: %ld kB\n", &total);
92
93 return bprintf("%f", (float)total / 1024 / 1024);
94 }
95
96 const char *
97 swap_used(void)
98 {
99 long total, free, cached;
100 char *match;
101
102 if (!pread("/proc/meminfo", buf, sizeof(buf) - 1)) {
103 return NULL;
104 }
105
106 if ((match = strstr(buf, "SwapTotal")) == NULL)
107 return NULL;
108 sscanf(match, "SwapTotal: %ld kB\n", &total);
109
110 if ((match = strstr(buf, "SwapCached")) == NULL)
111 return NULL;
112 sscanf(match, "SwapCached: %ld kB\n", &cached);
113
114 if ((match = strstr(buf, "SwapFree")) == NULL)
115 return NULL;
116 sscanf(match, "SwapFree: %ld kB\n", &free);
117
118 return bprintf("%f", (float)(total - free - cached) / 1024 / 1024);
119 }
120 #elif defined(__OpenBSD__)
121 #include <stdlib.h>
122 #include <sys/param.h> /* dbtob */
123 #include <sys/swap.h>
124 #include <sys/types.h>
125 #include <unistd.h>
126
127 #define dbtoqb(b) dbtob((int64_t)(b))
128
129 static void
130 getstats(int *total, int *used)
131 {
132 struct swapent *sep, *fsep;
133 int rnswap, nswap, i;
134
135 nswap = swapctl(SWAP_NSWAP, 0, 0);
136 if (nswap < 1)
137 fprintf(stderr, "swaptctl 'SWAP_NSWAP': %s\n", strerror(errno));
138
139 fsep = sep = calloc(nswap, sizeof(*sep));
140 if (sep == NULL)
141 fprintf(stderr, "calloc 'nswap': %s\n", strerror(errno));
142
143 rnswap = swapctl(SWAP_STATS, (void *)sep, nswap);
144 if (rnswap < 0)
145 fprintf(stderr, "swapctl 'SWAP_STATA': %s\n", strerror(errno));
146
147 if (nswap != rnswap)
148 fprintf(stderr, "SWAP_STATS != SWAP_NSWAP\n");
149
150 *total = 0;
151 *used = 0;
152
153 for (i = 0; i < rnswap; i++) {
154 *total += dbtoqb(sep->se_nblks);
155 *used += dbtoqb(sep->se_inuse);
156 }
157
158 free(fsep);
159 }
160
161 const char *
162 swap_free(void)
163 {
164 int total, used;
165
166 getstats(&total, &used);
167
168 return bprintf("%f", (float)(total - used) / 1024 / 1024 / 1024);
169 }
170
171 const char *
172 swap_perc(void)
173 {
174 int total, used;
175
176 getstats(&total, &used);
177
178 return bprintf("%d", 100 * used / total);
179 }
180
181 const char *
182 swap_total(void)
183 {
184 int total, used;
185
186 getstats(&total, &used);
187
188 return bprintf("%f", (float)total / 1024 / 1024 / 1024);
189 }
190
191 const char *
192 swap_used(void)
193 {
194 int total, used;
195
196 getstats(&total, &used);
197
198 return bprintf("%f", (float)used / 1024 / 1024 / 1024);
199 }
200 #endif