mirror of https://github.com/xzeldon/htop.git
Move mergeCommand to global process struct
This commit is contained in:
parent
94a52cb5c9
commit
cdb660adab
|
@ -517,6 +517,7 @@ void Process_done(Process* this) {
|
||||||
free(this->cmdline);
|
free(this->cmdline);
|
||||||
free(this->procComm);
|
free(this->procComm);
|
||||||
free(this->procExe);
|
free(this->procExe);
|
||||||
|
free(this->mergedCommand.str);
|
||||||
free(this->tty_name);
|
free(this->tty_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
Process.h
34
Process.h
|
@ -55,6 +55,35 @@ typedef enum ProcessField_ {
|
||||||
|
|
||||||
struct Settings_;
|
struct Settings_;
|
||||||
|
|
||||||
|
/* Holds information about regions of the cmdline that should be
|
||||||
|
* highlighted (e.g. program basename, delimiter, comm). */
|
||||||
|
typedef struct ProcessCmdlineHighlight_ {
|
||||||
|
size_t offset; /* first character to highlight */
|
||||||
|
size_t length; /* How many characters to highlight, zero if unused */
|
||||||
|
int attr; /* The attributes used to highlight */
|
||||||
|
int flags; /* Special flags used for selective highlighting, zero for always */
|
||||||
|
} ProcessCmdlineHighlight;
|
||||||
|
|
||||||
|
/* ProcessMergedCommand is populated by Process_makeCommandStr: It
|
||||||
|
* contains the merged Command string, and the information needed by
|
||||||
|
* Process_writeCommand to color the string. str will be NULL for kernel
|
||||||
|
* threads and zombies */
|
||||||
|
typedef struct ProcessMergedCommand_ {
|
||||||
|
char *str; /* merged Command string */
|
||||||
|
size_t maxLen; /* maximum expected length of Command string */
|
||||||
|
size_t highlightCount; /* how many portions of cmdline to highlight */
|
||||||
|
ProcessCmdlineHighlight highlights[8]; /* which portions of cmdline to highlight */
|
||||||
|
bool separateComm : 1; /* whether comm is a separate field */
|
||||||
|
bool unmatchedExe : 1; /* whether exe matched with cmdline */
|
||||||
|
bool cmdlineChanged : 1; /* whether cmdline changed */
|
||||||
|
bool exeChanged : 1; /* whether exe changed */
|
||||||
|
bool commChanged : 1; /* whether comm changed */
|
||||||
|
bool prevMergeSet : 1; /* whether showMergedCommand was set */
|
||||||
|
bool prevPathSet : 1; /* whether showProgramPath was set */
|
||||||
|
bool prevCommSet : 1; /* whether findCommInCmdline was set */
|
||||||
|
bool prevCmdlineSet : 1; /* whether stripExeFromCmdline was set */
|
||||||
|
} ProcessMergedCommand;
|
||||||
|
|
||||||
typedef struct Process_ {
|
typedef struct Process_ {
|
||||||
/* Super object for emulated OOP */
|
/* Super object for emulated OOP */
|
||||||
Object super;
|
Object super;
|
||||||
|
@ -200,6 +229,11 @@ typedef struct Process_ {
|
||||||
unsigned int tree_right;
|
unsigned int tree_right;
|
||||||
unsigned int tree_depth;
|
unsigned int tree_depth;
|
||||||
unsigned int tree_index;
|
unsigned int tree_index;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal state for merged Command display
|
||||||
|
*/
|
||||||
|
ProcessMergedCommand mergedCommand;
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
typedef struct ProcessFieldData_ {
|
typedef struct ProcessFieldData_ {
|
||||||
|
|
|
@ -108,11 +108,11 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
|
||||||
* happens on what is displayed - whether comm, full path, basename, etc.. So
|
* happens on what is displayed - whether comm, full path, basename, etc.. So
|
||||||
* this follows LinuxProcess_writeField(COMM) and LinuxProcess_writeCommand */
|
* this follows LinuxProcess_writeField(COMM) and LinuxProcess_writeCommand */
|
||||||
static const char* LinuxProcess_getCommandStr(const Process *this) {
|
static const char* LinuxProcess_getCommandStr(const Process *this) {
|
||||||
const LinuxProcess *lp = (const LinuxProcess *)this;
|
if ((Process_isUserlandThread(this) && this->settings->showThreadNames) || !this->mergedCommand.str) {
|
||||||
if ((Process_isUserlandThread(this) && this->settings->showThreadNames) || !lp->mergedCommand.str) {
|
|
||||||
return this->cmdline;
|
return this->cmdline;
|
||||||
}
|
}
|
||||||
return lp->mergedCommand.str;
|
|
||||||
|
return this->mergedCommand.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* LinuxProcess_new(const Settings* settings) {
|
Process* LinuxProcess_new(const Settings* settings) {
|
||||||
|
@ -131,7 +131,6 @@ void Process_delete(Object* cast) {
|
||||||
#endif
|
#endif
|
||||||
free(this->cwd);
|
free(this->cwd);
|
||||||
free(this->secattr);
|
free(this->secattr);
|
||||||
free(this->mergedCommand.str);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +306,7 @@ LinuxProcess_writeCommand() for coloring. The merged Command string is also
|
||||||
returned by LinuxProcess_getCommandStr() for searching, sorting and filtering.
|
returned by LinuxProcess_getCommandStr() for searching, sorting and filtering.
|
||||||
*/
|
*/
|
||||||
void LinuxProcess_makeCommandStr(Process* this) {
|
void LinuxProcess_makeCommandStr(Process* this) {
|
||||||
LinuxProcess *lp = (LinuxProcess *)this;
|
ProcessMergedCommand *mc = &this->mergedCommand;
|
||||||
LinuxProcessMergedCommand *mc = &lp->mergedCommand;
|
|
||||||
const Settings* settings = this->settings;
|
const Settings* settings = this->settings;
|
||||||
|
|
||||||
bool showMergedCommand = settings->showMergedCommand;
|
bool showMergedCommand = settings->showMergedCommand;
|
||||||
|
@ -502,8 +500,7 @@ void LinuxProcess_makeCommandStr(Process* this) {
|
||||||
static void LinuxProcess_writeCommand(const Process* this, int attr, int baseAttr, RichString* str) {
|
static void LinuxProcess_writeCommand(const Process* this, int attr, int baseAttr, RichString* str) {
|
||||||
(void)baseAttr;
|
(void)baseAttr;
|
||||||
|
|
||||||
const LinuxProcess *lp = (const LinuxProcess *)this;
|
const ProcessMergedCommand *mc = &this->mergedCommand;
|
||||||
const LinuxProcessMergedCommand *mc = &lp->mergedCommand;
|
|
||||||
|
|
||||||
int strStart = RichString_size(str);
|
int strStart = RichString_size(str);
|
||||||
|
|
||||||
|
@ -513,11 +510,11 @@ static void LinuxProcess_writeCommand(const Process* this, int attr, int baseAtt
|
||||||
const bool highlightSeparator = true;
|
const bool highlightSeparator = true;
|
||||||
const bool highlightDeleted = true;
|
const bool highlightDeleted = true;
|
||||||
|
|
||||||
RichString_appendWide(str, attr, lp->mergedCommand.str);
|
RichString_appendWide(str, attr, this->mergedCommand.str);
|
||||||
|
|
||||||
for (size_t i = 0, hlCount = CLAMP(mc->highlightCount, 0, ARRAYSIZE(mc->highlights)); i < hlCount; i++)
|
for (size_t i = 0, hlCount = CLAMP(mc->highlightCount, 0, ARRAYSIZE(mc->highlights)); i < hlCount; i++)
|
||||||
{
|
{
|
||||||
const LinuxProcessCmdlineHighlight* hl = &mc->highlights[i];
|
const ProcessCmdlineHighlight* hl = &mc->highlights[i];
|
||||||
|
|
||||||
if (!hl->length)
|
if (!hl->length)
|
||||||
continue;
|
continue;
|
||||||
|
@ -674,7 +671,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
||||||
break;
|
break;
|
||||||
case SECATTR: snprintf(buffer, n, "%-30s ", lp->secattr ? lp->secattr : "?"); break;
|
case SECATTR: snprintf(buffer, n, "%-30s ", lp->secattr ? lp->secattr : "?"); break;
|
||||||
case COMM: {
|
case COMM: {
|
||||||
if ((Process_isUserlandThread(this) && this->settings->showThreadNames) || !lp->mergedCommand.str) {
|
if ((Process_isUserlandThread(this) && this->settings->showThreadNames) || !this->mergedCommand.str) {
|
||||||
Process_writeField(this, str, field);
|
Process_writeField(this, str, field);
|
||||||
} else {
|
} else {
|
||||||
LinuxProcess_writeCommandField(this, str, buffer, n, attr);
|
LinuxProcess_writeCommandField(this, str, buffer, n, attr);
|
||||||
|
|
|
@ -30,40 +30,8 @@ in the source distribution for its full text.
|
||||||
#define PROCESS_FLAG_LINUX_CWD 0x00020000
|
#define PROCESS_FLAG_LINUX_CWD 0x00020000
|
||||||
#define PROCESS_FLAG_LINUX_DELAYACCT 0x00040000
|
#define PROCESS_FLAG_LINUX_DELAYACCT 0x00040000
|
||||||
|
|
||||||
|
|
||||||
/* Holds information about regions of the cmdline that should be
|
|
||||||
* highlighted (e.g. program basename, delimiter, comm). */
|
|
||||||
typedef struct LinuxProcessCmdlineHighlight_
|
|
||||||
{
|
|
||||||
size_t offset; /* first character to highlight */
|
|
||||||
size_t length; /* How many characters to highlight, zero if unused */
|
|
||||||
int attr; /* The attributes used to highlight */
|
|
||||||
int flags; /* Special flags used for selective highlighting, zero for always */
|
|
||||||
} LinuxProcessCmdlineHighlight;
|
|
||||||
|
|
||||||
/* LinuxProcessMergedCommand is populated by LinuxProcess_makeCommandStr: It
|
|
||||||
* contains the merged Command string, and the information needed by
|
|
||||||
* LinuxProcess_writeCommand to color the string. str will be NULL for kernel
|
|
||||||
* threads and zombies */
|
|
||||||
typedef struct LinuxProcessMergedCommand_ {
|
|
||||||
char *str; /* merged Command string */
|
|
||||||
size_t maxLen; /* maximum expected length of Command string */
|
|
||||||
size_t highlightCount; /* how many portions of cmdline to highlight */
|
|
||||||
LinuxProcessCmdlineHighlight highlights[8]; /* which portions of cmdline to highlight */
|
|
||||||
bool separateComm : 1; /* whether comm is a separate field */
|
|
||||||
bool unmatchedExe : 1; /* whether exe matched with cmdline */
|
|
||||||
bool cmdlineChanged : 1; /* whether cmdline changed */
|
|
||||||
bool exeChanged : 1; /* whether exe changed */
|
|
||||||
bool commChanged : 1; /* whether comm changed */
|
|
||||||
bool prevMergeSet : 1; /* whether showMergedCommand was set */
|
|
||||||
bool prevPathSet : 1; /* whether showProgramPath was set */
|
|
||||||
bool prevCommSet : 1; /* whether findCommInCmdline was set */
|
|
||||||
bool prevCmdlineSet : 1; /* whether stripExeFromCmdline was set */
|
|
||||||
} LinuxProcessMergedCommand;
|
|
||||||
|
|
||||||
typedef struct LinuxProcess_ {
|
typedef struct LinuxProcess_ {
|
||||||
Process super;
|
Process super;
|
||||||
LinuxProcessMergedCommand mergedCommand;
|
|
||||||
bool isKernelThread;
|
bool isKernelThread;
|
||||||
IOPriority ioPriority;
|
IOPriority ioPriority;
|
||||||
unsigned long int cminflt;
|
unsigned long int cminflt;
|
||||||
|
|
|
@ -1130,27 +1130,27 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
|
||||||
tokenEnd = lastChar + 1;
|
tokenEnd = lastChar + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxProcess *lp = (LinuxProcess *)process;
|
ProcessMergedCommand *mc = &process->mergedCommand;
|
||||||
lp->mergedCommand.maxLen = lastChar + 1; /* accommodate cmdline */
|
mc->maxLen = lastChar + 1; /* accommodate cmdline */
|
||||||
if (!process->cmdline || !String_eq(command, process->cmdline)) {
|
if (!process->cmdline || !String_eq(command, process->cmdline)) {
|
||||||
free_and_xStrdup(&process->cmdline, command);
|
free_and_xStrdup(&process->cmdline, command);
|
||||||
process->cmdlineBasenameStart = tokenStart;
|
process->cmdlineBasenameStart = tokenStart;
|
||||||
process->cmdlineBasenameEnd = tokenEnd;
|
process->cmdlineBasenameEnd = tokenEnd;
|
||||||
lp->mergedCommand.cmdlineChanged = true;
|
mc->cmdlineChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /proc/[pid]/comm could change, so should be updated */
|
/* /proc/[pid]/comm could change, so should be updated */
|
||||||
if ((amtRead = xReadfileat(procFd, "comm", command, sizeof(command))) > 0) {
|
if ((amtRead = xReadfileat(procFd, "comm", command, sizeof(command))) > 0) {
|
||||||
command[amtRead - 1] = '\0';
|
command[amtRead - 1] = '\0';
|
||||||
lp->mergedCommand.maxLen += amtRead - 1; /* accommodate comm */
|
mc->maxLen += amtRead - 1; /* accommodate comm */
|
||||||
if (!process->procComm || !String_eq(command, process->procComm)) {
|
if (!process->procComm || !String_eq(command, process->procComm)) {
|
||||||
free_and_xStrdup(&process->procComm, command);
|
free_and_xStrdup(&process->procComm, command);
|
||||||
lp->mergedCommand.commChanged = true;
|
mc->commChanged = true;
|
||||||
}
|
}
|
||||||
} else if (process->procComm) {
|
} else if (process->procComm) {
|
||||||
free(process->procComm);
|
free(process->procComm);
|
||||||
process->procComm = NULL;
|
process->procComm = NULL;
|
||||||
lp->mergedCommand.commChanged = true;
|
mc->commChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char filename[MAX_NAME + 1];
|
char filename[MAX_NAME + 1];
|
||||||
|
@ -1165,7 +1165,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
|
||||||
#endif
|
#endif
|
||||||
if (amtRead > 0) {
|
if (amtRead > 0) {
|
||||||
filename[amtRead] = 0;
|
filename[amtRead] = 0;
|
||||||
lp->mergedCommand.maxLen += amtRead; /* accommodate exe */
|
mc->maxLen += amtRead; /* accommodate exe */
|
||||||
if (!process->procExe ||
|
if (!process->procExe ||
|
||||||
(!process->procExeDeleted && !String_eq(filename, process->procExe)) ||
|
(!process->procExeDeleted && !String_eq(filename, process->procExe)) ||
|
||||||
(process->procExeDeleted && !String_startsWith(filename, process->procExe))) {
|
(process->procExeDeleted && !String_startsWith(filename, process->procExe))) {
|
||||||
|
@ -1176,7 +1176,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
|
||||||
;
|
;
|
||||||
|
|
||||||
process->procExeBasenameOffset = amtRead + 1;
|
process->procExeBasenameOffset = amtRead + 1;
|
||||||
lp->mergedCommand.exeChanged = true;
|
mc->exeChanged = true;
|
||||||
|
|
||||||
const char* deletedMarker = " (deleted)";
|
const char* deletedMarker = " (deleted)";
|
||||||
if (strlen(process->procExe) > strlen(deletedMarker)) {
|
if (strlen(process->procExe) > strlen(deletedMarker)) {
|
||||||
|
@ -1195,7 +1195,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc
|
||||||
process->procExe = NULL;
|
process->procExe = NULL;
|
||||||
process->procExeBasenameOffset = 0;
|
process->procExeBasenameOffset = 0;
|
||||||
process->procExeDeleted = false;
|
process->procExeDeleted = false;
|
||||||
lp->mergedCommand.exeChanged = true;
|
mc->exeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1429,7 +1429,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
* - not a zombie or it became zombie under htop's watch, and
|
* - not a zombie or it became zombie under htop's watch, and
|
||||||
* - not a user thread or if showThreadNames is not set */
|
* - not a user thread or if showThreadNames is not set */
|
||||||
if (!Process_isKernelThread(proc) &&
|
if (!Process_isKernelThread(proc) &&
|
||||||
(proc->state != 'Z' || lp->mergedCommand.str) &&
|
(proc->state != 'Z' || proc->mergedCommand.str) &&
|
||||||
(!Process_isUserlandThread(proc) || !settings->showThreadNames)) {
|
(!Process_isUserlandThread(proc) || !settings->showThreadNames)) {
|
||||||
LinuxProcess_makeCommandStr(proc);
|
LinuxProcess_makeCommandStr(proc);
|
||||||
}
|
}
|
||||||
|
@ -1464,13 +1464,13 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
proc->cmdlineBasenameEnd = -1;
|
proc->cmdlineBasenameEnd = -1;
|
||||||
free_and_xStrdup(&proc->cmdline, command);
|
free_and_xStrdup(&proc->cmdline, command);
|
||||||
proc->cmdlineBasenameStart = 0;
|
proc->cmdlineBasenameStart = 0;
|
||||||
lp->mergedCommand.commChanged = true;
|
proc->mergedCommand.commChanged = true;
|
||||||
} else if (Process_isThread(proc)) {
|
} else if (Process_isThread(proc)) {
|
||||||
if (settings->showThreadNames || Process_isKernelThread(proc)) {
|
if (settings->showThreadNames || Process_isKernelThread(proc)) {
|
||||||
proc->cmdlineBasenameEnd = -1;
|
proc->cmdlineBasenameEnd = -1;
|
||||||
free_and_xStrdup(&proc->cmdline, command);
|
free_and_xStrdup(&proc->cmdline, command);
|
||||||
proc->cmdlineBasenameStart = 0;
|
proc->cmdlineBasenameStart = 0;
|
||||||
lp->mergedCommand.commChanged = true;
|
proc->mergedCommand.commChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Process_isKernelThread(proc)) {
|
if (Process_isKernelThread(proc)) {
|
||||||
|
|
Loading…
Reference in New Issue