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) {
}
}
-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;
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;
}
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;
}
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;
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
}
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>");