htop icon indicating copy to clipboard operation
htop copied to clipboard

Add option to shadow path prefixes

Open cgzones opened this issue 3 years ago • 3 comments

Shadow path prefixes which are used by distributions, like

  • /usr/bin/
  • /usr/sbin/
  • /bin/
  • /sbin/
  • /usr/libexec/

cgzones avatar May 23 '21 14:05 cgzones

What about /usr/local/bin, /usr/local/sbin, and /opt?

BenBE avatar May 23 '21 15:05 BenBE

The original idea was to shadow paths used by distribution packages. It was not about "trusted" (e.g. /root/bin could be considered trusted) or common (like /usr/local/bin) ones.

cgzones avatar Jun 09 '21 12:06 cgzones

Cf. https://unix.stackexchange.com/questions/332764/role-of-the-usr-local-directory-in-freebsd

BenBE avatar Jun 09 '21 13:06 BenBE

Minor visual glitch still present: image

Disabling MergeCommand this works fine …

BenBE avatar Jan 31 '23 09:01 BenBE

While fixing the above issue, I also did a small re-organization in the code, as there's already a facility for highlighting stuff in the command column:

diff --git a/Process.c b/Process.c
index 9ee8f3ca..e38a698e 100644
--- a/Process.c
+++ b/Process.c
@@ -413,6 +413,7 @@ void Process_makeCommandStr(Process* this) {
    bool searchCommInCmdline = settings->findCommInCmdline;
    bool stripExeFromCmdline = settings->stripExeFromCmdline;
    bool showThreadNames = settings->showThreadNames;
+   bool shadowDistPathPrefix = settings->shadowDistPathPrefix;
 
    uint64_t settingsStamp = settings->lastUpdate;
 
@@ -472,6 +473,51 @@ void Process_makeCommandStr(Process* this) {
          str = stpcpy(str, SEPARATOR);                                                        \
       } while (0)
 
+   #define CHECK_AND_MARK(str_, prefix_)                                                      \
+      if (String_startsWith(str_, prefix_)) {                                                 \
+         WRITE_HIGHLIGHT(0, strlen(prefix_), CRT_colors[PROCESS_SHADOW], CMDLINE_HIGHLIGHT_FLAG_PREFIXDIR); \
+         break;                                                                               \
+      } else (void)0
+
+   #define CHECK_AND_MARK_DIST_PATH_PREFIXES(str_)                                            \
+      switch ((str_)[1]) {                                                                    \
+         case 'b':                                                                            \
+            CHECK_AND_MARK(str_, "/bin/");                                                    \
+            break;                                                                            \
+         case 'l':                                                                            \
+            CHECK_AND_MARK(str_, "/lib/");                                                    \
+            CHECK_AND_MARK(str_, "/lib32/");                                                  \
+            CHECK_AND_MARK(str_, "/lib64/");                                                  \
+            CHECK_AND_MARK(str_, "/libx32/");                                                 \
+            break;                                                                            \
+         case 's':                                                                            \
+            CHECK_AND_MARK(str_, "/sbin/");                                                   \
+            break;                                                                            \
+         case 'u':                                                                            \
+            if (String_startsWith(str_, "/usr/")) {                                           \
+               switch ((str_)[5]) {                                                           \
+                  case 'b':                                                                   \
+                     CHECK_AND_MARK(str_, "/usr/bin/");                                       \
+                     break;                                                                   \
+                  case 'l':                                                                   \
+                     CHECK_AND_MARK(str_, "/usr/libexec/");                                   \
+                     CHECK_AND_MARK(str_, "/usr/lib/");                                       \
+                     CHECK_AND_MARK(str_, "/usr/lib32/");                                     \
+                     CHECK_AND_MARK(str_, "/usr/lib64/");                                     \
+                     CHECK_AND_MARK(str_, "/usr/libx32/");                                    \
+                                                                                              \
+                     CHECK_AND_MARK(str_, "/usr/local/bin/");                                 \
+                     CHECK_AND_MARK(str_, "/usr/local/lib/");                                 \
+                     CHECK_AND_MARK(str_, "/usr/local/sbin/");                                \
+                     break;                                                                   \
+                  case 's':                                                                   \
+                     CHECK_AND_MARK(str_, "/usr/sbin/");                                      \
+                     break;                                                                   \
+               }                                                                              \
+            }                                                                                 \
+            break;                                                                            \
+         }
+
    const int baseAttr = Process_isThread(this) ? CRT_colors[PROCESS_THREAD_BASENAME] : CRT_colors[PROCESS_BASENAME];
    const int commAttr = Process_isThread(this) ? CRT_colors[PROCESS_THREAD_COMM] : CRT_colors[PROCESS_COMM];
    const int delExeAttr = CRT_colors[FAILED_READ];
@@ -510,6 +556,10 @@ void Process_makeCommandStr(Process* this) {
          }
       }
 
