#include #include #include #include #include "scheme.h" #include "../any_log.h" static const char *ram_formats[] = { "%{total}", "%{free}", "%{used}", "%{free-percentage}", "%{used-percentage}", NULL, }; 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); char ram_values[6][32] = { 0 }; snprintf(ram_values[0], 32, "%ld", total); snprintf(ram_values[1], 32, "%ld", available); snprintf(ram_values[2], 32, "%ld", total - available); snprintf(ram_values[3], 32, "%ld", 100 * available / total); snprintf(ram_values[4], 32, "%ld", 100 * (total - available) / total); block->text.text = strformat(block->state, ram_formats, (const char **)ram_values); assert(block->text.text != NULL); } static void block_ram_finalize(block_t *block) { free(block->state); } static bool block_ram_validate(block_t *block, const block_scheme_t *scheme) { if (block->text.text == NULL) { log_error("Block '%s' requires key '%s'", block->label, "text"); return false; } block->state = block->text.text; block->text.text = NULL; size_t count = strcount(block->state, ram_formats); if (count == 0) { log_warn("Block '%s' does not use any ram variable", block->label); block->update_cb = NULL; log_debug("Disabled updates for block '%s'", block->label); return true; } return true; } const block_scheme_t block_ram_scheme = { .name = "ram", .block = { .type = BLOCK_TEXT, .update_interval = { .tv_sec = 1, .tv_nsec = 0, }, .update_cb = block_ram_update, .finalize_cb = block_ram_finalize, }, .size = sizeof(char *), .entries = NULL, .validate = block_ram_validate, };