#include "stat.h" #include #include #include #include #include #include #include "display.h" #include "err.h" #include "log.h" #include "mem.h" stat* stat_init() { stat* s = xmalloc(sizeof(stat)); *s = (stat){ .sysver = "", .meminfo = {.mem_available = 0, .mem_total = 0}, .diskinfo = {.disk_available = 0, .disk_total = 0}, }; return s; } void stat_get_sysver(stat* s) { FILE* fp = fopen(PROC_PATH_VERSION, "r"); if (!fp) die("Cannot open %s", PROC_PATH_VERSION); if (fgets(s->sysver, sizeof(s->sysver), fp) != NULL) { s->sysver[strcspn(s->sysver, "\n")] = '\0'; } fclose(fp); } void stat_print_cpu_info(WINDOW* w, int y, int maxx, stat* s) { mvwprintw(w, y, maxx - STAT_INFO_WIDTH, " %.2f %%", s->cpu_occupy.cpu); } void stat_print_info(WINDOW* w, int y, int maxx, const char* label, unsigned long total, unsigned long ava) { unsigned long long t_bytes = total; unsigned long long a_bytes = ava; if (strcmp(label, "Mem") == 0 || strcmp(label, "Mem ") == 0) { t_bytes *= 1024; a_bytes *= 1024; } const char* units[] = {"B", "K", "M", "G", "T"}; int t_idx = 0; int a_idx = 0; double d_total = (double)t_bytes; double d_ava = (double)a_bytes; while (d_total >= 1024.0 && t_idx < 4) { d_total /= 1024.0; t_idx++; } while (d_ava >= 1024.0 && a_idx < 4) { d_ava /= 1024.0; a_idx++; } int startx = maxx - STAT_INFO_WIDTH; mvwprintw(w, y, startx, " %.2f%s/%.2f%s", d_ava, units[t_idx], d_total, units[t_idx]); /* wrefresh(w); */ } int stat_get_bar_ticks(int maxx, unsigned long long total, unsigned long long ava) { if (total == 0) return 0; if (ava >= total) return 0; unsigned long long used = total - ava; unsigned long long slots = (unsigned long long)(maxx); return (int)((slots * used) / total); } void stat_draw_cpu_bar(WINDOW* w, int maxx, int y, int x, stat* s) { int ava_to_draw_x = maxx - STAT_INFO_WIDTH - BAR_LABEL_WIDTH; int total_hashes = ava_to_draw_x * s->cpu_occupy.cpu; log_write(LOG_INFO, "stat_draw_cpu_bar: ava_to_draw = %d", ava_to_draw_x); log_write(LOG_INFO, "s->cpu_occupy.cpu = %f", s->cpu_occupy.cpu); log_write(LOG_INFO, "CPU Hashes = %d", total_hashes); char hashes[2048] = {0}; if (total_hashes > ava_to_draw_x) total_hashes = ava_to_draw_x; memset(hashes, '#', total_hashes); hashes[total_hashes] = '\0'; mvwprintw(w, y, x, "%-*s [", 4, "CPU"); wprintw_colorful(w, COLOR_PAIR_PROGRESS, "%.*s", total_hashes, hashes); int remaining_spaces = ava_to_draw_x - total_hashes; if (remaining_spaces > 0) { wprintw(w, "%*s", remaining_spaces, ""); } waddch(w, ']'); } void stat_draw_bar(WINDOW* w, const char* label, int maxx, int y, int x, unsigned long total, unsigned long ava) { int ava_to_draw_x = maxx - STAT_INFO_WIDTH - BAR_LABEL_WIDTH; int total_hashes = stat_get_bar_ticks(ava_to_draw_x, total, ava); char hashes[2048] = {0}; init_pair(COLOR_PAIR_PROGRESS, COLOR_GREEN, COLOR_BLACK); if (total_hashes > ava_to_draw_x) total_hashes = ava_to_draw_x; memset(hashes, '#', total_hashes); hashes[total_hashes] = '\0'; mvwprintw(w, y, x, "%-*s [", 4, label); wprintw_colorful(w, COLOR_PAIR_PROGRESS, "%.*s", total_hashes, hashes); int remaining_spaces = ava_to_draw_x - total_hashes; if (remaining_spaces > 0) { wprintw(w, "%*s", remaining_spaces, ""); } waddch(w, ']'); /* wrefresh(w); */ } void stat_get_meminfo(stat* s) { static char buf[128]; char key[32] = ""; unsigned long long val = 0; FILE* fp = fopen(PROC_PATH_MEMINFO, "r"); if (!fp) die("Cannot open %s", PROC_PATH_MEMINFO); while (fgets(buf, sizeof(buf), fp)) { if (sscanf(buf, "%31[^:]: %llu", key, &val) == 2) { if (strcmp(key, "MemTotal") == 0) { s->meminfo.mem_total = val; } else if (strcmp(key, "MemAvailable") == 0) { s->meminfo.mem_available = val; break; } } } fclose(fp); } void stat_get_diskinfo(stat* s) { struct statvfs vfs; if (statvfs("/", &vfs) != 0) { s->diskinfo.disk_total = 0; s->diskinfo.disk_available = 0; log_write(LOG_WARN, "Cannot get disk info"); } s->diskinfo.disk_total = (unsigned long long)vfs.f_blocks * vfs.f_frsize; s->diskinfo.disk_available = (unsigned long long)vfs.f_bavail * vfs.f_frsize; } void stat_get_cpuinfo(stat* s) { char buf[128]; FILE* fp = fopen(PROC_PATH_STAT, "r"); if (!fp) { log_write(LOG_WARN, "Cannot open %s", PROC_PATH_STAT); return; } fgets(buf, sizeof(buf), fp); sscanf(buf, "%s %llu %llu %llu %llu", s->cpu_occupy.name, &s->cpu_occupy.user, &s->cpu_occupy.nice, &s->cpu_occupy.system, &s->cpu_occupy.idle); fclose(fp); } void stat_calc_cpuocc(stat* s) { cpu_occupy* co = xmalloc(sizeof(cpu_occupy)); stat_get_cpuinfo(s); co->idle = s->cpu_occupy.idle; co->nice = s->cpu_occupy.nice; co->system = s->cpu_occupy.system; co->user = s->cpu_occupy.user; usleep(200000); stat_get_cpuinfo(s); unsigned long long t1 = co->user + co->nice + co->system + co->idle; unsigned long long t2 = s->cpu_occupy.user + s->cpu_occupy.nice + s->cpu_occupy.system + s->cpu_occupy.idle; unsigned long long user = s->cpu_occupy.user - co->user; unsigned long long system = s->cpu_occupy.system - co->system; s->cpu_occupy.cpu = (user + system) * 1.0 / (t2 - t1); free(co); }