diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-08-03 08:26:04 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-08-03 08:26:45 +0200 |
commit | 8a703c007647ece356f7e6b02757fbb19791d4d8 (patch) | |
tree | 5fb441b74d37533fdd14b8b1688d8cd09d1961cc /Applications | |
parent | 45c5a91afcff90fa156977bc3238ba3252a6f169 (diff) | |
download | serenity-8a703c007647ece356f7e6b02757fbb19791d4d8.zip |
ProcessManager: Add a new per-proces "open files" view showing open FDs
This uses the data from /proc/PID/fds with ease now that it's JSON. :^)
Diffstat (limited to 'Applications')
6 files changed, 153 insertions, 0 deletions
diff --git a/Applications/ProcessManager/Makefile b/Applications/ProcessManager/Makefile index a67af7d942..56a75d48eb 100644 --- a/Applications/ProcessManager/Makefile +++ b/Applications/ProcessManager/Makefile @@ -8,6 +8,8 @@ OBJS = \ ProcessStacksWidget.o \ ProcessMemoryMapWidget.o \ ProcessMemoryMapModel.o \ + ProcessFileDescriptorMapWidget.o \ + ProcessFileDescriptorMapModel.o \ main.o APP = ProcessManager diff --git a/Applications/ProcessManager/ProcessFileDescriptorMapModel.cpp b/Applications/ProcessManager/ProcessFileDescriptorMapModel.cpp new file mode 100644 index 0000000000..512d1474dd --- /dev/null +++ b/Applications/ProcessManager/ProcessFileDescriptorMapModel.cpp @@ -0,0 +1,74 @@ +#include "ProcessFileDescriptorMapModel.h" +#include <AK/JsonObject.h> +#include <AK/StringBuilder.h> +#include <LibCore/CFile.h> + +void ProcessFileDescriptorMapModel::update() +{ + CFile file(String::format("/proc/%d/fds", m_pid)); + if (!file.open(CIODevice::ReadOnly)) { + dbg() << "Unable to open " << file.filename(); + return; + } + + auto json = JsonValue::from_string(file.read_all()); + + ASSERT(json.is_array()); + m_process_fds = json.as_array(); + + did_update(); +} + +int ProcessFileDescriptorMapModel::row_count(const GModelIndex&) const +{ + return m_process_fds.size(); +} + +String ProcessFileDescriptorMapModel::column_name(int column) const +{ + switch (column) { + case Column::FileDescriptor: + return "FD"; + case Column::Path: + return "Path"; + default: + ASSERT_NOT_REACHED(); + } +} + +GModel::ColumnMetadata ProcessFileDescriptorMapModel::column_metadata(int column) const +{ + switch (column) { + case Column::FileDescriptor: + return { 32, TextAlignment::CenterRight }; + case Column::Path: + return { 300, TextAlignment::CenterLeft }; + default: + ASSERT_NOT_REACHED(); + } + return {}; +} + +GVariant ProcessFileDescriptorMapModel::data(const GModelIndex& index, Role role) const +{ + auto& fd_object = m_process_fds.at(index.row()).as_object(); + if (role == GModel::Role::Display) { + switch (index.column()) { + case Column::FileDescriptor: + return fd_object.get("fd").to_int(); + case Column::Path: + return fd_object.get("absolute_path").to_string(); + default: + ASSERT_NOT_REACHED(); + } + } + return {}; +} + +void ProcessFileDescriptorMapModel::set_pid(pid_t pid) +{ + if (m_pid == pid) + return; + m_pid = pid; + update(); +} diff --git a/Applications/ProcessManager/ProcessFileDescriptorMapModel.h b/Applications/ProcessManager/ProcessFileDescriptorMapModel.h new file mode 100644 index 0000000000..b9386df903 --- /dev/null +++ b/Applications/ProcessManager/ProcessFileDescriptorMapModel.h @@ -0,0 +1,29 @@ +#pragma once + +#include <AK/JsonArray.h> +#include <LibGUI/GModel.h> + +class ProcessFileDescriptorMapModel final : public GModel { +public: + enum Column { + FileDescriptor, + Path, + __Count + }; + + ProcessFileDescriptorMapModel() {} + virtual ~ProcessFileDescriptorMapModel() override {} + + virtual int row_count(const GModelIndex& = GModelIndex()) const override; + virtual int column_count(const GModelIndex& = GModelIndex()) const override { return Column::__Count; } + virtual String column_name(int) const override; + virtual ColumnMetadata column_metadata(int) const override; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; + virtual void update() override; + + void set_pid(pid_t); + +private: + JsonArray m_process_fds; + int m_pid { -1 }; +}; diff --git a/Applications/ProcessManager/ProcessFileDescriptorMapWidget.cpp b/Applications/ProcessManager/ProcessFileDescriptorMapWidget.cpp new file mode 100644 index 0000000000..cf3691661e --- /dev/null +++ b/Applications/ProcessManager/ProcessFileDescriptorMapWidget.cpp @@ -0,0 +1,25 @@ +#include "ProcessFileDescriptorMapWidget.h" +#include "ProcessFileDescriptorMapModel.h" +#include <LibGUI/GBoxLayout.h> +#include <LibGUI/GTableView.h> + +ProcessFileDescriptorMapWidget::ProcessFileDescriptorMapWidget(GWidget* parent) + : GWidget(parent) +{ + set_layout(make<GBoxLayout>(Orientation::Vertical)); + layout()->set_margins({ 4, 4, 4, 4 }); + m_table_view = new GTableView(this); + m_table_view->set_model(adopt(*new ProcessFileDescriptorMapModel)); +} + +ProcessFileDescriptorMapWidget::~ProcessFileDescriptorMapWidget() +{ +} + +void ProcessFileDescriptorMapWidget::set_pid(pid_t pid) +{ + if (m_pid == pid) + return; + m_pid = pid; + static_cast<ProcessFileDescriptorMapModel*>(m_table_view->model())->set_pid(pid); +} diff --git a/Applications/ProcessManager/ProcessFileDescriptorMapWidget.h b/Applications/ProcessManager/ProcessFileDescriptorMapWidget.h new file mode 100644 index 0000000000..a858281b6d --- /dev/null +++ b/Applications/ProcessManager/ProcessFileDescriptorMapWidget.h @@ -0,0 +1,18 @@ +#pragma once + +#include <LibGUI/GWidget.h> + +class GTableView; + +class ProcessFileDescriptorMapWidget final : public GWidget { + C_OBJECT(ProcessFileDescriptorMapWidget); +public: + explicit ProcessFileDescriptorMapWidget(GWidget* parent); + virtual ~ProcessFileDescriptorMapWidget() override; + + void set_pid(pid_t); + +private: + GTableView* m_table_view { nullptr }; + pid_t m_pid { -1 }; +}; diff --git a/Applications/ProcessManager/main.cpp b/Applications/ProcessManager/main.cpp index 36c15bb753..080683d493 100644 --- a/Applications/ProcessManager/main.cpp +++ b/Applications/ProcessManager/main.cpp @@ -1,5 +1,6 @@ #include "GraphWidget.h" #include "MemoryStatsWidget.h" +#include "ProcessFileDescriptorMapWidget.h" #include "ProcessMemoryMapWidget.h" #include "ProcessStacksWidget.h" #include "ProcessTableView.h" @@ -157,6 +158,9 @@ int main(int argc, char** argv) auto* process_tab_widget = new GTabWidget(process_container_splitter); + auto* open_files_widget = new ProcessFileDescriptorMapWidget(nullptr); + process_tab_widget->add_widget("Open files", open_files_widget); + auto* memory_map_widget = new ProcessMemoryMapWidget(nullptr); process_tab_widget->add_widget("Memory map", memory_map_widget); @@ -164,6 +168,7 @@ int main(int argc, char** argv) process_tab_widget->add_widget("Stacks", stacks_widget); process_table_view->on_process_selected = [&](pid_t pid) { + open_files_widget->set_pid(pid); stacks_widget->set_pid(pid); memory_map_widget->set_pid(pid); }; |