From 821bf5e071f3d9b44fffa7c632d24830e3833ff2 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Tue, 30 May 2023 17:51:26 +0100 Subject: pgrep: Add `-U` option to filter matches by UID or login name --- Userland/Utilities/pgrep.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'Userland') diff --git a/Userland/Utilities/pgrep.cpp b/Userland/Utilities/pgrep.cpp index 992bc9974a..ce0ca0698a 100644 --- a/Userland/Utilities/pgrep.cpp +++ b/Userland/Utilities/pgrep.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ ErrorOr serenity_main(Main::Arguments args) { TRY(Core::System::pledge("stdio rpath")); TRY(Core::System::unveil("/sys/kernel/processes", "r")); + TRY(Core::System::unveil("/etc/group", "r")); TRY(Core::System::unveil("/etc/passwd", "r")); TRY(Core::System::unveil(nullptr, nullptr)); @@ -25,6 +27,7 @@ ErrorOr serenity_main(Main::Arguments args) bool case_insensitive = false; bool list_process_name = false; bool invert_match = false; + HashTable uids_to_filter_by; StringView pattern; Core::ArgsParser args_parser; @@ -32,6 +35,30 @@ ErrorOr serenity_main(Main::Arguments args) args_parser.add_option(pid_delimiter, "Set the string used to delimit multiple pids", "delimiter", 'd', nullptr); args_parser.add_option(case_insensitive, "Make matches case-insensitive", "ignore-case", 'i'); args_parser.add_option(list_process_name, "List the process name in addition to its pid", "list-name", 'l'); + args_parser.add_option(Core::ArgsParser::Option { + .argument_mode = Core::ArgsParser::OptionArgumentMode::Required, + .help_string = "Select only processes whose UID is in the given comma-separated list. Login name or numerical user ID may be used", + .long_name = "uid", + .short_name = 'U', + .value_name = "uid-list", + .accept_value = [&uids_to_filter_by](StringView comma_separated_users) { + for (auto user_string : comma_separated_users.split_view(',')) { + auto maybe_uid = user_string.to_uint(); + if (maybe_uid.has_value()) { + uids_to_filter_by.set(maybe_uid.value()); + } else { + auto maybe_account = Core::Account::from_name(user_string, Core::Account::Read::PasswdOnly); + if (maybe_account.is_error()) { + warnln("Could not find user '{}': {}", user_string, maybe_account.error()); + return false; + } + uids_to_filter_by.set(maybe_account.release_value().uid()); + } + } + + return true; + }, + }); args_parser.add_option(invert_match, "Select non-matching lines", "invert-match", 'v'); args_parser.add_positional_argument(pattern, "Process name to search for", "process-name"); args_parser.parse(args); @@ -51,6 +78,9 @@ ErrorOr serenity_main(Main::Arguments args) for (auto const& it : all_processes.processes) { auto result = re.match(it.name, PosixFlags::Global); if (result.success ^ invert_match) { + if (!uids_to_filter_by.is_empty() && !uids_to_filter_by.contains(it.uid)) + continue; + matches.append(it); } } -- cgit v1.2.3