summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Action.c14
-rw-r--r--CommandScreen.c74
-rw-r--r--CommandScreen.h16
-rw-r--r--Makefile.am4
-rw-r--r--htop.1.in3
5 files changed, 108 insertions, 3 deletions
diff --git a/Action.c b/Action.c
index eac7f1f6..f36e0bd2 100644
--- a/Action.c
+++ b/Action.c
@@ -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"
@@ -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" },
@@ -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;
@@ -584,4 +595,5 @@ void Action_setBindings(Htop_Action* keys) {
keys['U'] = actionUntagAll;
keys['c'] = actionTagAllChildren;
keys['e'] = actionShowEnvScreen;
+ keys['M'] = actionShowCommandScreen;
}
diff --git a/CommandScreen.c b/CommandScreen.c
new file mode 100644
index 00000000..0e261175
--- /dev/null
+++ b/CommandScreen.c
@@ -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));
+}
diff --git a/CommandScreen.h b/CommandScreen.h
new file mode 100644
index 00000000..a1604a3e
--- /dev/null
+++ b/CommandScreen.h
@@ -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
diff --git a/Makefile.am b/Makefile.am
index c97ae938..441ea80e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 \
@@ -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
# -----
diff --git a/htop.1.in b/htop.1.in
index 424cc157..215d92c5 100644
--- a/htop.1.in
+++ b/htop.1.in
@@ -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