From 1a40b793adbdd7c8718b9f383eadd1ab0bb02cf0 Mon Sep 17 00:00:00 2001
From: Stanislaw Halik <sthalik@misaki.pl>
Date: Thu, 26 Dec 2024 06:27:31 +0100
Subject: [PATCH] compat: fix Linux process list

`procps-ng` silently broke API compatibility in a patch release.

Reported-by: @DoomSlinger
Fix-by: @thorger
Fixes: #1970
---
 compat/process-list.hpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/compat/process-list.hpp b/compat/process-list.hpp
index 6d9606103..34d65a752 100644
--- a/compat/process-list.hpp
+++ b/compat/process-list.hpp
@@ -148,9 +148,22 @@ QStringList get_all_executable_names()
 
     procps_pids_new(&info, items, 3);
 
+    // procps-ng version 4.0.5 removed an unused argument in PIDS_VAL() macro.
+    // cf. https://gitlab.com/procps-ng/procps/-/commit/967fdcfb06e20aad0f3
+
+    // Although the emitted machine code is identical, backward API
+    // compatibility was silently broken in the patch with no upgrade path
+    // (e.g. deprecating PIDS_VAL() while introducing PIDS_VAL2()).
+
+    // Unfortunately, procps-ng doesn't include a #define for identifying its
+    // version.  For these reasons the code below depends on undocumented ABI
+    // compatibility between procps-ng versions.. -sh 20241226
+
+#define OPENTRACK_PIDS_VAL(i, type, stack) stack->head[i].result.type
+
     while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY)))
     {
-        char  **p_cmdline = PIDS_VAL(rel_cmdline, strv,  stack, info);
+        char **p_cmdline = OPENTRACK_PIDS_VAL(rel_cmdline, strv, stack);
 
         // note, wine sets argv[0] so no parsing like in OSX case
         if (p_cmdline && p_cmdline[0] && p_cmdline[0][0] &&
