1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:24:57 +00:00

LibCore: Use Core::Stream for ProcessStatisticsReader

This commit is contained in:
Tim Schumacher 2022-12-08 14:50:31 +01:00 committed by Linus Groh
parent e338a0656d
commit 8940f2da7f
18 changed files with 55 additions and 95 deletions

View file

@ -433,16 +433,16 @@ void ProcessModel::update()
HashTable<int> live_tids;
u64 total_time_scheduled_diff = 0;
if (all_processes.has_value()) {
if (!all_processes.is_error()) {
if (m_has_total_scheduled_time)
total_time_scheduled_diff = all_processes->total_time_scheduled - m_total_time_scheduled;
total_time_scheduled_diff = all_processes.value().total_time_scheduled - m_total_time_scheduled;
m_total_time_scheduled = all_processes->total_time_scheduled;
m_total_time_scheduled_kernel = all_processes->total_time_scheduled_kernel;
m_total_time_scheduled = all_processes.value().total_time_scheduled;
m_total_time_scheduled_kernel = all_processes.value().total_time_scheduled_kernel;
m_has_total_scheduled_time = true;
for (size_t i = 0; i < all_processes->processes.size(); ++i) {
auto const& process = all_processes->processes[i];
for (size_t i = 0; i < all_processes.value().processes.size(); ++i) {
auto const& process = all_processes.value().processes[i];
NonnullOwnPtr<Process>* process_state = nullptr;
for (size_t i = 0; i < m_processes.size(); ++i) {
auto* other_process = &m_processes.ptr_at(i);
@ -549,7 +549,7 @@ void ProcessModel::update()
on_cpu_info_change(m_cpus);
if (on_state_update)
on_state_update(all_processes.has_value() ? all_processes->processes.size() : 0, m_threads.size());
on_state_update(!all_processes.is_error() ? all_processes.value().processes.size() : 0, m_threads.size());
// FIXME: This is a rather hackish way of invalidating indices.
// It would be good if GUI::Model had a way to orchestrate removal/insertion while preserving indices.

View file

@ -12,8 +12,8 @@
void CatDog::timer_event(Core::TimerEvent&)
{
auto maybe_proc_info = Core::ProcessStatisticsReader::get_all(m_proc_all);
if (maybe_proc_info.has_value()) {
auto maybe_proc_info = Core::ProcessStatisticsReader::get_all(*m_proc_all);
if (!maybe_proc_info.is_error()) {
auto proc_info = maybe_proc_info.release_value();
auto maybe_paint_program = proc_info.processes.first_matching([](auto& process) {

View file

@ -11,6 +11,7 @@
#include <AK/RefPtr.h>
#include <LibCore/ElapsedTimer.h>
#include <LibCore/File.h>
#include <LibCore/Stream.h>
#include <LibGUI/Menu.h>
#include <LibGUI/MouseTracker.h>
#include <LibGUI/Widget.h>
@ -72,7 +73,7 @@ private:
bool m_up, m_down, m_left, m_right;
bool m_roaming { true };
RefPtr<Core::File> m_proc_all;
NonnullOwnPtr<Core::Stream::File> m_proc_all;
NonnullRefPtr<Gfx::Bitmap> m_alert = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/alert.png"sv).release_value_but_fixme_should_propagate_errors();
NonnullRefPtr<Gfx::Bitmap> m_artist = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/artist.png"sv).release_value_but_fixme_should_propagate_errors();
@ -126,7 +127,7 @@ private:
CatDog()
: m_temp_pos { 0, 0 }
, m_proc_all(MUST(Core::File::open("/sys/kernel/processes", Core::OpenMode::ReadOnly)))
, m_proc_all(MUST(Core::Stream::File::open("/sys/kernel/processes"sv, Core::Stream::OpenMode::Read)))
{
set_image_by_main_state();
}

View file

@ -352,8 +352,8 @@ bool generate_profile(pid_t& pid)
DeprecatedString process_name;
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (all_processes.has_value()) {
auto& processes = all_processes->processes;
if (!all_processes.is_error()) {
auto& processes = all_processes.value().processes;
if (auto it = processes.find_if([&](auto& entry) { return entry.pid == pid; }); it != processes.end())
process_name = it->name;
else

View file

@ -8,7 +8,6 @@
#include <AK/JsonArray.h>
#include <AK/JsonObject.h>
#include <AK/JsonValue.h>
#include <LibCore/File.h>
#include <LibCore/ProcessStatisticsReader.h>
#include <pwd.h>
@ -16,29 +15,14 @@ namespace Core {
HashMap<uid_t, DeprecatedString> ProcessStatisticsReader::s_usernames;
Optional<AllProcessesStatistics> ProcessStatisticsReader::get_all(RefPtr<Core::File>& proc_all_file, bool include_usernames)
ErrorOr<AllProcessesStatistics> ProcessStatisticsReader::get_all(Core::Stream::SeekableStream& proc_all_file, bool include_usernames)
{
if (proc_all_file) {
if (!proc_all_file->seek(0, Core::SeekMode::SetPosition)) {
warnln("ProcessStatisticsReader: Failed to refresh /sys/kernel/processes: {}", proc_all_file->error_string());
return {};
}
} else {
proc_all_file = Core::File::construct("/sys/kernel/processes");
if (!proc_all_file->open(Core::OpenMode::ReadOnly)) {
warnln("ProcessStatisticsReader: Failed to open /sys/kernel/processes: {}", proc_all_file->error_string());
return {};
}
}
TRY(proc_all_file.seek(0, Core::Stream::SeekMode::SetPosition));
AllProcessesStatistics all_processes_statistics;
auto file_contents = proc_all_file->read_all();
auto json = JsonValue::from_string(file_contents);
if (json.is_error())
return {};
auto& json_obj = json.value().as_object();
auto file_contents = TRY(proc_all_file.read_all());
auto json_obj = TRY(JsonValue::from_string(file_contents)).as_object();
json_obj.get("processes"sv).as_array().for_each([&](auto& value) {
const JsonObject& process_object = value.as_object();
Core::ProcessStatistics process;
@ -104,10 +88,10 @@ Optional<AllProcessesStatistics> ProcessStatisticsReader::get_all(RefPtr<Core::F
return all_processes_statistics;
}
Optional<AllProcessesStatistics> ProcessStatisticsReader::get_all(bool include_usernames)
ErrorOr<AllProcessesStatistics> ProcessStatisticsReader::get_all(bool include_usernames)
{
RefPtr<Core::File> proc_all_file;
return get_all(proc_all_file, include_usernames);
auto proc_all_file = TRY(Core::Stream::File::open("/sys/kernel/processes"sv, Core::Stream::OpenMode::Read));
return get_all(*proc_all_file, include_usernames);
}
DeprecatedString ProcessStatisticsReader::username_from_uid(uid_t uid)

View file

@ -7,7 +7,7 @@
#pragma once
#include <AK/DeprecatedString.h>
#include <LibCore/File.h>
#include <LibCore/Stream.h>
#include <unistd.h>
namespace Core {
@ -72,8 +72,8 @@ struct AllProcessesStatistics {
class ProcessStatisticsReader {
public:
static Optional<AllProcessesStatistics> get_all(RefPtr<Core::File>&, bool include_usernames = true);
static Optional<AllProcessesStatistics> get_all(bool include_usernames = true);
static ErrorOr<AllProcessesStatistics> get_all(Core::Stream::SeekableStream&, bool include_usernames = true);
static ErrorOr<AllProcessesStatistics> get_all(bool include_usernames = true);
private:
static DeprecatedString username_from_uid(uid_t);

View file

@ -22,14 +22,12 @@ static ErrorOr<Core::ProcessStatistics const*> get_proc(Core::AllProcessesStatis
ErrorOr<pid_t> root_session_id(Optional<pid_t> force_sid)
{
auto stats = Core::ProcessStatisticsReader::get_all(false);
if (!stats.has_value())
return Error::from_string_literal("Failed to get all process statistics");
auto stats = TRY(Core::ProcessStatisticsReader::get_all(false));
pid_t sid = (force_sid.has_value()) ? force_sid.value() : TRY(System::getsid());
while (true) {
pid_t parent = TRY(get_proc(stats.value(), sid))->ppid;
pid_t parent_sid = TRY(get_proc(stats.value(), parent))->sid;
pid_t parent = TRY(get_proc(stats, sid))->ppid;
pid_t parent_sid = TRY(get_proc(stats, parent))->sid;
if (parent_sid == 0)
break;

View file

@ -21,7 +21,7 @@ void RunningProcessesModel::update()
m_processes.clear();
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (all_processes.has_value()) {
if (!all_processes.is_error()) {
for (auto& it : all_processes.value().processes) {
Process process;
process.pid = it.pid;

View file

@ -1073,15 +1073,13 @@ ErrorOr<Optional<DeprecatedString>> Window::compute_title_username(ConnectionFro
{
if (!client)
return Error::from_string_literal("Tried to compute title username without a client");
auto stats = Core::ProcessStatisticsReader::get_all(true);
if (!stats.has_value())
return Error::from_string_literal("Failed to get all process statistics");
auto stats = TRY(Core::ProcessStatisticsReader::get_all(true));
pid_t client_pid = TRY(client->socket().peer_pid());
auto client_stat = stats.value().processes.first_matching([&](auto& stat) { return stat.pid == client_pid; });
auto client_stat = stats.processes.first_matching([&](auto& stat) { return stat.pid == client_pid; });
if (!client_stat.has_value())
return Error::from_string_literal("Failed to find client process stat");
pid_t login_session_pid = TRY(Core::SessionManagement::root_session_id(client_pid));
auto login_session_stat = stats.value().processes.first_matching([&](auto& stat) { return stat.pid == login_session_pid; });
auto login_session_stat = stats.processes.first_matching([&](auto& stat) { return stat.pid == login_session_pid; });
if (!login_session_stat.has_value())
return Error::from_string_literal("Failed to find login process stat");
if (login_session_stat.value().uid == client_stat.value().uid)

View file

@ -21,11 +21,9 @@ static void print_usage_and_exit()
static ErrorOr<int> kill_all(DeprecatedString const& process_name, unsigned const signum)
{
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return 1;
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
for (auto& process : all_processes.value().processes) {
for (auto& process : all_processes.processes) {
if (process.name == process_name) {
TRY(Core::System::kill(process.pid, signum));
}

View file

@ -141,11 +141,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
outln("{:28} {:>4} {:>4} {:10} {:>4} {}", "COMMAND", "PID", "PGID", "USER", "FD", "NAME");
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return 1;
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
if (arg_pid == -1) {
for (auto& process : all_processes.value().processes) {
for (auto& process : all_processes.processes) {
if (process.pid == 0)
continue;
auto open_files = get_open_files_by_pid(process.pid);
@ -170,7 +168,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 0;
for (auto& file : open_files) {
display_entry(file, *all_processes->processes.find_if([&](auto& entry) { return entry.pid == arg_pid; }));
display_entry(file, *all_processes.processes.find_if([&](auto& entry) { return entry.pid == arg_pid; }));
}
}

View file

@ -58,11 +58,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
HashMap<pid_t, DeprecatedString> programs;
if (flag_program) {
auto processes = Core::ProcessStatisticsReader::get_all();
if (!processes.has_value())
return 1;
auto processes = TRY(Core::ProcessStatisticsReader::get_all());
for (auto& proc : processes.value().processes) {
for (auto& proc : processes.processes) {
programs.set(proc.pid, proc.name);
}
}

View file

@ -38,12 +38,10 @@ ErrorOr<int> serenity_main(Main::Arguments args)
return 1;
}
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return 1;
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
Vector<pid_t> matches;
for (auto& it : all_processes.value().processes) {
for (auto& it : all_processes.processes) {
auto result = re.match(it.name, PosixFlags::Global);
if (result.success ^ invert_match) {
matches.append(it.pid);

View file

@ -18,11 +18,9 @@ static ErrorOr<int> pid_of(DeprecatedString const& process_name, bool single_sho
{
bool displayed_at_least_one = false;
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return 1;
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
for (auto& it : all_processes.value().processes) {
for (auto& it : all_processes.processes) {
if (it.name == process_name) {
if (!omit_pid || it.pid != pid) {
out(displayed_at_least_one ? " {}"sv : "{}"sv, it.pid);

View file

@ -34,10 +34,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
args_parser.add_positional_argument(pattern, "Process name to search for", "process-name");
args_parser.parse(args);
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value()) {
return 1;
}
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
PosixOptions options {};
if (case_insensitive) {
@ -50,7 +47,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
}
Vector<Core::ProcessStatistics> matched_processes;
for (auto& process : all_processes.value().processes) {
for (auto& process : all_processes.processes) {
auto result = re.match(process.name, PosixFlags::Global);
if (result.success) {
matched_processes.append(process);

View file

@ -98,11 +98,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
cmd_column = add_column("CMD", Alignment::Left);
}
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return 1;
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
auto& processes = all_processes.value().processes;
auto& processes = all_processes.processes;
if (!pid_list.is_empty()) {
every_process_flag = true;

View file

@ -89,14 +89,12 @@ struct Snapshot {
u64 total_time_scheduled_kernel { 0 };
};
static Snapshot get_snapshot()
static ErrorOr<Snapshot> get_snapshot()
{
auto all_processes = Core::ProcessStatisticsReader::get_all();
if (!all_processes.has_value())
return {};
auto all_processes = TRY(Core::ProcessStatisticsReader::get_all());
Snapshot snapshot;
for (auto& process : all_processes.value().processes) {
for (auto& process : all_processes.processes) {
for (auto& thread : process.threads) {
ThreadData thread_data;
thread_data.tid = thread.tid;
@ -126,8 +124,8 @@ static Snapshot get_snapshot()
}
}
snapshot.total_time_scheduled = all_processes->total_time_scheduled;
snapshot.total_time_scheduled_kernel = all_processes->total_time_scheduled_kernel;
snapshot.total_time_scheduled = all_processes.total_time_scheduled;
snapshot.total_time_scheduled_kernel = all_processes.total_time_scheduled_kernel;
return snapshot;
}
@ -216,7 +214,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
enable_nonblocking_stdin();
Vector<ThreadData*> threads;
auto prev = get_snapshot();
auto prev = TRY(get_snapshot());
usleep(10000);
for (;;) {
if (g_window_size_changed) {
@ -224,7 +222,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
g_window_size_changed = false;
}
auto current = get_snapshot();
auto current = TRY(get_snapshot());
auto total_scheduled_diff = current.total_time_scheduled - prev.total_time_scheduled;
printf("\033[3J\033[H\033[2J");

View file

@ -33,11 +33,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
return 1;
}
auto process_statistics = Core::ProcessStatisticsReader::get_all();
if (!process_statistics.has_value()) {
warnln("Error: Could not get process statistics");
return 1;
}
auto process_statistics = TRY(Core::ProcessStatisticsReader::get_all());
auto now = time(nullptr);
@ -70,7 +66,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
DeprecatedString what = "n/a";
for (auto& process : process_statistics.value().processes) {
for (auto& process : process_statistics.processes) {
if (process.tty == tty && process.pid == process.pgid)
what = process.name;
}