Serenity Operating System
at master 73 lines 2.3 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedString.h> 8#include <LibCore/ArgsParser.h> 9#include <LibCore/ProcessStatisticsReader.h> 10#include <LibCore/System.h> 11#include <LibMain/Main.h> 12#include <stdio.h> 13#include <string.h> 14#include <unistd.h> 15 16static ErrorOr<int> pid_of(DeprecatedString const& process_name, bool single_shot, bool omit_pid, pid_t pid) 17{ 18 bool displayed_at_least_one = false; 19 20 auto all_processes = TRY(Core::ProcessStatisticsReader::get_all()); 21 22 for (auto& it : all_processes.processes) { 23 if (it.name == process_name) { 24 if (!omit_pid || it.pid != pid) { 25 out(displayed_at_least_one ? " {}"sv : "{}"sv, it.pid); 26 displayed_at_least_one = true; 27 28 if (single_shot) 29 break; 30 } 31 } 32 } 33 34 if (displayed_at_least_one) 35 outln(); 36 37 return 0; 38} 39 40ErrorOr<int> serenity_main(Main::Arguments args) 41{ 42 TRY(Core::System::pledge("stdio rpath")); 43 TRY(Core::System::unveil("/sys/kernel/processes", "r")); 44 TRY(Core::System::unveil("/etc/passwd", "r")); 45 TRY(Core::System::unveil(nullptr, nullptr)); 46 47 bool single_shot = false; 48 StringView omit_pid_value; 49 StringView process_name; 50 51 Core::ArgsParser args_parser; 52 args_parser.add_option(single_shot, "Only return one pid", nullptr, 's'); 53 args_parser.add_option(omit_pid_value, "Omit the given PID, or the parent process if the special value %PPID is passed", nullptr, 'o', "pid"); 54 args_parser.add_positional_argument(process_name, "Process name to search for", "process-name"); 55 56 args_parser.parse(args); 57 58 pid_t pid_to_omit = 0; 59 if (!omit_pid_value.is_empty()) { 60 if (omit_pid_value == "%PPID"sv) { 61 pid_to_omit = getppid(); 62 } else { 63 auto number = omit_pid_value.to_uint(); 64 if (!number.has_value()) { 65 warnln("Invalid value for -o"); 66 args_parser.print_usage(stderr, args.strings[0]); 67 return 1; 68 } 69 pid_to_omit = number.value(); 70 } 71 } 72 return pid_of(process_name, single_shot, !omit_pid_value.is_empty(), pid_to_omit); 73}