summaryrefslogtreecommitdiffstats
path: root/linux/LinuxProcessList.c
diff options
context:
space:
mode:
authorNarendran Gopalakrishnan <g_narendran142@yahoo.com>2020-10-17 16:24:45 +0530
committerBenBE <BenBE@geshi.org>2020-11-24 19:05:48 +0100
commit09fe94da18d33d2c4e1fe415e8346fa99b9944b4 (patch)
treed5d405e4bfdbbe8e4940ffe92f8b50def3cb6122 /linux/LinuxProcessList.c
parent42c842c190912de58ccf3f41bd58c452c595e40d (diff)
Improving Command display/sort
Diffstat (limited to 'linux/LinuxProcessList.c')
-rw-r--r--linux/LinuxProcessList.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 1cc0a274..498ee0ef 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -875,6 +875,7 @@ static void setCommand(Process* process, const char* command, int len) {
}
static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirname, const char* name) {
+ LinuxProcess *lp = (LinuxProcess *)process;
char filename[MAX_NAME + 1];
xSnprintf(filename, MAX_NAME, "%s/%s/cmdline", dirname, name);
int fd = open(filename, O_RDONLY);
@@ -885,6 +886,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
int amtRead = xread(fd, command, sizeof(command) - 1);
close(fd);
int tokenEnd = 0;
+ int tokenStart = 0;
int lastChar = 0;
if (amtRead == 0) {
if (process->state == 'Z') {
@@ -897,12 +899,23 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
return false;
}
for (int i = 0; i < amtRead; i++) {
- if (command[i] == '\0' || command[i] == '\n') {
+ /* newline used as delimiter - when forming the mergedCommand, newline is
+ * converted to space by LinuxProcess_makeCommandStr */
+ if (command[i] == '\0') {
+ command[i] = '\n';
+ }
+
+ if (command[i] == '\n') {
if (tokenEnd == 0) {
tokenEnd = i;
}
- command[i] = ' ';
} else {
+ /* htop considers the next character after the last / that is before
+ * basenameOffset, as the start of the basename in cmdline - see
+ * Process_writeCommand */
+ if (!tokenEnd && command[i] == '/') {
+ tokenStart = i + 1;
+ }
lastChar = i;
}
}
@@ -910,8 +923,55 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
tokenEnd = amtRead;
}
command[lastChar + 1] = '\0';
- process->basenameOffset = tokenEnd;
- setCommand(process, command, lastChar + 1);
+ lp->mergedCommand.maxLen = lastChar + 1; /* accomodate cmdline */
+ if (!process->comm || strcmp(command, process->comm)) {
+ process->basenameOffset = tokenEnd;
+ setCommand(process, command, lastChar + 1);
+ lp->procCmdlineBasenameOffset = tokenStart;
+ lp->procCmdlineBasenameEnd = tokenEnd;
+ lp->mergedCommand.cmdlineChanged = true;
+ }
+
+ /* /proc/[pid]/comm could change, so should be udpated */
+ xSnprintf(filename, MAX_NAME, "%s/%s/comm", dirname, name);
+ if ((fd = open(filename, O_RDONLY)) != -1 &&
+ (amtRead = xread(fd, command, sizeof(command) - 1)) > 0) {
+ close(fd);
+ command[amtRead - 1] = 0;
+ lp->mergedCommand.maxLen += amtRead - 1; /* accomodate comm */
+ if (!lp->procComm || strcmp(command, lp->procComm)) {
+ free(lp->procComm);
+ lp->procComm = xStrdup(command);
+ lp->mergedCommand.commChanged = true;
+ }
+ } else if (lp->procComm) {
+ free(lp->procComm);
+ lp->procComm = NULL;
+ lp->mergedCommand.commChanged = true;
+ }
+
+ /* execve could change /proc/[pid]/exe, so procExe should be udpated */
+ xSnprintf(command, sizeof(command), "%s/%s/exe", dirname, name);
+ if ((amtRead = readlink(command, filename, sizeof(filename) - 1)) > 0) {
+ filename[amtRead] = 0;
+ lp->mergedCommand.maxLen += amtRead; /* accomodate exe */
+ if (!lp->procExe || strcmp(filename, lp->procExe)) {
+ free(lp->procExe);
+ lp->procExe = xStrdup(filename);
+ lp->procExeLen = amtRead;
+ /* exe is guaranteed to contain at least one /, but validate anyway */
+ while (amtRead && filename[--amtRead] != '/')
+ ;
+ lp->procExeBasenameOffset = amtRead + 1;
+ lp->mergedCommand.exeChanged = true;
+ }
+ } else if (lp->procExe) {
+ free(lp->procExe);
+ lp->procExe = NULL;
+ lp->procExeLen = 0;
+ lp->procExeBasenameOffset = 0;
+ lp->mergedCommand.exeChanged = true;
+ }
return true;
}
@@ -1121,6 +1181,15 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
}
}
}
+ /* (Re)Generate the Command string, but only if the process is:
+ * - not a kernel thread, and
+ * - not a zombie or it became zombie under htop's watch, and
+ * - not a user thread or if showThreadNames is not set */
+ if (!Process_isKernelThread(proc) &&
+ (proc->state != 'Z' || lp->mergedCommand.str) &&
+ (!Process_isUserlandThread(proc) || !settings->showThreadNames)) {
+ LinuxProcess_makeCommandStr(proc);
+ }
#ifdef HAVE_DELAYACCT
LinuxProcessList_readDelayAcctData(this, lp);

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