summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorMaxwell Trussell <maxtrussell@gmail.com>2022-10-12 00:14:50 -0700
committerAndreas Kling <kling@serenityos.org>2022-10-13 11:15:33 +0200
commitf5e68fcc2056f3deae6183a3906dcf66f05107f2 (patch)
tree33f4db60828e55616a9125ffd80efaca647815f6 /Userland
parenta982e0380e34e8f6e0240198a62f67e2a802d0da (diff)
downloadserenity-f5e68fcc2056f3deae6183a3906dcf66f05107f2.zip
Utilities: Add pkill
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Utilities/CMakeLists.txt3
-rw-r--r--Userland/Utilities/pkill.cpp71
2 files changed, 73 insertions, 1 deletions
diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt
index 6f9c73f87b..dc28c0cc4f 100644
--- a/Userland/Utilities/CMakeLists.txt
+++ b/Userland/Utilities/CMakeLists.txt
@@ -3,7 +3,7 @@ list(APPEND SPECIAL_TARGETS test install)
list(APPEND REQUIRED_TARGETS
arp base64 basename cat chmod chown clear comm cp cut date dd df diff dirname dmesg du echo env expr false fgrep
file find grep groups head host hostname id ifconfig kill killall ln logout ls mkdir mount mv nproc
- pgrep pidof ping pmap ps readlink realpath reboot rm rmdir route seq shutdown sleep sort stat stty su tail test
+ pgrep pidof ping pkill pmap ps readlink realpath reboot rm rmdir route seq shutdown sleep sort stat stty su tail test
touch tr true umount uname uniq uptime w wc which whoami xargs yes less
)
list(APPEND RECOMMENDED_TARGETS
@@ -175,6 +175,7 @@ target_link_libraries(pathchk LibMain)
target_link_libraries(pgrep LibRegex LibMain)
target_link_libraries(pidof LibMain)
target_link_libraries(ping LibMain)
+target_link_libraries(pkill LibRegex LibMain)
target_link_libraries(pledge LibMain)
target_link_libraries(pls LibCrypt LibMain)
target_link_libraries(pmap LibMain)
diff --git a/Userland/Utilities/pkill.cpp b/Userland/Utilities/pkill.cpp
new file mode 100644
index 0000000000..8d993db903
--- /dev/null
+++ b/Userland/Utilities/pkill.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2022, Maxwell Trussell <maxtrussell@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Format.h>
+#include <AK/Vector.h>
+#include <LibCore/ArgsParser.h>
+#include <LibCore/ProcessStatisticsReader.h>
+#include <LibCore/System.h>
+#include <LibMain/Main.h>
+#include <LibRegex/Regex.h>
+#include <LibRegex/RegexOptions.h>
+#include <signal.h>
+#include <sys/types.h>
+
+ErrorOr<int> serenity_main(Main::Arguments args)
+{
+ TRY(Core::System::pledge("stdio proc rpath"));
+ TRY(Core::System::unveil("/proc/all", "r"));
+ TRY(Core::System::unveil("/etc/passwd", "r"));
+ TRY(Core::System::unveil(nullptr, nullptr));
+
+ bool case_insensitive = false;
+ bool echo = false;
+ char const* pattern = nullptr;
+ int signal = SIGTERM;
+
+ Core::ArgsParser args_parser;
+ args_parser.add_option(case_insensitive, "Make matches case-insensitive", nullptr, 'i');
+ args_parser.add_option(echo, "Display what is killed", "echo", 'e');
+ args_parser.add_option(signal, "Signal number to send", "signal", 's', "number");
+ 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;
+ }
+
+ PosixOptions options {};
+ if (case_insensitive) {
+ options |= PosixFlags::Insensitive;
+ }
+
+ Regex<PosixExtended> re(pattern, options);
+ if (re.parser_result.error != regex::Error::NoError) {
+ return 1;
+ }
+
+ Vector<Core::ProcessStatistics> matched_processes;
+ for (auto& process : all_processes.value().processes) {
+ auto result = re.match(process.name, PosixFlags::Global);
+ if (result.success) {
+ matched_processes.append(process);
+ }
+ }
+
+ if (matched_processes.is_empty()) {
+ return 1;
+ }
+
+ for (auto& process : matched_processes) {
+ if (echo) {
+ outln("{} killed (pid {})", process.name, process.pid);
+ }
+ kill(process.pid, signal);
+ }
+ return 0;
+}