From 9a8221568ada269d20c3e9d291ad5f9d07cac755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sun, 21 Mar 2021 19:40:56 +0100 Subject: [PATCH] Rework TTY column * Rename internal identifier from TTY_NR to just TTY * Unify column header on platforms * Use devname(3) on BSD derivate to show the actual terminal, simplifies current FreeBSD implementation. * Use 'unsigned long int' as id type, to fit dev_t on Linux. Only on Solaris the terminal path is not yet resolved. --- Macros.h | 16 +++-- Process.c | 18 +++--- Process.h | 12 ++-- darwin/DarwinProcess.c | 14 +++-- dragonflybsd/DragonFlyBSDProcess.c | 2 +- dragonflybsd/DragonFlyBSDProcessList.c | 10 ++- freebsd/FreeBSDProcess.c | 14 +---- freebsd/FreeBSDProcess.h | 5 -- freebsd/FreeBSDProcessList.c | 87 +++----------------------- freebsd/FreeBSDProcessList.h | 2 - htop.1.in | 2 +- linux/LinuxProcess.c | 11 +--- linux/LinuxProcess.h | 1 - linux/LinuxProcessList.c | 8 +-- openbsd/OpenBSDProcess.c | 6 +- openbsd/OpenBSDProcessList.c | 10 ++- solaris/SolarisProcess.c | 2 +- unsupported/UnsupportedProcess.c | 2 +- unsupported/UnsupportedProcessList.c | 1 + 19 files changed, 76 insertions(+), 147 deletions(-) diff --git a/Macros.h b/Macros.h index 736d31c5..789b09b6 100644 --- a/Macros.h +++ b/Macros.h @@ -4,27 +4,31 @@ #include // IWYU pragma: keep #ifndef MINIMUM -#define MINIMUM(a, b) ((a) < (b) ? (a) : (b)) +#define MINIMUM(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAXIMUM -#define MAXIMUM(a, b) ((a) > (b) ? (a) : (b)) +#define MAXIMUM(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef CLAMP -#define CLAMP(x, low, high) (assert((low) <= (high)), ((x) > (high)) ? (high) : MAXIMUM(x, low)) +#define CLAMP(x, low, high) (assert((low) <= (high)), ((x) > (high)) ? (high) : MAXIMUM(x, low)) #endif #ifndef ARRAYSIZE -#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) #endif #ifndef SPACESHIP_NUMBER -#define SPACESHIP_NUMBER(a, b) (((a) > (b)) - ((a) < (b))) +#define SPACESHIP_NUMBER(a, b) (((a) > (b)) - ((a) < (b))) #endif #ifndef SPACESHIP_NULLSTR -#define SPACESHIP_NULLSTR(a, b) strcmp((a) ? (a) : "", (b) ? (b) : "") +#define SPACESHIP_NULLSTR(a, b) strcmp((a) ? (a) : "", (b) ? (b) : "") +#endif + +#ifndef SPACESHIP_DEFAULTSTR +#define SPACESHIP_DEFAULTSTR(a, b, s) strcmp((a) ? (a) : (s), (b) ? (b) : (s)) #endif #ifdef __GNUC__ // defined by GCC and Clang diff --git a/Process.c b/Process.c index e7431cec..9575ed66 100644 --- a/Process.c +++ b/Process.c @@ -378,17 +378,15 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->tgid); break; case TPGID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, this->tpgid); break; - case TTY_NR: { - unsigned int major = major(this->tty_nr); - unsigned int minor = minor(this->tty_nr); - if (major == 0 && minor == 0) { + case TTY: + if (!this->tty_name) { attr = CRT_colors[PROCESS_SHADOW]; - xSnprintf(buffer, n, "(none) "); + xSnprintf(buffer, n, "(no tty) "); } else { - xSnprintf(buffer, n, "%3u:%3u ", major, minor); + const char* name = String_startsWith(this->tty_name, "/dev/") ? (this->tty_name + strlen("/dev/")) : this->tty_name; + xSnprintf(buffer, n, "%-8s ", name); } break; - } case USER: if (Process_getuid != this->st_uid) attr = CRT_colors[PROCESS_SHADOW]; @@ -435,6 +433,7 @@ void Process_display(const Object* cast, RichString* out) { void Process_done(Process* this) { assert (this != NULL); free(this->comm); + free(this->tty_name); } static const char* Process_getCommandStr(const Process* p) { @@ -612,8 +611,9 @@ int Process_compareByKey_Base(const Process* p1, const Process* p2, ProcessField return SPACESHIP_NUMBER(p1->tgid, p2->tgid); case TPGID: return SPACESHIP_NUMBER(p1->tpgid, p2->tpgid); - case TTY_NR: - return SPACESHIP_NUMBER(p1->tty_nr, p2->tty_nr); + case TTY: + /* Order no tty last */ + return SPACESHIP_DEFAULTSTR(p1->tty_name, p2->tty_name, "\x7F"); case USER: return SPACESHIP_NULLSTR(p1->user, p2->user); default: diff --git a/Process.h b/Process.h index 72197963..a0bdea74 100644 --- a/Process.h +++ b/Process.h @@ -28,7 +28,7 @@ typedef enum ProcessField_ { PPID = 4, PGRP = 5, SESSION = 6, - TTY_NR = 7, + TTY = 7, TPGID = 8, MINFLT = 10, MAJFLT = 12, @@ -84,11 +84,11 @@ typedef struct Process_ { /* Foreground group identifier of the controlling terminal */ int tpgid; - /* - * Controlling terminal of the process. - * The minor device number is contained in the combination of bits 31 to 20 and 7 to 0; the major device number is in bits 15 to 8. - * */ - unsigned int tty_nr; + /* Controlling terminal identifier of the process */ + unsigned long int tty_nr; + + /* Controlling terminal name of the process */ + char* tty_name; /* User identifier */ uid_t st_uid; diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index dea7f904..810b1fa0 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -26,7 +26,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, @@ -272,11 +272,17 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, proc->tpgid = ps->kp_eproc.e_tpgid; proc->tgid = proc->pid; proc->st_uid = ps->kp_eproc.e_ucred.cr_uid; - /* e_tdev = (major << 24) | (minor & 0xffffff) */ - /* e_tdev == -1 for "no device" */ - proc->tty_nr = ps->kp_eproc.e_tdev & 0xff; /* TODO tty_nr is unsigned */ dp->translated = ps->kp_proc.p_flag & P_TRANSLATED; + proc->tty_nr = ps->kp_eproc.e_tdev; + const char* name = (ps->kp_eproc.e_tdev != NODEV) ? devname(ps->kp_eproc.e_tdev, S_IFCHR) : NULL; + if (!name) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } + proc->starttime_ctime = ep->p_starttime.tv_sec; Process_fillStarttimeBuffer(proc); diff --git a/dragonflybsd/DragonFlyBSDProcess.c b/dragonflybsd/DragonFlyBSDProcess.c index 6acc0d48..9b30a334 100644 --- a/dragonflybsd/DragonFlyBSDProcess.c +++ b/dragonflybsd/DragonFlyBSDProcess.c @@ -26,7 +26,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, diff --git a/dragonflybsd/DragonFlyBSDProcessList.c b/dragonflybsd/DragonFlyBSDProcessList.c index 79c8f886..935444e3 100644 --- a/dragonflybsd/DragonFlyBSDProcessList.c +++ b/dragonflybsd/DragonFlyBSDProcessList.c @@ -396,12 +396,20 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc->tgid = kproc->kp_pid; // thread group id proc->pgrp = kproc->kp_pgid; // process group id proc->session = kproc->kp_sid; - proc->tty_nr = kproc->kp_tdev; // control terminal device number proc->st_uid = kproc->kp_uid; // user ID proc->processor = kproc->kp_lwp.kl_origcpu; proc->starttime_ctime = kproc->kp_start.tv_sec; proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); + proc->tty_nr = kproc->kp_tdev; // control terminal device number + const char* name = (kproc->kp_tdev != NODEV) ? devname(kproc->kp_tdev, S_IFCHR) : NULL; + if (!name) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } + ProcessList_add(super, proc); proc->comm = DragonFlyBSDProcessList_readProcessName(dfpl->kd, kproc, &proc->basenameOffset); dfp->jname = DragonFlyBSDProcessList_readJailName(dfpl, kproc->kp_jailid); diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c index c2c21af1..72e0b10f 100644 --- a/freebsd/FreeBSDProcess.c +++ b/freebsd/FreeBSDProcess.c @@ -26,7 +26,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = PROCESS_FLAG_FREEBSD_TTY, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of copy-on-write faults", .flags = 0, .defaultSortDesc = true, }, [PRIORITY] = { .name = "PRIORITY", .title = "PRI ", .description = "Kernel's internal priority for the process", .flags = 0, }, @@ -74,16 +74,6 @@ static void FreeBSDProcess_writeField(const Process* this, RichString* str, Proc case JAIL: Process_printLeftAlignedField(str, attr, fp->jname ? fp->jname : "N/A", 11); return; - case TTY_NR: - if (fp->ttyPath) { - if (fp->ttyPath == nodevStr) - attr = CRT_colors[PROCESS_SHADOW]; - xSnprintf(buffer, n, "%-8s", fp->ttyPath); - } else { - attr = CRT_colors[PROCESS_SHADOW]; - xSnprintf(buffer, n, "? "); - } - break; default: Process_writeField(this, str, field); return; @@ -101,8 +91,6 @@ static int FreeBSDProcess_compareByKey(const Process* v1, const Process* v2, Pro return SPACESHIP_NUMBER(p1->jid, p2->jid); case JAIL: return SPACESHIP_NULLSTR(p1->jname, p2->jname); - case TTY_NR: - return SPACESHIP_NULLSTR(p1->ttyPath, p2->ttyPath); default: return Process_compareByKey_Base(v1, v2, key); } diff --git a/freebsd/FreeBSDProcess.h b/freebsd/FreeBSDProcess.h index 750e485e..5b6b4c66 100644 --- a/freebsd/FreeBSDProcess.h +++ b/freebsd/FreeBSDProcess.h @@ -14,16 +14,11 @@ in the source distribution for its full text. #include "Settings.h" -#define PROCESS_FLAG_FREEBSD_TTY 0x0100 - -extern const char* const nodevStr; - typedef struct FreeBSDProcess_ { Process super; bool isKernelThread; int jid; char* jname; - const char* ttyPath; } FreeBSDProcess; static inline bool Process_isKernelThread(const Process* this) { diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c index 2e937669..c5e8fd11 100644 --- a/freebsd/FreeBSDProcessList.c +++ b/freebsd/FreeBSDProcessList.c @@ -10,7 +10,6 @@ in the source distribution for its full text. #include "FreeBSDProcessList.h" #include -#include #include #include #include @@ -22,7 +21,6 @@ in the source distribution for its full text. #include #include #include -#include #include #include #include @@ -148,16 +146,12 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui CRT_fatalError("kvm_openfiles() failed"); } - fpl->ttys = Hashtable_new(20, true); - return pl; } void ProcessList_delete(ProcessList* this) { const FreeBSDProcessList* fpl = (FreeBSDProcessList*) this; - Hashtable_delete(fpl->ttys); - if (fpl->kd) { kvm_close(fpl->kd); } @@ -383,70 +377,6 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) { pl->usedSwap *= pageSizeKb; } -static void FreeBSDProcessList_scanTTYs(ProcessList* pl) { - FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl; - - // scan /dev/tty* - { - DIR* dirPtr = opendir("/dev"); - if (!dirPtr) - return; - - int dirFd = dirfd(dirPtr); - if (dirFd < 0) - goto err1; - - const struct dirent* entry; - while ((entry = readdir(dirPtr))) { - if (!String_startsWith(entry->d_name, "tty")) - continue; - - struct stat info; - if (Compat_fstatat(dirFd, "/dev", entry->d_name, &info, 0) < 0) - continue; - - if (!S_ISCHR(info.st_mode)) - continue; - - if (!Hashtable_get(fpl->ttys, info.st_rdev)) - Hashtable_put(fpl->ttys, info.st_rdev, xStrdup(entry->d_name)); - } - -err1: - closedir(dirPtr); - } - - // scan /dev/pts/* - { - DIR* dirPtr = opendir("/dev/pts"); - if (!dirPtr) - return; - - int dirFd = dirfd(dirPtr); - if (dirFd < 0) - goto err2; - - const struct dirent* entry; - while ((entry = readdir(dirPtr))) { - struct stat info; - if (Compat_fstatat(dirFd, "/dev/pts", entry->d_name, &info, 0) < 0) - continue; - - if (!S_ISCHR(info.st_mode)) - continue; - - if (!Hashtable_get(fpl->ttys, info.st_rdev)) { - char* path; - xAsprintf(&path, "pts/%s", entry->d_name); - Hashtable_put(fpl->ttys, info.st_rdev, path); - } - } - -err2: - closedir(dirPtr); - } -} - static char* FreeBSDProcessList_readProcessName(kvm_t* kd, const struct kinfo_proc* kproc, int* basenameEnd) { char** argv = kvm_getargv(kd, kproc, 0); if (!argv) { @@ -512,10 +442,6 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { return; } - if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) { - FreeBSDProcessList_scanTTYs(super); - } - int count = 0; const struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count); @@ -543,6 +469,15 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { ProcessList_add(super, proc); proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset); fp->jname = FreeBSDProcessList_readJailName(kproc); + + proc->tty_nr = kproc->ki_tdev; + const char* name = (kproc->ki_tdev != NODEV) ? devname(kproc->ki_tdev, S_IFCHR) : NULL; + if (!name) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } } else { if (fp->jid != kproc->ki_jid) { // process can enter jail anytime @@ -603,10 +538,6 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { default: proc->state = '?'; } - if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) { - fp->ttyPath = (kproc->ki_tdev == NODEV) ? nodevStr : Hashtable_get(fpl->ttys, kproc->ki_tdev); - } - if (Process_isKernelThread(proc)) super->kernelThreads++; diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h index 398bb827..882345e8 100644 --- a/freebsd/FreeBSDProcessList.h +++ b/freebsd/FreeBSDProcessList.h @@ -39,8 +39,6 @@ typedef struct FreeBSDProcessList_ { CPUData* cpus; - Hashtable* ttys; - unsigned long* cp_time_o; unsigned long* cp_time_n; diff --git a/htop.1.in b/htop.1.in index e8cfc3f6..af3ca6b7 100644 --- a/htop.1.in +++ b/htop.1.in @@ -288,7 +288,7 @@ The process's group ID. .B SESSION (SID) The process's session ID. .TP -.B TTY_NR (TTY) +.B TTY The controlling terminal of the process. .TP .B TPGID diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 764f0151..61f22349 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -38,7 +38,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, [CMINFLT] = { .name = "CMINFLT", .title = " CMINFLT ", .description = "Children processes' minor faults", .flags = 0, .defaultSortDesc = true, }, @@ -129,7 +129,6 @@ void Process_delete(Object* cast) { #endif free(this->cwd); free(this->secattr); - free(this->ttyDevice); free(this->procExe); free(this->procComm); free(this->mergedCommand.str); @@ -610,14 +609,6 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces int attr = CRT_colors[DEFAULT_COLOR]; size_t n = sizeof(buffer) - 1; switch (field) { - case TTY_NR: - if (lp->ttyDevice) { - xSnprintf(buffer, n, "%-8s ", lp->ttyDevice + 5 /* skip "/dev/" */); - break; - } - - Process_writeField(this, str, field); - return; case CMINFLT: Process_colorNumber(str, lp->cminflt, coloring); return; case CMAJFLT: Process_colorNumber(str, lp->cmajflt, coloring); return; case M_DRS: Process_humanNumber(str, lp->m_drs * pageSizeKB, coloring); return; diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index 29ef2a98..622189b2 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -117,7 +117,6 @@ typedef struct LinuxProcess_ { #endif char* cgroup; unsigned int oom; - char* ttyDevice; #ifdef HAVE_DELAYACCT unsigned long long int delay_read_time; unsigned long long cpu_delay_total; diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index e51c33ea..4564f8e6 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1196,7 +1196,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc return true; } -static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned int tty_nr) { +static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned long int tty_nr) { unsigned int maj = major(tty_nr); unsigned int min = minor(tty_nr); @@ -1363,13 +1363,13 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ char command[MAX_NAME + 1]; unsigned long long int lasttimes = (lp->utime + lp->stime); - unsigned int tty_nr = proc->tty_nr; + unsigned long int tty_nr = proc->tty_nr; if (! LinuxProcessList_readStatFile(proc, procFd, command, sizeof(command))) goto errorReadingProcess; if (tty_nr != proc->tty_nr && this->ttyDrivers) { - free(lp->ttyDevice); - lp->ttyDevice = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr); + free(proc->tty_name); + proc->tty_name = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr); } if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO) { diff --git a/openbsd/OpenBSDProcess.c b/openbsd/OpenBSDProcess.c index cb04055e..f757b23b 100644 --- a/openbsd/OpenBSDProcess.c +++ b/openbsd/OpenBSDProcess.c @@ -63,9 +63,9 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { .flags = 0, .pidColumn = true, }, - [TTY_NR] = { - .name = "TTY_NR", - .title = " TTY ", + [TTY] = { + .name = "TTY", + .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c index 122b55d3..fbe7c103 100644 --- a/openbsd/OpenBSDProcessList.c +++ b/openbsd/OpenBSDProcessList.c @@ -225,7 +225,6 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { proc->tpgid = kproc->p_tpgid; proc->tgid = kproc->p_pid; proc->session = kproc->p_sid; - proc->tty_nr = kproc->p_tdev; proc->pgrp = kproc->p__pgid; proc->st_uid = kproc->p_uid; proc->starttime_ctime = kproc->p_ustart_sec; @@ -233,6 +232,15 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { proc->user = UsersTable_getRef(this->super.usersTable, proc->st_uid); ProcessList_add(&this->super, proc); proc->comm = OpenBSDProcessList_readProcessName(this->kd, kproc, &proc->basenameOffset); + + proc->tty_nr = kproc->p_tdev; + const char* name = ((dev_t)kproc->p_tdev != NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL; + if (!name || String_eq(name, "??")) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } } else { if (settings->updateProcessNames) { free(proc->comm); diff --git a/solaris/SolarisProcess.c b/solaris/SolarisProcess.c index c0bc295a..310d8fb6 100644 --- a/solaris/SolarisProcess.c +++ b/solaris/SolarisProcess.c @@ -28,7 +28,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, diff --git a/unsupported/UnsupportedProcess.c b/unsupported/UnsupportedProcess.c index de95d089..def2a180 100644 --- a/unsupported/UnsupportedProcess.c +++ b/unsupported/UnsupportedProcess.c @@ -23,7 +23,7 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, }, [PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, }, [SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, }, - [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, }, + [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, }, [TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, }, [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, .defaultSortDesc = true,}, [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, .defaultSortDesc = true, }, diff --git a/unsupported/UnsupportedProcessList.c b/unsupported/UnsupportedProcessList.c index 010a83e9..81031487 100644 --- a/unsupported/UnsupportedProcessList.c +++ b/unsupported/UnsupportedProcessList.c @@ -54,6 +54,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc->pgrp = 0; proc->session = 0; proc->tty_nr = 0; + proc->tty_name = NULL; proc->tpgid = 0; proc->st_uid = 0; proc->processor = 0;