---
Makefile | 1 +
README | 1 +
components/iocheck.c | 170 +++++++++++++++++++++++++++++++++++++++++++
config.def.h | 3 +
slstatus.h | 5 ++
5 files changed, 180 insertions(+)
create mode 100644 components/iocheck.c
diff --git a/Makefile b/Makefile
index 2f93b87..fd85ad7 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -12,6 +12,7 @@ COM =\
components/disk\
components/entropy\
components/hostname\
+ components/iocheck\
components/ip\
components/kernel_release\
components/keyboard_indicators\
diff --git a/README b/README
index 86fe988..996c22e 100644
--- a/README
+++ b/README
_AT_@ -15,6 +15,7 @@ Features
- Available entropy
- Username/GID/UID
- Hostname
+- Disk IO (read, write and percentage) (Linux only)
- IP address (IPv4 and IPv6)
- Kernel version
- Keyboard indicators
diff --git a/components/iocheck.c b/components/iocheck.c
new file mode 100644
index 0000000..d3ff9d8
--- /dev/null
+++ b/components/iocheck.c
_AT_@ -0,0 +1,170 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include "../util.h"
+
+#if defined(__linux__)
+ static int
+ get_io(uintmax_t *s_in, uintmax_t *s_out)
+ {
+ FILE *fp;
+ struct {
+ const char *name;
+ const size_t len;
+ uintmax_t *var;
+ } ent[] = {
+ { "pgpgin", sizeof("pgpgin") - 1, s_in },
+ { "pgpgout", sizeof("pgpgout") - 1, s_out },
+ };
+ size_t line_len = 0, i, left;
+ char *line = NULL;
+
+ /* get number of fields we want to extract */
+ for (i = 0, left = 0; i < LEN(ent); i++) {
+ if (ent[i].var) {
+ left++;
+ }
+ }
+
+ if (!(fp = fopen("/proc/vmstat", "r"))) {
+ warn("fopen '/proc/vmstat':");
+ return 1;
+ }
+
+ /* read file line by line and extract field information */
+ while (left > 0 && getline(&line, &line_len, fp) >= 0) {
+ for (i = 0; i < LEN(ent); i++) {
+ if (ent[i].var &&
+ !strncmp(line,ent[i].name, ent[i].len)) {
+ sscanf(line + ent[i].len + 1,
+ "%ju\n", ent[i].var);
+ left--;
+ break;
+ }
+ }
+ }
+ free(line);
+ if(ferror(fp)) {
+ warn("getline '/proc/vmstat':");
+ return 1;
+ }
+
+ fclose(fp);
+ return 0;
+ }
+
+ const char *
+ io_in(void)
+ {
+ uintmax_t oldin;
+ static uintmax_t newin;
+
+ oldin = newin;
+
+ if (get_io(&newin, NULL)) {
+ return NULL;
+ }
+ if (oldin == 0) {
+ return NULL;
+ }
+
+ return fmt_human((newin-oldin) * 1024, 1024);
+ }
+
+ const char *
+ io_out(void)
+ {
+ uintmax_t oldout;
+ static uintmax_t newout;
+
+ oldout = newout;
+
+ if (get_io(NULL, &newout)) {
+ return NULL;
+ }
+ if (oldout == 0) {
+ return NULL;
+ }
+
+ return fmt_human((newout - oldout) * 1024, 1024);
+ }
+
+ const char *
+ io_perc(void)
+ {
+ struct dirent *dp;
+ DIR *bd;
+ uintmax_t oldwait;
+ static uintmax_t newwait;
+ extern const unsigned int interval;
+
+ oldwait = newwait;
+
+ if (!(bd = opendir("/sys/block"))) {
+ warn("opendir '%s':", "/sys/block");
+ return NULL;
+ }
+
+ newwait = 0;
+ /* get IO wait stats from the /sys/block directories */
+ while ((dp = readdir(bd))) {
+ if (strstr(dp->d_name, "loop") ||
+ strstr(dp->d_name, "ram")) {
+ continue;
+ }
+ if (!strcmp(dp->d_name, ".") ||
+ !strcmp(dp->d_name, "..")) {
+ continue;
+ }
+ /* virtual devices don't count */
+ char virtpath[50];
+ strcpy(virtpath, "/sys/devices/virtual/block/");
+ strcat(virtpath, dp->d_name);
+ if (access(virtpath, R_OK) == 0) {
+ continue;
+ }
+ char statpath[34];
+ strcpy(statpath, "/sys/block/");
+ strcat(statpath, dp->d_name);
+ strcat(statpath, "/stat");
+ uintmax_t partwait;
+ if (pscanf(statpath,
+ "%*d %*d %*d %*d %*d %*d %*d %*d %*d %ju %*d",
+ &partwait) != 1) {
+ continue;
+ }
+ newwait += partwait;
+ }
+ closedir(bd);
+ if (oldwait == 0 || newwait < oldwait) {
+ return NULL;
+ }
+
+ return bprintf("%0.1f", 100 *
+ (newwait - oldwait) / (float)interval);
+ }
+
+#else
+ const char *
+ io_in(void)
+ {
+ return NULL;
+ }
+
+ const char *
+ io_out(void)
+ {
+ return NULL;
+ }
+
+ const char *
+ io_perc(void)
+ {
+ return NULL;
+ }
+#endif
diff --git a/config.def.h b/config.def.h
index 93a875a..c321c50 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -28,6 +28,9 @@ static const char unknown_str[] = "n/a";
* entropy available entropy NULL
* gid GID of current user NULL
* hostname hostname NULL
+ * io_in disk IO (read) NULL
+ * io_out disk IO (write) NULL
+ * io_perc disk IO (percentage) NULL
* ipv4 IPv4 address interface name (eth0)
* ipv6 IPv6 address interface name (eth0)
* kernel_release `uname -r` NULL
diff --git a/slstatus.h b/slstatus.h
index b0f2564..3464f5b 100644
--- a/slstatus.h
+++ b/slstatus.h
_AT_@ -24,6 +24,11 @@ const char *entropy(void);
/* hostname */
const char *hostname(void);
+/* iocheck */
+const char *io_in(void);
+const char *io_out(void);
+const char *io_perc(void);
+
/* ip */
const char *ipv4(const char *interface);
const char *ipv6(const char *interface);
--
2.33.0
Received on Thu Sep 02 2021 - 18:09:02 CEST
This archive was generated by hypermail 2.3.0 : Thu Sep 02 2021 - 21:24:29 CEST