浏览代码

Utilities: Add pkill

Maxwell Trussell 2 年之前
父节点
当前提交
f5e68fcc20
共有 2 个文件被更改,包括 73 次插入1 次删除
  1. 2 1
      Userland/Utilities/CMakeLists.txt
  2. 71 0
      Userland/Utilities/pkill.cpp

+ 2 - 1
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)

+ 71 - 0
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;
+}