Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Action.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ in the source distribution for its full text.
#include "CategoriesPanel.h"
#include "CRT.h"
#include "EnvScreen.h"
#include "CommandScreen.h"
#include "MainPanel.h"
#include "OpenFilesScreen.h"
#include "Process.h"
Expand Down Expand Up @@ -422,8 +423,8 @@ static const struct { const char* key; const char* info; } helpRight[] = {
{ .key = " e: ", .info = "show process environment" },
{ .key = " i: ", .info = "set IO priority" },
{ .key = " l: ", .info = "list open files with lsof" },
{ .key = " M: ", .info = "show process command in multiple lines" },
{ .key = " s: ", .info = "trace syscalls with strace" },
{ .key = " ", .info = "" },
{ .key = " F2 C S: ", .info = "setup" },
{ .key = " F1 h: ", .info = "show this help screen" },
{ .key = " F10 q: ", .info = "quit" },
Expand Down Expand Up @@ -530,6 +531,16 @@ static Htop_Reaction actionShowEnvScreen(State* st) {
return HTOP_REFRESH | HTOP_REDRAW_BAR;
}

static Htop_Reaction actionShowCommandScreen(State* st) {
Process* p = (Process*) Panel_getSelected(st->panel);
if (!p) return HTOP_OK;
CommandScreen* cmdScr = CommandScreen_new(p);
InfoScreen_run((InfoScreen*)cmdScr);
CommandScreen_delete((Object*)cmdScr);
clear();
CRT_enableDelay();
return HTOP_REFRESH | HTOP_REDRAW_BAR;
}

void Action_setBindings(Htop_Action* keys) {
keys[KEY_RESIZE] = actionResize;
Expand Down Expand Up @@ -584,4 +595,5 @@ void Action_setBindings(Htop_Action* keys) {
keys['U'] = actionUntagAll;
keys['c'] = actionTagAllChildren;
keys['e'] = actionShowEnvScreen;
keys['M'] = actionShowCommandScreen;
}
74 changes: 74 additions & 0 deletions CommandScreen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "CommandScreen.h"

#include "config.h"
#include "CRT.h"
#include "IncSet.h"
#include "ListItem.h"
#include "Platform.h"
#include "StringUtils.h"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>


static void CommandScreen_addLine(InfoScreen* this, char* line, const char* p, int line_offset, int len) {
memcpy(line, p - line_offset, len);
line[len] = '\0';
InfoScreen_addLine(this, line);
}

static void CommandScreen_scan(InfoScreen* this) {
Panel* panel = this->display;
int idx = MAXIMUM(Panel_getSelectedIndex(panel), 0);

Panel_prune(panel);

const char* p = this->process->comm;
char* line = xMalloc(COLS + 1);
int line_offset = 0, last_spc = -1, len;
for (; *p != '\0'; p++, line_offset++) {
if (*p == ' ') last_spc = line_offset;

if (line_offset == COLS) {
len = (last_spc == -1) ? line_offset : last_spc;
CommandScreen_addLine(this, line, p, line_offset, len);
line_offset -= len;
last_spc = -1;
}
}

if (line_offset > 0) CommandScreen_addLine(this, line, p, line_offset, line_offset);

free(line);
Panel_setSelected(panel, idx);
}

static void CommandScreen_draw(InfoScreen* this) {
char* title = xMalloc(COLS + 1);
int len = snprintf(title, COLS + 1, "Command of process %d - %s", this->process->pid, this->process->comm);
if (len > COLS) {
memset(&title[COLS - 3], '.', 3);
}

InfoScreen_drawTitled(this, "%s", title);
free(title);
}

InfoScreenClass CommandScreen_class = {
.super = {
.extends = Class(Object),
.delete = CommandScreen_delete
},
.scan = CommandScreen_scan,
.draw = CommandScreen_draw
};

CommandScreen* CommandScreen_new(Process* process) {
CommandScreen* this = AllocThis(CommandScreen);
return (CommandScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 3, " ");
}

void CommandScreen_delete(Object* this) {
free(InfoScreen_done((InfoScreen*)this));
}
16 changes: 16 additions & 0 deletions CommandScreen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef HEADER_CommandScreen
#define HEADER_CommandScreen

#include "InfoScreen.h"

typedef struct CommandScreen_ {
InfoScreen super;
} CommandScreen;

extern InfoScreenClass CommandScreen_class;

CommandScreen* CommandScreen_new(Process* process);

void CommandScreen_delete(Object* this);

#endif
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
SignalsPanel.c StringUtils.c SwapMeter.c TasksMeter.c UptimeMeter.c \
TraceScreen.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
HostnameMeter.c OpenFilesScreen.c Affinity.c IncSet.c Action.c EnvScreen.c \
InfoScreen.c XAlloc.c
InfoScreen.c CommandScreen.c XAlloc.c

myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
Expand All @@ -32,7 +32,7 @@ BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h
ScreenManager.h Settings.h SignalsPanel.h StringUtils.h SwapMeter.h \
TasksMeter.h UptimeMeter.h TraceScreen.h UsersTable.h Vector.h Process.h \
AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h IncSet.h Action.h \
EnvScreen.h InfoScreen.h XAlloc.h Macros.h
EnvScreen.h InfoScreen.h CommandScreen.h XAlloc.h Macros.h

# Linux
# -----
Expand Down
3 changes: 3 additions & 0 deletions htop.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ update of system calls issued by the process.
Display open files for a process: if lsof(1) is installed, pressing this key
will display the list of file descriptors opened by the process.
.TP
.B M
Display the command line of the highlighted process in multiple lines.
.TP
.B F1, h, ?
Go to the help screen
.TP
Expand Down