-
Notifications
You must be signed in to change notification settings - Fork 1
/
ufbtop.c
316 lines (288 loc) · 8.56 KB
/
ufbtop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>
#include <time.h>
#include <linux/fb.h>
#include "font.h"
#include "bitmap.h"
#include "fbdraw.h"
#define FBDEV_DEFAULT "/dev/fb0"
char *progname = NULL;
unsigned char default_font_w = 8;
unsigned char default_font_h = 8;
int draw_string(unsigned int x, unsigned int y,
uint32_t colorfg, uint32_t colorbg,
char *s, struct fbdraw_info *fb)
{
struct bitmap bm;
memset(&bm, 0, sizeof(bm));
bm.w = default_font_w;
bm.h = default_font_h;
while (*s) {
bm.data = vga_font_8x8[(uint8_t)*s];
fbdraw_bitmap(x, y, &bm, &colorfg, &colorbg, fb);
x += bm.w;
s++;
}
return 0;
}
int draw_progress_bar(unsigned int x, unsigned int y,
unsigned int w, unsigned int h,
uint32_t colorfg, uint32_t colorbg,
unsigned short progress, struct fbdraw_info *fb)
{
fbdraw_rect(x, y, w, h, colorfg, fb);
float fw = w;
fw -= (float)x;
if (fw > 0) {
fw /= (float)100;
fw *= (float)progress;
}
if (progress >= 100)
fw = w;
unsigned int pw = (unsigned int)fw;
fbdraw_rect_solid(x + 1, y + 1, pw - 2, h - 2, colorfg, fb);
fbdraw_rect_solid(x + pw + 1, y + 1, w - pw - 2, h - 2,
colorbg, fb);
return 0;
}
void get_version(char *s, unsigned long size) {
static int fd = -1;
if (fd < 0)
fd = open("/proc/version", O_RDONLY);
char buf[200];
pread(fd, buf, 200, 0);
buf[199] = '\0';
snprintf(s,size,"VER: %s",buf);
}
void get_hostname(char *s, unsigned long size)
{
static int fd = -1;
if (fd < 0)
fd = open("/proc/sys/kernel/hostname", O_RDONLY);
char hostname[64];
memset(hostname, ' ', 64);
if (pread(fd, hostname, 64, 0) < 0)
hostname[0] = '\0';
hostname[63] = '\0';
snprintf(s, size, "HOST: %s", hostname);
}
void get_uptime(char *s, unsigned long size)
{
struct sysinfo info;
sysinfo(&info);
unsigned long days, hours, mins;
days = info.uptime / (24 * 60 * 60);
mins = info.uptime / 60;
hours = (mins / 60) % 24;
mins %= 60;
snprintf(s, size, "UPTIME: %2lu DAYS %2lu HOURS %2lu MINS",
days, hours, mins);
}
unsigned short get_cpu_usage(void)
{
static int fd = -1;
if (fd == -1)
fd = open("/proc/stat", O_RDONLY);
char buf[128];
memset(buf, 0, 128);
pread(fd, buf, 128, 0);
strtok(buf, " ");
unsigned long user_now = atol(strtok(NULL, " "));
unsigned long nice_now = atol(strtok(NULL, " "));
unsigned long system_now = atol(strtok(NULL, " "));
unsigned long idle_now = atol(strtok(NULL, " "));
unsigned long iowait_now = atol(strtok(NULL, " "));
unsigned long irq_now = atoll(strtok(NULL, " "));
unsigned long softirq_now = atol(strtok(NULL, " "));
unsigned long steal_now = atol(strtok(NULL, " "));
unsigned long guest_now = atol(strtok(NULL, " "));
unsigned long guest_nice_now = atol(strtok(NULL, " "));
unsigned long total_now = user_now + nice_now + system_now +
idle_now + iowait_now + irq_now + softirq_now +
steal_now + guest_now + guest_nice_now;
unsigned long used_now = user_now + nice_now + system_now +
irq_now + softirq_now + guest_now + guest_nice_now;
static unsigned long used_old = 0;
static unsigned long total_old = 0;
if (used_old == 0 && total_old == 0) {
used_old = used_now;
total_old = total_now;
return 0;
}
float used = (float)(used_now - used_old);
float total = (float)(total_now - total_old);
used_old = used_now;
total_old = total_now;
return (unsigned short)(used / total * 100.0);
}
unsigned short get_mem_usage(void)
{
static FILE *fp = NULL;
if (fp == NULL)
fp = fopen("/proc/meminfo", "r");
rewind(fp);
char line[64];
unsigned long available, total, used;
while (fgets(line, 64, fp) != NULL) {
sscanf(line, "MemAvailable: %lu %*s\n", &available);
sscanf(line, "MemTotal: %lu %*s\n", &total);
}
used = total - available;
float fu, ft;
fu = (float)used;
ft = (float)total;
return (unsigned short)(fu / ft * 100);
}
unsigned short get_swap_usage(void)
{
static FILE *fp = NULL;
if (fp == NULL)
fp = fopen("/proc/meminfo", "r");
rewind(fp);
char line[64];
unsigned long total, free, used;
while (fgets(line, 64, fp) != NULL) {
sscanf(line, "SwapTotal: %lu %*s\n", &total);
sscanf(line, "SwapFree: %lu %*s\n", &free);
}
used = total - free;
if (total == 0 || used == 0)
return 0;
float fu, ft;
ft = (float)total;
fu = (float)used;
return (unsigned short)(fu / ft * 100);
}
int main(int argc, char *argv[])
{
char *fbdev_pathname = getenv("FRAMEBUFFER");
if (fbdev_pathname == NULL)
fbdev_pathname = FBDEV_DEFAULT;
int fbdev_fd = open(fbdev_pathname, O_RDWR);
if (fbdev_fd < 0) {
fprintf(stderr, "can't open framebuffer %s,REASON: %s\n",
fbdev_pathname, strerror(errno));
exit(EXIT_FAILURE);
}
struct fbdraw_info fb;
memset(&fb, 0, sizeof(fb));
struct fb_var_screeninfo fb_vinfo;
if (ioctl(fbdev_fd, FBIOGET_VSCREENINFO, &fb_vinfo) < 0) {
fprintf(stderr,
"can't get framebuffer %s var_screeninfo,REASON: %s\n",
fbdev_pathname, strerror(errno));
exit(EXIT_FAILURE);
}
struct fb_fix_screeninfo fb_finfo;
if (ioctl(fbdev_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) {
fprintf(stderr,
"can't get framebuffer %s fix_screeninfo,REASON: %s\n",
fbdev_pathname, strerror(errno));
exit(EXIT_FAILURE);
}
fb.xres = fb_vinfo.xres;
fb.yres = fb_vinfo.yres;
fb.bits_per_pixel = fb_vinfo.bits_per_pixel;
fb.size = fb_finfo.smem_len;
fb.line_length = fb_finfo.line_length;
fb.mem = mmap(NULL, fb.size, PROT_READ | PROT_WRITE,
MAP_SHARED, fbdev_fd, 0);
printf("xres = %u\n", fb.xres);
printf("yres = %u\n", fb.yres);
printf("bits_per_pixel = %u\n", fb.bits_per_pixel);
printf("size = %lu\n", fb.size);
printf("line_length = %u\n", fb.line_length);
if (fb.mem == MAP_FAILED) {
fprintf(stderr,
"can't mmap framebuffer %s,REASON: %s\n",
fbdev_pathname, strerror(errno));
exit(EXIT_FAILURE);
}
useconds_t delay = 100000;
if (argc > 1)
delay = atol(argv[1]);
uint32_t bg = 0xFFFFFFFF;
uint32_t fg = 0x0;
char version_str[256];
unsigned int version_str_x = 10;
unsigned int version_str_y = 20;
char hostname_str[128];
unsigned int hostname_str_x = 10;
unsigned int hostname_str_y = 30;
char uptime_str[128];
unsigned int uptime_str_x = 10;
unsigned int uptime_str_y = 40;
char *cpu_str = "CPU: ";
unsigned int cpu_str_x = 10;
unsigned int cpu_str_y = 50;
unsigned int cpu_progress = 0;
unsigned int cpu_progress_x = cpu_str_x + strlen(cpu_str) *
default_font_w;
unsigned int cpu_progress_y = cpu_str_y;
char *mem_str = "MEM: ";
unsigned int mem_str_x = 10;
unsigned int mem_str_y = 60;
unsigned int mem_progress = 0;
unsigned int mem_progress_x = mem_str_x + strlen(mem_str) *
default_font_w;
unsigned int mem_progress_y = mem_str_y;
char *swap_str = "SWAP: ";
unsigned int swap_str_x = 10;
unsigned int swap_str_y = 70;
unsigned int swap_progress = 0;
unsigned int swap_progress_x = swap_str_x + strlen(swap_str) *
default_font_w;
unsigned int swap_progress_y = swap_str_y;
// fill bg
fbdraw_rect_solid(0, 0, fb.xres, fb.yres, bg, &fb);
while (1) {
// get version
get_version(version_str, 256);
draw_string(version_str_x, version_str_y, fg, bg,
version_str, &fb);
// get hostname
get_hostname(hostname_str, 128);
// draw hostname
draw_string(hostname_str_x, hostname_str_y, fg, bg,
hostname_str, &fb);
// get uptime
get_uptime(uptime_str, 128);
// draw uptime
draw_string(uptime_str_x, uptime_str_y, fg, bg,
uptime_str, &fb);
// get cpu usage
cpu_progress = get_cpu_usage();
// draw cpu usage
draw_string(cpu_str_x, cpu_str_y, fg, bg, cpu_str, &fb);
draw_progress_bar(cpu_progress_x, cpu_progress_y,
fb.xres - cpu_progress_x - 10, 8,
fg, bg, cpu_progress, &fb);
// get mem usage
mem_progress = get_mem_usage();
// draw mem usage
draw_string(mem_str_x, mem_str_y, fg, bg, mem_str, &fb);
draw_progress_bar(mem_progress_x, mem_progress_y,
fb.xres - mem_progress_x - 10, 8,
fg, bg, mem_progress, &fb);
// get swap usage
swap_progress = get_swap_usage();
// draw swap usage
draw_string(swap_str_x, swap_str_y, fg, bg, swap_str, &fb);
draw_progress_bar(swap_progress_x, swap_progress_y,
fb.xres - swap_progress_x - 10, 8,
fg, bg, swap_progress, &fb);
// sleep some time
if (delay > 0)
usleep(delay);
}
exit(EXIT_SUCCESS);
}