X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fprint_mem.c;h=840f997eea99659fc53c9f1509cf4847877980d9;hb=0f4fbf70afc607e2dcb14ef8292911042490d1dc;hp=c2f48f4ee60ba63f3bbb6b5af3aaf394e9249663;hpb=c55754542ec8f17246415fa19baf06ef7dc6ab87;p=i3%2Fi3status diff --git a/src/print_mem.c b/src/print_mem.c index c2f48f4..840f997 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -1,4 +1,5 @@ // vim:ts=4:sw=4:expandtab +#include #include #include #include @@ -11,7 +12,7 @@ #define MAX_EXPONENT 4 static const char *const iec_symbols[MAX_EXPONENT + 1] = {"", "Ki", "Mi", "Gi", "Ti"}; -static const char filename[] = "/proc/meminfo"; +static const char memoryfile_linux[] = "/proc/meminfo"; /* * Prints the given amount of bytes in a human readable manner. @@ -29,170 +30,179 @@ static int print_bytes_human(char *outwalk, uint64_t bytes) { } /* - * Determines whether remaining bytes are below given threshold. + * Convert a string to its absolute representation based on the total + * memory of `mem_total`. + * + * The string can contain any percentage values, which then return a + * the value of `size` in relation to `mem_total`. + * Alternatively an absolute value can be given, suffixed with an iec + * symbol. * */ -static bool below_threshold(const long totalRam, const long usedRam, const char *threshold_type, const long low_threshold) { - // empty is available or free, based on "use_available_memory" - long empty = totalRam - usedRam; - if (BEGINS_WITH(threshold_type, "percentage_")) { - return 100.0 * empty / totalRam < low_threshold; - } else if (strcasecmp(threshold_type, "bytes_free") == 0) { - return empty < low_threshold; - } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) { - uint64_t base = BINARY_BASE; - long factor = 1; - - switch (threshold_type[0]) { +static long memory_absolute(const long mem_total, const char *size) { + char *endptr = NULL; + + long mem_absolute = strtol(size, &endptr, 10); + + if (endptr) { + while (endptr[0] != '\0' && isspace(endptr[0])) + endptr++; + + switch (endptr[0]) { case 'T': case 't': - factor *= base; + mem_absolute *= BINARY_BASE; case 'G': case 'g': - factor *= base; + mem_absolute *= BINARY_BASE; case 'M': case 'm': - factor *= base; + mem_absolute *= BINARY_BASE; case 'K': case 'k': - factor *= base; + mem_absolute *= BINARY_BASE; + break; + case '%': + mem_absolute = mem_total * mem_absolute / 100; break; default: - return false; + break; } - return empty < low_threshold * factor; } - return false; + + return mem_absolute; } -void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *degraded_format_below_threshold, const char *degraded_threshold_type, const float degraded_low_threshold, const char *critical_format_below_threshold, const char *critical_threshold_type, const float critical_low_threshold, const bool use_available_memory) { +void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *format_degraded, const char *threshold_degraded, const char *threshold_critical, const char *memory_used_method) { char *outwalk = buffer; #if defined(linux) const char *selected_format = format; const char *walk; - bool colorful_output = false; + const char *output_color = NULL; - long totalRam = -1; - long freeRam = -1; - long availableRam = -1; - long usedRam = -1; - long sharedRam = -1; - long cached = -1; - long buffers = -1; + long ram_total = -1; + long ram_free = -1; + long ram_available = -1; + long ram_used = -1; + long ram_shared = -1; + long ram_cached = -1; + long ram_buffers = -1; - FILE *file = fopen(filename, "r"); + FILE *file = fopen(memoryfile_linux, "r"); if (!file) { goto error; } char line[128]; while (fgets(line, sizeof line, file)) { if (BEGINS_WITH(line, "MemTotal:")) { - totalRam = strtol(line + strlen("MemTotal:"), NULL, 10); + ram_total = strtol(line + strlen("MemTotal:"), NULL, 10); } if (BEGINS_WITH(line, "MemFree:")) { - freeRam = strtol(line + strlen("MemFree:"), NULL, 10); + ram_free = strtol(line + strlen("MemFree:"), NULL, 10); } if (BEGINS_WITH(line, "MemAvailable:")) { - availableRam = strtol(line + strlen("MemAvailable:"), NULL, 10); + ram_available = strtol(line + strlen("MemAvailable:"), NULL, 10); } if (BEGINS_WITH(line, "Buffers:")) { - buffers = strtol(line + strlen("Buffers:"), NULL, 10); + ram_buffers = strtol(line + strlen("Buffers:"), NULL, 10); } if (BEGINS_WITH(line, "Cached:")) { - cached = strtol(line + strlen("Cached:"), NULL, 10); + ram_cached = strtol(line + strlen("Cached:"), NULL, 10); } if (BEGINS_WITH(line, "Shmem:")) { - sharedRam = strtol(line + strlen("Shmem:"), NULL, 10); + ram_shared = strtol(line + strlen("Shmem:"), NULL, 10); } - if (totalRam != -1 && freeRam != -1 && availableRam != -1 && buffers != -1 && cached != -1 && sharedRam != -1) { + if (ram_total != -1 && ram_free != -1 && ram_available != -1 && ram_buffers != -1 && ram_cached != -1 && ram_shared != -1) { break; } } fclose(file); - if (totalRam == -1 || freeRam == -1 || availableRam == -1 || buffers == -1 || cached == -1 || sharedRam == -1) { + if (ram_total == -1 || ram_free == -1 || ram_available == -1 || ram_buffers == -1 || ram_cached == -1 || ram_shared == -1) { goto error; } - totalRam = totalRam * BINARY_BASE; - freeRam = freeRam * BINARY_BASE; - availableRam = availableRam * BINARY_BASE; - buffers = buffers * BINARY_BASE; - cached = cached * BINARY_BASE; - sharedRam = sharedRam * BINARY_BASE; - if (use_available_memory) { - usedRam = totalRam - availableRam; - } else { - usedRam = totalRam - freeRam - buffers - cached; + ram_total = ram_total * BINARY_BASE; + ram_free = ram_free * BINARY_BASE; + ram_available = ram_available * BINARY_BASE; + ram_buffers = ram_buffers * BINARY_BASE; + ram_cached = ram_cached * BINARY_BASE; + ram_shared = ram_shared * BINARY_BASE; + + if (BEGINS_WITH(memory_used_method, "memavailable")) { + ram_used = ram_total - ram_available; + } else if (BEGINS_WITH(memory_used_method, "classical")) { + ram_used = ram_total - ram_free - ram_buffers - ram_cached; } - if (degraded_low_threshold > 0 && below_threshold(totalRam, usedRam, degraded_threshold_type, degraded_low_threshold)) { - if (critical_low_threshold > 0 && below_threshold(totalRam, usedRam, critical_threshold_type, critical_low_threshold)) { - START_COLOR("color_bad"); - colorful_output = true; - if (critical_format_below_threshold != NULL) - selected_format = critical_format_below_threshold; - } else { - START_COLOR("color_degraded"); - colorful_output = true; - if (degraded_format_below_threshold != NULL) - selected_format = degraded_format_below_threshold; + if (threshold_degraded) { + long abs = memory_absolute(ram_total, threshold_degraded); + if (ram_available < abs) { + output_color = "color_degraded"; + } + } + + if (threshold_critical) { + long abs = memory_absolute(ram_total, threshold_critical); + if (ram_available < abs) { + output_color = "color_bad"; } } + if (output_color) { + START_COLOR(output_color); + + if (format_degraded) + selected_format = format_degraded; + } + for (walk = selected_format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; - continue; - } - if (BEGINS_WITH(walk + 1, "total")) { - outwalk += print_bytes_human(outwalk, totalRam); + + } else if (BEGINS_WITH(walk + 1, "total")) { + outwalk += print_bytes_human(outwalk, ram_total); walk += strlen("total"); - } - if (BEGINS_WITH(walk + 1, "used")) { - outwalk += print_bytes_human(outwalk, usedRam); + } else if (BEGINS_WITH(walk + 1, "used")) { + outwalk += print_bytes_human(outwalk, ram_used); walk += strlen("used"); - } - if (BEGINS_WITH(walk + 1, "free")) { - outwalk += print_bytes_human(outwalk, freeRam); + } else if (BEGINS_WITH(walk + 1, "free")) { + outwalk += print_bytes_human(outwalk, ram_free); walk += strlen("free"); - } - if (BEGINS_WITH(walk + 1, "available")) { - outwalk += print_bytes_human(outwalk, availableRam); + } else if (BEGINS_WITH(walk + 1, "available")) { + outwalk += print_bytes_human(outwalk, ram_available); walk += strlen("available"); - } - if (BEGINS_WITH(walk + 1, "shared")) { - outwalk += print_bytes_human(outwalk, sharedRam); + } else if (BEGINS_WITH(walk + 1, "shared")) { + outwalk += print_bytes_human(outwalk, ram_shared); walk += strlen("shared"); - } - if (BEGINS_WITH(walk + 1, "percentage_free")) { - outwalk += sprintf(outwalk, "%.01f%s", 100.0 * freeRam / totalRam, pct_mark); + } else if (BEGINS_WITH(walk + 1, "percentage_free")) { + outwalk += sprintf(outwalk, "%.01f%s", 100.0 * ram_free / ram_total, pct_mark); walk += strlen("percentage_free"); - } - if (BEGINS_WITH(walk + 1, "percentage_available")) { - outwalk += sprintf(outwalk, "%.01f%s", 100.0 * availableRam / totalRam, pct_mark); + } else if (BEGINS_WITH(walk + 1, "percentage_available")) { + outwalk += sprintf(outwalk, "%.01f%s", 100.0 * ram_available / ram_total, pct_mark); walk += strlen("percentage_available"); - } - if (BEGINS_WITH(walk + 1, "percentage_used")) { - outwalk += sprintf(outwalk, "%.01f%s", 100.0 * usedRam / totalRam, pct_mark); + } else if (BEGINS_WITH(walk + 1, "percentage_used")) { + outwalk += sprintf(outwalk, "%.01f%s", 100.0 * ram_used / ram_total, pct_mark); walk += strlen("percentage_used"); - } - if (BEGINS_WITH(walk + 1, "percentage_shared")) { - outwalk += sprintf(outwalk, "%.01f%s", 100.0 * sharedRam / totalRam, pct_mark); + } else if (BEGINS_WITH(walk + 1, "percentage_shared")) { + outwalk += sprintf(outwalk, "%.01f%s", 100.0 * ram_shared / ram_total, pct_mark); walk += strlen("percentage_shared"); + + } else { + *(outwalk++) = '%'; } } - if (colorful_output) + if (output_color) END_COLOR; *outwalk = '\0'; @@ -203,6 +213,7 @@ error: OUTPUT_FULL_TEXT("can't read memory"); fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); #else + OUTPUT_FULL_TEXT(""); fputs("i3status: Memory status information is not supported on this system\n", stderr); #endif }