]> code.delx.au - monosys/blobdiff - xfce4-genmon-script.c
multiboot-setup: support Debian10 installer
[monosys] / xfce4-genmon-script.c
index c3c2eec0717b21b24294204bfd0f4220cb042d1f..c86426fb97d6a7d1ac3d9f9c6d84d9f27f774018 100644 (file)
@@ -29,10 +29,13 @@ char* read_file(char* filename) {
     size_t pos = 0;
     int fd = open(filename, 0);
 
+    if (fd < 0) {
+        return NULL;
+    }
+
     for (;;) {
         ssize_t result = read(fd, buf+pos, sizeof(buf)-pos);
         if (result < 0) {
-            fprintf(stderr, "Failed reading file: %s -- %s\n", strerror(errno), filename);
             return NULL;
         }
         if (result == 0) {
@@ -46,13 +49,13 @@ char* read_file(char* filename) {
     }
 }
 
-int parse_int(char* s) {
+long parse_int(char* s) {
     if (s == NULL) {
         return -1;
     }
 
     errno = 0;
-    int value = strtol(s, NULL, 10);
+    long value = strtol(s, NULL, 10);
     if (errno != 0) {
         fprintf(stderr, "Failed to parse string: %s -- %s\n", strerror(errno), s);
         return -1;
@@ -76,6 +79,7 @@ char* read_next_line(char** s) {
 int read_cpu_idle_jiffys() {
     char* procstat = read_file("/proc/stat");
     if (procstat == NULL) {
+        fprintf(stderr, "Failed reading file /proc/stat: %s\n", strerror(errno));
         return -1;
     }
 
@@ -94,6 +98,7 @@ int read_cpu_idle_jiffys() {
 int count_cpus() {
     char* procstat = read_file("/proc/stat");
     if (procstat == NULL) {
+        fprintf(stderr, "Failed reading file /proc/stat: %s\n", strerror(errno));
         return -1;
     }
 
@@ -128,16 +133,17 @@ int read_cpu_percent() {
     return 100 - (int)round(idle_jiffys_per_cpu_second);
 }
 
-int read_mem_percent() {
+int read_meminfo(int* mem_free_mibis, int* mem_total_mibis) {
     char* meminfo = read_file("/proc/meminfo");
     if (meminfo == NULL) {
+        fprintf(stderr, "Failed reading file /proc/meminfo: %s\n", strerror(errno));
         return -1;
     }
 
-    int mem_total = -1;
-    int mem_free = -1;
+    *mem_free_mibis = -1;
+    *mem_total_mibis = -1;
 
-    while (*meminfo && (mem_total < 0 || mem_free < 0)) {
+    while (*meminfo) {
         char* line = read_next_line(&meminfo);
         if (line == NULL) {
             break;
@@ -151,35 +157,76 @@ int read_mem_percent() {
             return -1;
         }
 
+        if (strcmp(key, "MemAvailable") == 0) {
+            int mem_available = parse_int(value_str);
+            *mem_free_mibis = (int)round((double)mem_available / 1024);
+        }
+
         if (strcmp(key, "MemTotal") == 0) {
-            mem_total = parse_int(value_str);
-        } else if (strcmp(key, "MemAvailable") == 0) {
-            mem_free = parse_int(value_str);
+            int mem_available = parse_int(value_str);
+            *mem_total_mibis = (int)round((double)mem_available / 1024);
         }
     }
 
-    if (mem_total < 0 || mem_free < 0) {
-        fprintf(stderr, "Failed to find MemTotal and MemAvailable in /proc/meminfo\n");
+    if (*mem_free_mibis < 0 || *mem_total_mibis < 0) {
+        fprintf(stderr, "Failed to find field in /proc/meminfo\n");
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+int read_zfs_arc_used_mibis() {
+    char* arcstats = read_file("/proc/spl/kstat/zfs/arcstats");
+    if (arcstats == NULL) {
         return -1;
     }
 
-    int mem_used = mem_total - mem_free;
+    while (*arcstats) {
+        char* line = read_next_line(&arcstats);
+        if (line == NULL) {
+            break;
+        }
+
+        char* key = strtok(line, " ");
+        strtok(NULL, " ");
+        char* value_str = strtok(NULL, " ");
+
+        if (key == NULL || value_str == NULL) {
+            fprintf(stderr, "Failed to parse key/value token in /proc/spl/kstat/zfs/arcstats\n");
+            return -1;
+        }
+
+        if (strcmp(key, "size") == 0) {
+            long arc_used = parse_int(value_str);
+            return (int)round((double)arc_used / 1024 / 1024);
+        }
+    }
 
-    return (int)round((double)mem_used / (double)mem_total * 100);
+    fprintf(stderr, "Failed to find 'c' in /proc/spl/kstat/zfs/arcstats\n");
+    return -1;
 }
 
 int read_battery_percent() {
     char* percent_str = NULL;
+
     if (percent_str == NULL) {
         percent_str = read_file("/sys/class/power_supply/BAT0/capacity");
     }
+
     if (percent_str == NULL) {
         percent_str = read_file("/sys/class/power_supply/BAT1/capacity");
     }
+
+    if (percent_str == NULL) {
+        fprintf(stderr, "Failed reading file battery capacity file: %s\n", strerror(errno));
+        return -1;
+    }
+
     return parse_int(percent_str);
 }
 
-void print_percent(
+void print_red_threshold(
     char* name, char* units,
     int value,
     int red_low, int red_high
@@ -194,31 +241,48 @@ void print_percent(
     }
 
     printf(
-        "%s <span color='%s'>%d</span>%s  ",
+        "%s <span color='%s'>%d</span>%s\n",
         name, color, value, units
     );
 }
 
-int main(void) {
-    printf("<txt>");
+int main(int argc, char** argv) {
+    char* show_flags = "cmb";
+    char* top_padding = "0";
+    if (argc >= 2) {
+        show_flags = argv[1];
+    }
+    if (argc >= 3) {
+        top_padding = argv[2];
+    }
 
-    print_percent(
-        "cpu", "%",
-        read_cpu_percent(),
-        50, 100
-    );
+    printf("<txt><span size=\"%s\">\n</span>", top_padding);
 
-    print_percent(
-        "mem", "%",
-        read_mem_percent(),
-        70, 100
-    );
+    if (strchr(show_flags, 'c')) {
+        print_red_threshold(
+            "cpu", "%",
+            read_cpu_percent(),
+            50, 100
+        );
+    }
 
-    print_percent(
-        "batt", "%",
-        read_battery_percent(),
-        0, 25
-    );
+    if (strchr(show_flags, 'm')) {
+        int mem_free_mibis, mem_total_mibis;
+        read_meminfo(&mem_free_mibis, &mem_total_mibis);
+        print_red_threshold(
+            "mem", " MiB",
+            mem_free_mibis + read_zfs_arc_used_mibis(),
+            0, mem_total_mibis / 10
+        );
+    }
+
+    if (strchr(show_flags, 'b')) {
+        print_red_threshold(
+            "batt", "%",
+            read_battery_percent(),
+            0, 25
+        );
+    }
 
     printf("</txt>");