+      if (shadowDistPathPrefix && showProgramPath && cmdline[0] == '/') {
+         CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline);
+      }
+
       if (cmdlineBasenameEnd > cmdlineBasenameStart)
          WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
 
@@ -537,6 +587,8 @@ void Process_makeCommandStr(Process* this) {
 
    /* Start with copying exe */
    if (showProgramPath) {
+      if (shadowDistPathPrefix)
+         CHECK_AND_MARK_DIST_PATH_PREFIXES(procExe);
       if (haveCommInExe)
          WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
       WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
@@ -594,6 +646,9 @@ void Process_makeCommandStr(Process* this) {
       WRITE_SEPARATOR;
    }
 
+   if (shadowDistPathPrefix)
+      CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline);
+
    if (!haveCommInExe && haveCommInCmdline && !haveCommField && (!Process_isUserlandThread(this) || showThreadNames))
       WRITE_HIGHLIGHT(commStart, commEnd - commStart, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
 
@@ -601,6 +656,8 @@ void Process_makeCommandStr(Process* this) {
    if (*cmdline)
       (void)stpcpyWithNewlineConversion(str, cmdline);
 
+   #undef CHECK_AND_MARK_DIST_PATH_PREFIXES
+   #undef CHECK_AND_MARK
    #undef WRITE_SEPARATOR
    #undef WRITE_HIGHLIGHT
 }
@@ -670,55 +727,11 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin
          if (!highlightDeleted)
             continue;
 
-      RichString_setAttrn(str, hl->attr, strStart + hl->offset, hl->length);
-   }
-
-   if (this->settings->shadowDistPathPrefix && mergedCommand[0] == '/') {
-      #define CHECK_AND_MARK(prefix_)                                                         \
-         if (String_startsWith(mergedCommand, prefix_)) {                                     \
-            RichString_setAttrn(str, CRT_colors[PROCESS_SHADOW], strStart, strlen(prefix_));  \
-            break;                                                                            \
-         } else (void)0
-
-      switch (mergedCommand[1]) {
-         case 'b':
-            CHECK_AND_MARK("/bin/");
-            break;
-         case 'l':
-            CHECK_AND_MARK("/lib/");
-            CHECK_AND_MARK("/lib32/");
-            CHECK_AND_MARK("/lib64/");
-            CHECK_AND_MARK("/libx32/");
-            break;
-         case 's':
-            CHECK_AND_MARK("/sbin/");
-            break;
-         case 'u':
-            if (String_startsWith(mergedCommand, "/usr/")) {
-               switch (mergedCommand[5]) {
-                  case 'b':
-                     CHECK_AND_MARK("/usr/bin/");
-                     break;
-                  case 'l':
-                     CHECK_AND_MARK("/usr/libexec/");
-                     CHECK_AND_MARK("/usr/lib/");
-                     CHECK_AND_MARK("/usr/lib32/");
-                     CHECK_AND_MARK("/usr/lib64/");
-                     CHECK_AND_MARK("/usr/libx32/");
-
-                     CHECK_AND_MARK("/usr/local/bin/");
-                     CHECK_AND_MARK("/usr/local/lib/");
-                     CHECK_AND_MARK("/usr/local/sbin/");
-                     break;
-                  case 's':
-                     CHECK_AND_MARK("/usr/sbin/");
-                     break;
-               }
-            }
-            break;
-      }
+      if (hl->flags & CMDLINE_HIGHLIGHT_FLAG_PREFIXDIR)
+         if (!highlightDeleted)
+            continue;
 
-      #undef CHECK_AND_MARK
+      RichString_setAttrn(str, hl->attr, strStart + hl->offset, hl->length);
    }
 }
 
diff --git a/Process.h b/Process.h
index fa047ace..eb79470d 100644
--- a/Process.h
+++ b/Process.h
@@ -331,6 +331,7 @@ static inline bool Process_isThread(const Process* this) {
 #define CMDLINE_HIGHLIGHT_FLAG_BASENAME   0x00000002
 #define CMDLINE_HIGHLIGHT_FLAG_COMM       0x00000004
 #define CMDLINE_HIGHLIGHT_FLAG_DELETED    0x00000008
+#define CMDLINE_HIGHLIGHT_FLAG_PREFIXDIR  0x00000010
 
 #define ONE_K 1024UL
 #define ONE_M (ONE_K * ONE_K)

Please test and give a quick feedback if you see anything odd. Will push my local patches later.

BenBE avatar Jan 31 '23 15:01 BenBE