mirror of https://github.com/xzeldon/htop.git
Add Linux cwd process column
This commit is contained in:
parent
c6b66a75ea
commit
fe84840314
|
@ -115,6 +115,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
[SECATTR] = { .name = "SECATTR", .title = " Security Attribute ", .description = "Security attribute of the process (e.g. SELinux or AppArmor)", .flags = PROCESS_FLAG_LINUX_SECATTR, },
|
[SECATTR] = { .name = "SECATTR", .title = " Security Attribute ", .description = "Security attribute of the process (e.g. SELinux or AppArmor)", .flags = PROCESS_FLAG_LINUX_SECATTR, },
|
||||||
[PROC_COMM] = { .name = "COMM", .title = "COMM ", .description = "comm string of the process from /proc/[pid]/comm", .flags = 0, },
|
[PROC_COMM] = { .name = "COMM", .title = "COMM ", .description = "comm string of the process from /proc/[pid]/comm", .flags = 0, },
|
||||||
[PROC_EXE] = { .name = "EXE", .title = "EXE ", .description = "Basename of exe of the process from /proc/[pid]/exe", .flags = 0, },
|
[PROC_EXE] = { .name = "EXE", .title = "EXE ", .description = "Basename of exe of the process from /proc/[pid]/exe", .flags = 0, },
|
||||||
|
[CWD] = { .name ="CWD", .title = "CWD ", .description = "The current working directory of the process", .flags = PROCESS_FLAG_LINUX_CWD, },
|
||||||
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
|
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,6 +157,7 @@ void Process_delete(Object* cast) {
|
||||||
#ifdef HAVE_OPENVZ
|
#ifdef HAVE_OPENVZ
|
||||||
free(this->ctid);
|
free(this->ctid);
|
||||||
#endif
|
#endif
|
||||||
|
free(this->cwd);
|
||||||
free(this->secattr);
|
free(this->secattr);
|
||||||
free(this->ttyDevice);
|
free(this->ttyDevice);
|
||||||
free(this->procExe);
|
free(this->procExe);
|
||||||
|
@ -739,6 +741,17 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CWD:
|
||||||
|
if (!lp->cwd) {
|
||||||
|
xSnprintf(buffer, n, "%-25s ", "N/A");
|
||||||
|
attr = CRT_colors[PROCESS_SHADOW];
|
||||||
|
} else if (String_startsWith(lp->cwd, "/proc/") && strstr(lp->cwd, " (deleted)") != NULL) {
|
||||||
|
xSnprintf(buffer, n, "%-25s ", "main thread terminated");
|
||||||
|
attr = CRT_colors[PROCESS_SHADOW];
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, n, "%-25.25s ", lp->cwd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Process_writeField(this, str, field);
|
Process_writeField(this, str, field);
|
||||||
return;
|
return;
|
||||||
|
@ -841,6 +854,8 @@ static long LinuxProcess_compare(const void* v1, const void* v2) {
|
||||||
const char *exe2 = p2->procExe ? (p2->procExe + p2->procExeBasenameOffset) : (Process_isKernelThread(p2) ? kthreadID : "");
|
const char *exe2 = p2->procExe ? (p2->procExe + p2->procExeBasenameOffset) : (Process_isKernelThread(p2) ? kthreadID : "");
|
||||||
return strcmp(exe1, exe2);
|
return strcmp(exe1, exe2);
|
||||||
}
|
}
|
||||||
|
case CWD:
|
||||||
|
return SPACESHIP_NULLSTR(p1->cwd, p2->cwd);
|
||||||
default:
|
default:
|
||||||
return Process_compare(v1, v2);
|
return Process_compare(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ in the source distribution for its full text.
|
||||||
#define PROCESS_FLAG_LINUX_CTXT 0x00004000
|
#define PROCESS_FLAG_LINUX_CTXT 0x00004000
|
||||||
#define PROCESS_FLAG_LINUX_SECATTR 0x00008000
|
#define PROCESS_FLAG_LINUX_SECATTR 0x00008000
|
||||||
#define PROCESS_FLAG_LINUX_LRS_FIX 0x00010000
|
#define PROCESS_FLAG_LINUX_LRS_FIX 0x00010000
|
||||||
|
#define PROCESS_FLAG_LINUX_CWD 0x00020000
|
||||||
|
|
||||||
typedef enum UnsupportedProcessFields {
|
typedef enum UnsupportedProcessFields {
|
||||||
FLAGS = 9,
|
FLAGS = 9,
|
||||||
|
@ -94,7 +95,8 @@ typedef enum LinuxProcessFields {
|
||||||
SECATTR = 123,
|
SECATTR = 123,
|
||||||
PROC_COMM = 124,
|
PROC_COMM = 124,
|
||||||
PROC_EXE = 125,
|
PROC_EXE = 125,
|
||||||
LAST_PROCESSFIELD = 126,
|
CWD = 126,
|
||||||
|
LAST_PROCESSFIELD = 127,
|
||||||
} LinuxProcessField;
|
} LinuxProcessField;
|
||||||
|
|
||||||
/* LinuxProcessMergedCommand is populated by LinuxProcess_makeCommandStr: It
|
/* LinuxProcessMergedCommand is populated by LinuxProcess_makeCommandStr: It
|
||||||
|
@ -181,6 +183,7 @@ typedef struct LinuxProcess_ {
|
||||||
unsigned long ctxt_diff;
|
unsigned long ctxt_diff;
|
||||||
char* secattr;
|
char* secattr;
|
||||||
unsigned long long int last_mlrs_calctime;
|
unsigned long long int last_mlrs_calctime;
|
||||||
|
char* cwd;
|
||||||
} LinuxProcess;
|
} LinuxProcess;
|
||||||
|
|
||||||
#define Process_isKernelThread(_process) (((const LinuxProcess*)(_process))->isKernelThread)
|
#define Process_isKernelThread(_process) (((const LinuxProcess*)(_process))->isKernelThread)
|
||||||
|
|
|
@ -882,6 +882,31 @@ static void LinuxProcessList_readSecattrData(LinuxProcess* process, openat_arg_t
|
||||||
process->secattr = xStrdup(buffer);
|
process->secattr = xStrdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd) {
|
||||||
|
char pathBuffer[PATH_MAX + 1];
|
||||||
|
|
||||||
|
#if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT)
|
||||||
|
ssize_t r = readlinkat(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1);
|
||||||
|
#else
|
||||||
|
char filename[MAX_NAME + 1];
|
||||||
|
xSnprintf(filename, sizeof(filename), "%s/cwd", procFd);
|
||||||
|
ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1);
|
||||||
|
#endif
|
||||||
|
if (r < 0) {
|
||||||
|
free(process->cwd);
|
||||||
|
process->cwd = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathBuffer[r] = '\0';
|
||||||
|
|
||||||
|
if (process->cwd && String_eq(process->cwd, pathBuffer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(process->cwd);
|
||||||
|
process->cwd = xStrdup(pathBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DELAYACCT
|
#ifdef HAVE_DELAYACCT
|
||||||
|
|
||||||
static int handleNetlinkMsg(struct nl_msg* nlmsg, void* linuxProcess) {
|
static int handleNetlinkMsg(struct nl_msg* nlmsg, void* linuxProcess) {
|
||||||
|
@ -1404,6 +1429,10 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
LinuxProcessList_readSecattrData(lp, procFd);
|
LinuxProcessList_readSecattrData(lp, procFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings->flags & PROCESS_FLAG_LINUX_CWD) {
|
||||||
|
LinuxProcessList_readCwd(lp, procFd);
|
||||||
|
}
|
||||||
|
|
||||||
if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
|
if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
|
||||||
proc->basenameOffset = -1;
|
proc->basenameOffset = -1;
|
||||||
setCommand(proc, command, commLen);
|
setCommand(proc, command, commLen);
|
||||||
|
|
Loading…
Reference in New Issue