Index | Thread | Search

From:
Kristaps Dzonsons <kristaps@bsd.lv>
Subject:
Patch: x11/i3status
To:
"ports@openbsd.org" <ports@openbsd.org>
Date:
Wed, 5 Nov 2025 09:28:42 -0800

Download raw body.

Thread
  • Kristaps Dzonsons:

    Patch: x11/i3status

Hi all, the i3status port didn't include memory information, so I added 
it in.  Enclosed is a patch for the memory and additional documentation 
in the manpage.

The calculation for used/available memory is a little different than on 
Linux:

  total = (usermem from sysctl)
  free = (from sysctl)
  cached = (from sysctl)
  buffers = shared = 0
  available = free + cached
  used (memavailable) = total - available
  used (classical) = total - free - buffers - cached
  shared = 0

So both methods of used memory are equivalent.

These are already in an upstream PR.

Best,

Kristaps

Index: src/print_mem.c
--- src/print_mem.c.orig
+++ src/print_mem.c
@@ -5,6 +5,11 @@
 #include <stdlib.h>
 #include <yajl/yajl_gen.h>
 #include <yajl/yajl_version.h>
+#ifdef __OpenBSD__
+# include <sys/mount.h> 
+# include <sys/shm.h> 
+# include <sys/sysctl.h>
+#endif
 #include "i3status.h"
 
 #define MAX_DECIMALS 4
@@ -12,12 +17,12 @@
 
 #define BINARY_BASE 1024UL
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
 static const char *const iec_symbols[] = {"B", "KiB", "MiB", "GiB", "TiB"};
 #define MAX_EXPONENT ((sizeof iec_symbols / sizeof *iec_symbols) - 1)
 #endif
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
 /*
  * Prints the given amount of bytes in a human readable manner.
  *
@@ -42,7 +47,7 @@ static int print_percentage(char *outwalk, float perce
 }
 #endif
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
 /*
  * Convert a string to its absolute representation based on the total
  * memory of `mem_total`.
@@ -89,11 +94,10 @@ static unsigned long memory_absolute(const char *mem_a
 void print_memory(memory_ctx_t *ctx) {
     char *outwalk = ctx->buf;
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
     const char *selected_format = ctx->format;
     const char *output_color = NULL;
 
-    int unread_fields = 6;
     unsigned long ram_total;
     unsigned long ram_free;
     unsigned long ram_available;
@@ -101,6 +105,51 @@ void print_memory(memory_ctx_t *ctx) {
     unsigned long ram_cached;
     unsigned long ram_shared;
 
+#if defined(__OpenBSD__)
+    int64_t tmp;
+    size_t sz;
+
+    /* Total memory set to the physical memory less kernel. */
+
+    int usermem_mib[] = {CTL_HW, HW_USERMEM64};
+    sz = sizeof(tmp);
+    if (sysctl(usermem_mib, 2, &tmp, &sz, NULL, 0) != 0) {
+        goto error;
+    }
+    ram_total = tmp;
+
+    int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
+    struct uvmexp uvmexp;
+    sz = sizeof(uvmexp);
+    if (sysctl(uvmexp_mib, 2, &uvmexp, &sz, NULL, 0) == -1) {
+        goto error;
+    }
+    const long pagesize = sysconf(_SC_PAGESIZE);
+    ram_free = uvmexp.free * pagesize;
+
+    int shmall_mib[] = {CTL_KERN, KERN_SHMINFO, KERN_SHMINFO_SHMALL};
+    sz = sizeof(tmp);
+    if (sysctl(shmall_mib, 3, &tmp, &sz, NULL, 0) == -1) {
+        goto error;
+    }
+
+    int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
+    struct bcachestats bcstats;
+    sz = sizeof(bcstats);
+    if (sysctl(bcstats_mib, 3, &bcstats, &sz, NULL, 0) == -1) {
+        goto error;
+    }
+    ram_cached = bcstats.numbufpages * pagesize;
+
+    /* Available is free and cached memory. */
+
+    ram_available = ram_free + ram_cached;
+
+    /* This information doesn't seem to exist. */
+
+    ram_shared = ram_buffers = 0;
+#elif defined(__linux__)
+    int unread_fields = 6;
     FILE *file = fopen("/proc/meminfo", "r");
     if (!file) {
         goto error;
@@ -138,6 +187,7 @@ void print_memory(memory_ctx_t *ctx) {
     ram_buffers *= 1024UL;
     ram_cached *= 1024UL;
     ram_shared *= 1024UL;
+#endif
 
     unsigned long ram_used;
     if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) {
Index: man/i3status.man
--- man/i3status.man.orig
+++ man/i3status.man
@@ -469,8 +469,8 @@ starting from %cpu0. This feature is currently not sup
 
 === Memory
 
-Gets the memory usage from system on a Linux system from +/proc/meminfo+. Other
-systems are currently not supported.
+Gets the memory usage from +/proc/meminfo+ on a Linux system and +sysctl+ on
+OpenBSD. Other systems are currently not supported.
 
 As format placeholders, +total+, +used+, +free+, +available+ and +shared+ are
 available. These will print human readable values. It's also possible to prefix
@@ -487,17 +487,16 @@ If the +format_degraded+ parameter is given and either
 degraded threshold applies, +format_degraded+ will get used as format string.
 It acts equivalently to +format+.
 
-It's also possible to define the unit for the various format placeholders. As
-+/proc/meminfo+ returns the memory in kB they will be converted to the given
-unit. If no unit is given or the +auto+ option is used, the conversion will
-select the maximum possible unit.
+It's also possible to define the unit for the various format placeholders.
+If no unit is given or the +auto+ option is used, the conversion will select the
+maximum possible unit.
 
 As the converted format placeholder will be a decimal number, the number of
 decimals can be configured via the +decimals+ option. If no such option is
 given the converted format placeholder will have one decimal.
 
 As Linux' meminfo doesn't expose the overall memory in use, there are multiple
-methods to distinguish the actually used memory. 
+methods to distinguish the actually used memory. On OpenBSD, these are the same.
 
 *Example memory_used_method*: +memavailable+ ("total memory" - "MemAvailable", matches +free+ command)