[gnome-terminal/gnome-3-34-ntfy-opn-ttl-ts: 5/16] screen: Try harder to find a foreground process group member



commit 6e7c40c2afd31c7db85a040284920e473716c49c
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri May 18 20:15:34 2018 +0200

    screen: Try harder to find a foreground process group member
    
    For pipelined commands, it's possible that the process group leader,
    whose PID is used as the group ID, has terminated but not the entire
    group. eg., $ cat <file> | less.  Sadly, there's no nice user-space
    API to list the members of a group, and crawling the entire /proc like
    pgrep might be overkill if the system is overloaded.
    
    Therefore, the next 20 PIDs after the group ID and the first 20 PIDs
    starting from 2 are checked in the hope that one of them would belong
    to the foreground process group.
    
    Subsequent commits will use this to track the current foreground
    process, instead of using the shell's history, to notify when a
    long-running foreground process group terminates.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711059

 src/terminal-screen.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)
---
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 1b763a38..db281cbf 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -2136,7 +2136,35 @@ terminal_screen_has_foreground_process (TerminalScreen *screen,
 #else
   g_snprintf (filename, sizeof (filename), "/proc/%d/cmdline", fgpid);
   if (!g_file_get_contents (filename, &data_buf, &len, NULL))
-    return TRUE;
+    {
+      int j;
+
+      for (j = 0; j < 20; j++)
+        {
+          pid_t pgid;
+          pid_t pid;
+
+          pid = (pid_t) (fgpid + 1 + j);
+          pgid = getpgid (pid);
+          if (pgid != fgpid)
+            {
+              pid = (pid_t) (2 + j);
+              pgid = getpgid (pid);
+              if (pgid != fgpid)
+                continue;
+            }
+
+          g_snprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
+
+          g_clear_pointer (&data_buf, g_free);
+          if (g_file_get_contents (filename, &data_buf, &len, NULL))
+            break;
+        }
+
+      if (j == 20)
+        return TRUE;
+    }
+
   data = data_buf;
 #endif
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]