Linux: use correct column alignment for wide fields

This affects:
- PROC_COMM, PROC_EXE and CWD on Linux
- JAIL on FreeBSD and DragonFlyBSD
- ZONE on Solaris
This commit is contained in:
Christian Göttsche 2021-01-10 15:57:46 +01:00
parent 8a67d7f086
commit a5db139a0a
8 changed files with 34 additions and 33 deletions

View File

@ -244,6 +244,11 @@ void Process_outputRate(RichString* str, char* buffer, size_t n, double rate, in
}
}
void Process_printLeftAlignedField(RichString* str, int attr, const char* content, unsigned int width) {
int c = RichString_appendnWide(str, attr, content, MINIMUM(width, strlen(content)));
RichString_appendChr(str, ' ', width + 1 - c);
}
void Process_writeField(const Process* this, RichString* str, ProcessField field) {
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
@ -365,8 +370,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
attr = CRT_colors[PROCESS_SHADOW];
if (this->user) {
int c = RichString_appendnWide(str, attr, this->user, MINIMUM(9, strlen(this->user)));
RichString_appendChr(str, ' ', 10 - c);
Process_printLeftAlignedField(str, attr, this->user, 9);
return;
}

View File

@ -179,6 +179,8 @@ void Process_fillStarttimeBuffer(Process* this);
void Process_outputRate(RichString* str, char* buffer, size_t n, double rate, int coloring);
void Process_printLeftAlignedField(RichString* str, int attr, const char* content, unsigned int width);
void Process_display(const Object* cast, RichString* out);
void Process_done(Process* this);

View File

@ -60,7 +60,7 @@ static inline int RichString_writeFromWide(RichString* this, int attrs, const ch
this->chptr[i] = (CharType) { .attr = attrs & 0xffffff, .chars = { (iswprint(data[j]) ? data[j] : '?') } };
}
return len;
return wcswidth(data, len);
}
static inline int RichString_writeFromAscii(RichString* this, int attrs, const char* data, int from, int len) {

View File

@ -71,14 +71,7 @@ static void DragonFlyBSDProcess_writeField(const Process* this, RichString* str,
// add Platform-specific fields here
case PID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, (fp->kernel ? -1 : this->pid)); break;
case JID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, fp->jid); break;
case JAIL: {
xSnprintf(buffer, n, "%-11s ", fp->jname);
if (buffer[11] != '\0') {
buffer[11] = ' ';
buffer[12] = '\0';
}
break;
}
case JAIL: Process_printLeftAlignedField(str, attr, fp->jname, 11); return;
default:
Process_writeField(this, str, field);
return;

View File

@ -71,14 +71,9 @@ static void FreeBSDProcess_writeField(const Process* this, RichString* str, Proc
switch (field) {
// add FreeBSD-specific fields here
case JID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, fp->jid); break;
case JAIL: {
xSnprintf(buffer, n, "%-11s ", fp->jname);
if (buffer[11] != '\0') {
buffer[11] = ' ';
buffer[12] = '\0';
}
break;
}
case JAIL:
Process_printLeftAlignedField(str, attr, fp->jname ? fp->jname : "N/A", 11);
return;
case TTY_NR:
if (fp->ttyPath) {
if (fp->ttyPath == nodevStr)

View File

@ -414,7 +414,7 @@ static char* FreeBSDProcessList_readJailName(const struct kinfo_proc* kproc) {
char* jname = NULL;
char jnamebuf[MAXHOSTNAMELEN];
if (kproc->ki_jid != 0 ) {
if (kproc->ki_jid != 0) {
struct iovec jiov[6];
memset(jnamebuf, 0, sizeof(jnamebuf));

View File

@ -707,39 +707,46 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
return;
}
case PROC_COMM: {
const char* procComm;
if (lp->procComm) {
attr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_COMM : PROCESS_COMM];
/* 15 being (TASK_COMM_LEN - 1) */
xSnprintf(buffer, n, "%-15.15s ", lp->procComm);
procComm = lp->procComm;
} else {
attr = CRT_colors[PROCESS_SHADOW];
xSnprintf(buffer, n, "%-15.15s ", Process_isKernelThread(lp) ? kthreadID : "N/A");
procComm = Process_isKernelThread(lp) ? kthreadID : "N/A";
}
break;
/* 15 being (TASK_COMM_LEN - 1) */
Process_printLeftAlignedField(str, attr, procComm, 15);
return;
}
case PROC_EXE: {
const char* procExe;
if (lp->procExe) {
attr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_BASENAME : PROCESS_BASENAME];
if (lp->procExeDeleted)
attr = CRT_colors[FAILED_READ];
xSnprintf(buffer, n, "%-15.15s ", lp->procExe + lp->procExeBasenameOffset);
procExe = lp->procExe + lp->procExeBasenameOffset;
} else {
attr = CRT_colors[PROCESS_SHADOW];
xSnprintf(buffer, n, "%-15.15s ", Process_isKernelThread(lp) ? kthreadID : "N/A");
procExe = Process_isKernelThread(lp) ? kthreadID : "N/A";
}
break;
Process_printLeftAlignedField(str, attr, procExe, 15);
return;
}
case CWD:
case CWD: {
const char* cwd;
if (!lp->cwd) {
xSnprintf(buffer, n, "%-25s ", "N/A");
attr = CRT_colors[PROCESS_SHADOW];
cwd = "N/A";
} else if (String_startsWith(lp->cwd, "/proc/") && strstr(lp->cwd, " (deleted)") != NULL) {
xSnprintf(buffer, n, "%-25s ", "main thread terminated");
attr = CRT_colors[PROCESS_SHADOW];
cwd = "main thread terminated";
} else {
xSnprintf(buffer, n, "%-25.25s ", lp->cwd);
cwd = lp->cwd;
}
break;
Process_printLeftAlignedField(str, attr, cwd, 25);
return;
}
default:
Process_writeField(this, str, field);
return;

View File

@ -79,7 +79,7 @@ static void SolarisProcess_writeField(const Process* this, RichString* str, Proc
case TASKID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->taskid); break;
case POOLID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->poolid); break;
case CONTID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->contid); break;
case ZONE: xSnprintf(buffer, n, "%-*s ", ZONENAME_MAX/4, sp->zname); break;
case ZONE: Process_printLeftAlignedField(str, attr, sp->zname ? sp->zname : "global", ZONENAME_MAX/4); return;
case PID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->realpid); break;
case PPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->realppid); break;
case LWPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, sp->lwpid); break;