summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-10-29 11:45:53 +0100
committerAndreas Kling <kling@serenityos.org>2020-10-29 11:45:53 +0100
commita6b2598fba21b28414b04f80d9305b0a5a1f640d (patch)
tree1d3dedcefc49024f58544c4b607a2f1db6e3661e /Userland
parentd27a8e505f0b8374b2edfc0271687cd4fa4f4490 (diff)
downloadserenity-a6b2598fba21b28414b04f80d9305b0a5a1f640d.zip
Userland: Teach "kill" to understand signal names (not just numbers)
You can now do things like "kill -STOP pid" :^) The getsignalbyname() helper function should probably move to LibC or somewhere where it can be used by other signal related programs.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/kill.cpp66
1 files changed, 64 insertions, 2 deletions
diff --git a/Userland/kill.cpp b/Userland/kill.cpp
index 2e9889929f..7858625d4f 100644
--- a/Userland/kill.cpp
+++ b/Userland/kill.cpp
@@ -26,9 +26,11 @@
#include <AK/Optional.h>
#include <AK/String.h>
+#include <ctype.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
static void print_usage_and_exit()
@@ -37,6 +39,55 @@ static void print_usage_and_exit()
exit(1);
}
+static const char* signal_names[] = {
+ "INVAL",
+ "HUP",
+ "INT",
+ "QUIT",
+ "ILL",
+ "TRAP",
+ "ABRT",
+ "BUS",
+ "FPE",
+ "KILL",
+ "USR1",
+ "SEGV",
+ "USR2",
+ "PIPE",
+ "ALRM",
+ "TERM",
+ "STKFLT",
+ "CHLD",
+ "CONT",
+ "STOP",
+ "TSTP",
+ "TTIN",
+ "TTOU",
+ "URG",
+ "XCPU",
+ "XFSZ",
+ "VTALRM",
+ "PROF",
+ "WINCH",
+ "IO",
+ "INFO",
+ "SYS"
+};
+
+static_assert(sizeof(signal_names) == sizeof(const char*) * 32);
+
+int getsignalbyname(const char* name)
+{
+ ASSERT(name);
+ for (size_t i = 0; i < NSIG; ++i) {
+ auto* signal_name = signal_names[i];
+ if (!strcmp(signal_name, name))
+ return i;
+ }
+ errno = EINVAL;
+ return -1;
+}
+
int main(int argc, char** argv)
{
if (pledge("stdio proc", nullptr) < 0) {
@@ -52,9 +103,20 @@ int main(int argc, char** argv)
pid_argi = 2;
if (argv[1][0] != '-')
print_usage_and_exit();
- auto number = StringView(&argv[1][1]).to_uint();
+
+ Optional<unsigned> number;
+
+ if (isalpha(argv[1][1])) {
+ int value = getsignalbyname(&argv[1][1]);
+ if (value >= 0 && value < NSIG)
+ number = value;
+ }
+
+ if (!number.has_value())
+ number = StringView(&argv[1][1]).to_uint();
+
if (!number.has_value()) {
- printf("'%s' is not a valid signal number\n", &argv[1][1]);
+ printf("'%s' is not a valid signal name or number\n", &argv[1][1]);
return 2;
}
signum = number.value();