htop
htop copied to clipboard
Add option to shadow path prefixes
Shadow path prefixes which are used by distributions, like
- /usr/bin/
- /usr/sbin/
- /bin/
- /sbin/
- /usr/libexec/
What about /usr/local/bin
, /usr/local/sbin
, and /opt
?
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.
Cf. https://unix.stackexchange.com/questions/332764/role-of-the-usr-local-directory-in-freebsd
Minor visual glitch still present:
Disabling MergeCommand this works fine …
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.