#include #include #include #include #include "../block.h" #include "../any_log.h" typedef struct { block_text_t block; char *format; } block_ram_t; static const struct timespec block_ram_interval = { .tv_sec = 1, .tv_nsec = 0, }; static void block_ram_update(block_t *block) { FILE *meminfo = fopen("/proc/meminfo", "rb"); assert(meminfo != NULL); uintmax_t total, unused, available, buffers, cached; assert(5 == fscanf(meminfo, "MemTotal: %ju kB\n" "MemFree: %ju kB\n" "MemAvailable: %ju kB\n" "Buffers: %ju kB\n" "Cached: %ju kB\n", &total, &unused, &available, &buffers, &cached)); fclose(meminfo); static const char *ram_formats[] = { "total", "free", "used", "free-percentage", "used-percentage", NULL, }; char buffer[32][5] = { 0 }; snprintf(buffer[0], 32, "%ld", total); snprintf(buffer[1], 32, "%ld", available); snprintf(buffer[2], 32, "%ld", total - available); snprintf(buffer[3], 32, "%ld", 100 * available / total); snprintf(buffer[4], 32, "%ld", 100 * (total - available) / total); const char *ram_values[] = { buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], NULL, }; block_ram_t *ram = (block_ram_t *)block; free(ram->block.text); ram->block.text = strformat(ram->format, '%', ram_formats, ram_values); assert(ram->block.text != NULL); } static block_t *block_ram_alloc(const block_scheme_t *scheme) { block_t *block = calloc(1, sizeof(block_ram_t)); block->type = BLOCK_TEXT; block->update_interval = block_ram_interval; block->update_fn = block_ram_update; return block; } static void block_ram_clean(block_t *block) { block_ram_t *ram = (block_ram_t *)block; free(ram->format); free(ram->block.text); } static bool block_ram_validate(block_t *block, const block_scheme_t *scheme) { block_ram_t *ram = (block_ram_t *)block; if (ram->block.text == NULL) { log_error("Block '%s' requires key '%s'", block->label, "text"); return false; } if (strstr(ram->block.text, "%{") == NULL) { log_warn("Block '%s' does not use any ram variable", block->label); block->update_fn = NULL; log_debug("Disabled updates for block '%s'", block->label); return true; } ram->format = ram->block.text; ram->block.text = NULL; return true; } const block_scheme_t block_ram_scheme = { .name = "ram", .entries = NULL, .alloc_fn = block_ram_alloc, .clean_fn = block_ram_clean, .validate_fn = block_ram_validate, .resolve_fn = NULL, };