summaryrefslogtreecommitdiffstats
path: root/linux
diff options
context:
space:
mode:
authorBenny Baumann <BenBE@geshi.org>2021-04-10 13:31:39 +0200
committerBenBE <BenBE@geshi.org>2021-05-23 09:22:21 +0200
commitbcb18ef82269c68d54a160290e5f8b2e939674ec (patch)
treee5967c038b2d11ed906b8fdda0babe114dab3c46 /linux
parentc0d02024407411f75a4d7d5b63f26b74c727027b (diff)
Move Process_makeCommandStr to global Process implementation
Diffstat (limited to 'linux')
-rw-r--r--linux/LinuxProcess.c356
-rw-r--r--linux/LinuxProcess.h4
-rw-r--r--linux/LinuxProcessList.c4
3 files changed, 4 insertions, 360 deletions
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c
index 155bea86..7d32a6d3 100644
--- a/linux/LinuxProcess.c
+++ b/linux/LinuxProcess.c
@@ -172,358 +172,6 @@ static void LinuxProcess_printDelay(float delay_percent, char* buffer, int n) {
}
#endif
-/*
-TASK_COMM_LEN is defined to be 16 for /proc/[pid]/comm in man proc(5), but it is
-not available in an userspace header - so define it. Note: when colorizing a
-basename with the comm prefix, the entire basename (not just the comm prefix) is
-colorized for better readability, and it is implicit that only upto
-(TASK_COMM_LEN - 1) could be comm
-*/
-#define TASK_COMM_LEN 16
-
-static bool findCommInCmdline(const char *comm, const char *cmdline, int cmdlineBasenameStart, int *pCommStart, int *pCommEnd) {
- /* Try to find procComm in tokenized cmdline - this might in rare cases
- * mis-identify a string or fail, if comm or cmdline had been unsuitably
- * modified by the process */
- const char *tokenBase;
- size_t tokenLen;
- const size_t commLen = strlen(comm);
-
- if (cmdlineBasenameStart < 0)
- return false;
-
- for (const char *token = cmdline + cmdlineBasenameStart; *token;) {
- for (tokenBase = token; *token && *token != '\n'; ++token) {
- if (*token == '/') {
- tokenBase = token + 1;
- }
- }
- tokenLen = token - tokenBase;
-
- if ((tokenLen == commLen || (tokenLen > commLen && commLen == (TASK_COMM_LEN - 1))) &&
- strncmp(tokenBase, comm, commLen) == 0) {
- *pCommStart = tokenBase - cmdline;
- *pCommEnd = token - cmdline;
- return true;
- }
- if (*token) {
- do {
- ++token;
- } while (*token && '\n' == *token);
- }
- }
- return false;
-}
-
-static int matchCmdlinePrefixWithExeSuffix(const char *cmdline, int cmdlineBaseOffset, const char *exe, int exeBaseOffset, int exeBaseLen) {
- int matchLen; /* matching length to be returned */
- char delim; /* delimiter following basename */
-
- /* cmdline prefix is an absolute path: it must match whole exe. */
- if (cmdline[0] == '/') {
- matchLen = exeBaseLen + exeBaseOffset;
- if (strncmp(cmdline, exe, matchLen) == 0) {
- delim = cmdline[matchLen];
- if (delim == 0 || delim == '\n' || delim == ' ') {
- return matchLen;
- }
- }
- return 0;
- }
-
- /* cmdline prefix is a relative path: We need to first match the basename at
- * cmdlineBaseOffset and then reverse match the cmdline prefix with the exe
- * suffix. But there is a catch: Some processes modify their cmdline in ways
- * that make htop's identification of the basename in cmdline unreliable.
- * For e.g. /usr/libexec/gdm-session-worker modifies its cmdline to
- * "gdm-session-worker [pam/gdm-autologin]" and htop ends up with
- * proccmdlineBasenameEnd at "gdm-autologin]". This issue could arise with
- * chrome as well as it stores in cmdline its concatenated argument vector,
- * without NUL delimiter between the arguments (which may contain a '/')
- *
- * So if needed, we adjust cmdlineBaseOffset to the previous (if any)
- * component of the cmdline relative path, and retry the procedure. */
- bool delimFound; /* if valid basename delimiter found */
- do {
- /* match basename */
- matchLen = exeBaseLen + cmdlineBaseOffset;
- if (cmdlineBaseOffset < exeBaseOffset &&
- strncmp(cmdline + cmdlineBaseOffset, exe + exeBaseOffset, exeBaseLen) == 0) {
- delim = cmdline[matchLen];
- if (delim == 0 || delim == '\n' || delim == ' ') {
- int i, j;
- /* reverse match the cmdline prefix and exe suffix */
- for (i = cmdlineBaseOffset - 1, j = exeBaseOffset - 1;
- i >= 0 && j >= 0 && cmdline[i] == exe[j]; --i, --j)
- ;
- /* full match, with exe suffix being a valid relative path */
- if (i < 0 && j >= 0 && exe[j] == '/') {
- return matchLen;
- }
- }
- }
-
- /* Try to find the previous potential cmdlineBaseOffset - it would be
- * preceded by '/' or nothing, and delimited by ' ' or '\n' */
- for (delimFound = false, cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) {
- if (delimFound) {
- if (cmdline[cmdlineBaseOffset - 1] == '/') {
- break;
- }
- } else if (cmdline[cmdlineBaseOffset] == ' ' || cmdline[cmdlineBaseOffset] == '\n') {
- delimFound = true;
- }
- }
- } while (delimFound);
-
- return 0;
-}
-
-/* stpcpy, but also converts newlines to spaces */
-static inline char *stpcpyWithNewlineConversion(char *dstStr, const char *srcStr) {
- for (; *srcStr; ++srcStr) {
- *dstStr++ = (*srcStr == '\n') ? ' ' : *srcStr;
- }
- *dstStr = 0;
- return dstStr;
-}
-
-/*
-This function makes the merged Command string. It also stores the offsets of the
-basename, comm w.r.t the merged Command string - these offsets will be used by
-LinuxProcess_writeCommand() for coloring. The merged Command string is also
-returned by LinuxProcess_getCommandStr() for searching, sorting and filtering.
-*/
-void LinuxProcess_makeCommandStr(Process* this) {
- ProcessMergedCommand *mc = &this->mergedCommand;
- const Settings* settings = this->settings;
-
- bool showMergedCommand = settings->showMergedCommand;
- bool showProgramPath = settings->showProgramPath;
- bool searchCommInCmdline = settings->findCommInCmdline;
- bool stripExeFromCmdline = settings->stripExeFromCmdline;
-
- /* lp->mergedCommand.str needs updating only if its state or contents changed.
- * Its content is based on the fields cmdline, comm, and exe. */
- if (
- mc->prevMergeSet == showMergedCommand &&
- mc->prevPathSet == showProgramPath &&
- mc->prevCommSet == searchCommInCmdline &&
- mc->prevCmdlineSet == stripExeFromCmdline &&
- !mc->cmdlineChanged &&
- !mc->commChanged &&
- !mc->exeChanged
- ) {
- return;
- }
-
- /* The field separtor "│" has been chosen such that it will not match any
- * valid string used for searching or filtering */
- const char *SEPARATOR = CRT_treeStr[TREE_STR_VERT];
- const int SEPARATOR_LEN = strlen(SEPARATOR);
-
- /* Check for any changed fields since we last built this string */
- if (mc->cmdlineChanged || mc->commChanged || mc->exeChanged) {
- free(mc->str);
- /* Accommodate the column text, two field separators and terminating NUL */
- mc->str = xCalloc(1, mc->maxLen + 2*SEPARATOR_LEN + 1);
- }
-
- /* Preserve the settings used in this run */
- mc->prevMergeSet = showMergedCommand;
- mc->prevPathSet = showProgramPath;
- mc->prevCommSet = searchCommInCmdline;
- mc->prevCmdlineSet = stripExeFromCmdline;
-
- /* Mark everything as unchanged */
- mc->cmdlineChanged = false;
- mc->commChanged = false;
- mc->exeChanged = false;
-
- /* Reset all locations that need extra handling when actually displaying */
- mc->highlightCount = 0;
- memset(mc->highlights, 0, sizeof(mc->highlights));
-
- size_t mbMismatch = 0;
- #define WRITE_HIGHLIGHT(_offset, _length, _attr, _flags) \
- do { \
- /* Check if we still have capacity */ \
- assert(mc->highlightCount < ARRAYSIZE(mc->highlights)); \
- if (mc->highlightCount >= ARRAYSIZE(mc->highlights)) \
- continue; \
- \
- mc->highlights[mc->highlightCount].offset = str - strStart + _offset - mbMismatch; \
- mc->highlights[mc->highlightCount].length = _length; \
- mc->highlights[mc->highlightCount].attr = _attr; \
- mc->highlights[mc->highlightCount].flags = _flags; \
- mc->highlightCount++; \
- } while (0)
-
- #define WRITE_SEPARATOR \
- do { \
- WRITE_HIGHLIGHT(0, 1, CRT_colors[FAILED_READ], CMDLINE_HIGHLIGHT_FLAG_SEPARATOR); \
- mbMismatch += SEPARATOR_LEN - 1; \
- str = stpcpy(str, SEPARATOR); \
- } while (0)
-
- 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 delAttr = CRT_colors[FAILED_READ];
-
- /* Establish some shortcuts to data we need */
- const char *cmdline = this->cmdline;
- const char *procComm = this->procComm;
- const char *procExe = this->procExe;
-
- char *strStart = mc->str;
- char *str = strStart;
-
- int cmdlineBasenameStart = this->cmdlineBasenameStart;
- int cmdlineBasenameEnd = this->cmdlineBasenameEnd;
-
- if (!cmdline) {
- cmdlineBasenameStart = 0;
- cmdlineBasenameEnd = 0;
- cmdline = "(zombie)";
- }
-
- assert(cmdlineBasenameStart >= 0);
- assert(cmdlineBasenameStart <= (int)strlen(cmdline));
-
- if (!showMergedCommand || !procExe || !procComm) { /* fall back to cmdline */
- if (showMergedCommand && !procExe && procComm && strlen(procComm)) { /* Prefix column with comm */
- if (strncmp(cmdline + cmdlineBasenameStart, procComm, MINIMUM(TASK_COMM_LEN - 1, strlen(procComm))) != 0) {
- WRITE_HIGHLIGHT(0, strlen(procComm), commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
- str = stpcpy(str, procComm);
-
- WRITE_SEPARATOR;
- }
- }
-
- if (showProgramPath) {
- WRITE_HIGHLIGHT(cmdlineBasenameStart, cmdlineBasenameEnd - cmdlineBasenameStart, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
- (void)stpcpyWithNewlineConversion(str, cmdline);
- } else {
- WRITE_HIGHLIGHT(0, cmdlineBasenameEnd - cmdlineBasenameStart, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
- (void)stpcpyWithNewlineConversion(str, cmdline + cmdlineBasenameStart);
- }
-
- return;
- }
-
- int exeLen = strlen(this->procExe);
- int exeBasenameOffset = this->procExeBasenameOffset;
- int exeBasenameLen = exeLen - exeBasenameOffset;
-
- assert(exeBasenameOffset >= 0);
- assert(exeBasenameOffset <= (int)strlen(procExe));
-
- bool haveCommInExe = false;
- if (procExe && procComm) {
- haveCommInExe = strncmp(procExe + exeBasenameOffset, procComm, TASK_COMM_LEN - 1) == 0;
- }
-
- /* Start with copying exe */
- if (showProgramPath) {
- if (haveCommInExe)
- WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
- WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
- if (this->procExeDeleted)
- WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
- str = stpcpy(str, procExe);
- } else {
- if (haveCommInExe)
- WRITE_HIGHLIGHT(0, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
- WRITE_HIGHLIGHT(0, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
- if (this->procExeDeleted)
- WRITE_HIGHLIGHT(0, exeBasenameLen, delAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
- str = stpcpy(str, procExe + exeBasenameOffset);
- }
-
- bool haveCommInCmdline = false;
- int commStart = 0;
- int commEnd = 0;
-
- /* Try to match procComm with procExe's basename: This is reliable (predictable) */
- if (searchCommInCmdline) {
- /* commStart/commEnd will be adjusted later along with cmdline */
- haveCommInCmdline = findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commEnd);
- }
-
- int matchLen = matchCmdlinePrefixWithExeSuffix(cmdline, cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen);
-
- bool haveCommField = false;
-
- if (!haveCommInExe && !haveCommInCmdline && procComm) {
- WRITE_SEPARATOR;
- WRITE_HIGHLIGHT(0, strlen(procComm), commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
- str = stpcpy(str, procComm);
- haveCommField = true;
- }
-
- if (matchLen) {
- /* strip the matched exe prefix */
- cmdline += matchLen;
-
- commStart -= matchLen;
- commEnd -= matchLen;
- }
-
- if (!matchLen || (haveCommField && *cmdline)) {
- /* cmdline will be a separate field */
- WRITE_SEPARATOR;
- }
-
- if (!haveCommInExe && haveCommInCmdline && !haveCommField)
- WRITE_HIGHLIGHT(commStart, commEnd - commStart, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
-
- /* Display cmdline if it hasn't been consumed by procExe */
- if (*cmdline) {
- (void) stpcpyWithNewlineConversion(str, cmdline);
- }
-
- #undef WRITE_SEPARATOR
- #undef WRITE_HIGHLIGHT
-}
-
-static void LinuxProcess_writeCommand(const Process* this, int attr, int baseAttr, RichString* str) {
- (void)baseAttr;
-
- const ProcessMergedCommand *mc = &this->mergedCommand;
-
- int strStart = RichString_size(str);
-
-// int commAttr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_COMM : PROCESS_COMM];
-
- const bool highlightBaseName = this->settings->highlightBaseName;
- const bool highlightSeparator = true;
- const bool highlightDeleted = true;
-
- RichString_appendWide(str, attr, this->mergedCommand.str);
-
- for (size_t i = 0, hlCount = CLAMP(mc->highlightCount, 0, ARRAYSIZE(mc->highlights)); i < hlCount; i++)
- {
- const ProcessCmdlineHighlight* hl = &mc->highlights[i];
-
- if (!hl->length)
- continue;
-
- if (hl->flags & CMDLINE_HIGHLIGHT_FLAG_SEPARATOR)
- if (!highlightSeparator)
- continue;
-
- if (hl->flags & CMDLINE_HIGHLIGHT_FLAG_BASENAME)
- if (!highlightBaseName)
- continue;
-
- if (hl->flags & CMDLINE_HIGHLIGHT_FLAG_DELETED)
- if (!highlightDeleted)
- continue;
-
- RichString_setAttrn(str, hl->attr, strStart + hl->offset, hl->length);
- }
-}
-
static void LinuxProcess_writeCommandField(const Process *this, RichString *str, char *buffer, int n, int attr) {
/* This code is from Process_writeField for COMM, but we invoke
* LinuxProcess_writeCommand to display
@@ -534,7 +182,7 @@ static void LinuxProcess_writeCommandField(const Process *this, RichString *str,
baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
}
if (!this->settings->treeView || this->indent == 0) {
- LinuxProcess_writeCommand(this, attr, baseattr, str);
+ Process_writeCommand(this, attr, baseattr, str);
} else {
char* buf = buffer;
int maxIndent = 0;
@@ -566,7 +214,7 @@ static void LinuxProcess_writeCommandField(const Process *this, RichString *str,
const char* draw = CRT_treeStr[lastItem ? TREE_STR_BEND : TREE_STR_RTEE];
xSnprintf(buf, n, "%s%s ", draw, this->showChildren ? CRT_treeStr[TREE_STR_SHUT] : CRT_treeStr[TREE_STR_OPEN] );
RichString_appendWide(str, CRT_colors[PROCESS_TREE], buffer);
- LinuxProcess_writeCommand(this, attr, baseattr, str);
+ Process_writeCommand(this, attr, baseattr, str);
}
}
diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h
index 90ce7c50..fe9d88e2 100644
--- a/linux/LinuxProcess.h
+++ b/linux/LinuxProcess.h
@@ -119,10 +119,6 @@ IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this);
bool LinuxProcess_setIOPriority(Process* this, Arg ioprio);
-/* This function constructs the string that is displayed by
- * LinuxProcess_writeCommand and also returned by LinuxProcess_getCommandStr */
-void LinuxProcess_makeCommandStr(Process *this);
-
bool Process_isThread(const Process* this);
#endif
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 020fc0a5..ca2f2b80 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -1028,7 +1028,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
for (int i = 0; i < amtRead; i++) {
/* newline used as delimiter - when forming the mergedCommand, newline is
- * converted to space by LinuxProcess_makeCommandStr */
+ * converted to space by Process_makeCommandStr */
if (command[i] == '\0') {
command[i] = '\n';
} else {
@@ -1432,7 +1432,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
if (!Process_isKernelThread(proc) &&
(proc->state != 'Z' || proc->mergedCommand.str) &&
(!Process_isUserlandThread(proc) || !settings->showThreadNames)) {
- LinuxProcess_makeCommandStr(proc);
+ Process_makeCommandStr(proc);
}
#ifdef HAVE_DELAYACCT

© 2014-2024 Faster IT GmbH | imprint | privacy policy