From f4a5cd63bb158b580bad510a5ad4a7ac337e3f4b Mon Sep 17 00:00:00 2001 From: Maciej Date: Sat, 29 Oct 2022 21:49:51 +0200 Subject: [PATCH] SystemMonitor: Add Command column to ProcessModel This column shows full command line of a process, or empty line if an error occures when reading it. The command is not escaped for now. --- .../SystemMonitor/ProcessModel.cpp | 27 +++++++++++++++++++ .../Applications/SystemMonitor/ProcessModel.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/Userland/Applications/SystemMonitor/ProcessModel.cpp b/Userland/Applications/SystemMonitor/ProcessModel.cpp index 8cb79d2855..791a6c5ed7 100644 --- a/Userland/Applications/SystemMonitor/ProcessModel.cpp +++ b/Userland/Applications/SystemMonitor/ProcessModel.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,8 @@ String ProcessModel::column_name(int column) const return "Pledge"; case Column::Veil: return "Veil"; + case Column::Command: + return "Command"; default: VERIFY_NOT_REACHED(); } @@ -150,6 +153,7 @@ GUI::Variant ProcessModel::data(GUI::ModelIndex const& index, GUI::ModelRole rol case Column::User: case Column::Pledge: case Column::Veil: + case Column::Command: return Gfx::TextAlignment::CenterLeft; case Column::PID: case Column::TID: @@ -221,6 +225,8 @@ GUI::Variant ProcessModel::data(GUI::ModelIndex const& index, GUI::ModelRole rol return thread.current_state.cpu; case Column::Name: return thread.current_state.name; + case Column::Command: + return thread.current_state.command; case Column::Syscalls: return thread.current_state.syscall_count; case Column::InodeFaults: @@ -289,6 +295,8 @@ GUI::Variant ProcessModel::data(GUI::ModelIndex const& index, GUI::ModelRole rol if (thread.current_state.kernel) return String::formatted("{} (*)", thread.current_state.name); return thread.current_state.name; + case Column::Command: + return thread.current_state.command; case Column::Syscalls: return thread.current_state.syscall_count; case Column::InodeFaults: @@ -400,6 +408,24 @@ Vector ProcessModel::matches(StringView searching, unsigned fla return found_indices; } +static ErrorOr try_read_command_line(pid_t pid) +{ + auto file = TRY(Core::Stream::File::open(String::formatted("/proc/{}/cmdline", pid), Core::Stream::OpenMode::Read)); + auto data = TRY(file->read_all()); + auto json = TRY(JsonValue::from_string(StringView { data.bytes() })); + auto array = json.as_array().values(); + return String::join(" "sv, array); +} + +static String read_command_line(pid_t pid) +{ + auto string_or_error = try_read_command_line(pid); + if (string_or_error.is_error()) { + return ""; + } + return string_or_error.release_value(); +} + void ProcessModel::update() { auto previous_tid_count = m_threads.size(); @@ -442,6 +468,7 @@ void ProcessModel::update() state.kernel = process.kernel; state.executable = process.executable; state.name = thread.name; + state.command = read_command_line(process.pid); state.uid = process.uid; state.state = thread.state; state.user = process.username; diff --git a/Userland/Applications/SystemMonitor/ProcessModel.h b/Userland/Applications/SystemMonitor/ProcessModel.h index 3bdf317695..5970f7d852 100644 --- a/Userland/Applications/SystemMonitor/ProcessModel.h +++ b/Userland/Applications/SystemMonitor/ProcessModel.h @@ -52,6 +52,7 @@ public: UnixSocketWriteBytes, IPv4SocketReadBytes, IPv4SocketWriteBytes, + Command, __Count }; @@ -105,6 +106,7 @@ private: bool kernel { false }; String executable { "" }; String name { "" }; + String command { "" }; uid_t uid { 0 }; String state { "" }; String user { "" }; @@ -149,6 +151,7 @@ private: this->kernel = other.kernel; this->executable = other.executable; this->name = other.name; + this->command = other.command; this->uid = other.uid; this->state = other.state; this->user = other.user;