diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-11-06 10:46:40 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-11-06 10:56:41 +0100 |
commit | 153ea704af5e22c70e169f112e9df3e4cd9a6f11 (patch) | |
tree | e879dcf3decc9e162d3a4f0a746b05214b7899c1 /Userland | |
parent | 52d502e11f3207f2c5c36e7cc676f43f249fc351 (diff) | |
download | serenity-153ea704af5e22c70e169f112e9df3e4cd9a6f11.zip |
Add some basic signal support.
It only works for sending a signal to a process that's in userspace code.
We implement reception by synthesizing a PUSHA+PUSHF in the receiving process
(operating on values in the TSS.)
The TSS CS:EIP is then rerouted to the signal handler and a tiny return
trampoline is constructed in a dedicated region in the receiving process.
Also hacked up /bin/kill to be able to send arbitrary signals (kill -N PID)
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/cat.cpp | 10 | ||||
-rw-r--r-- | Userland/kill.cpp | 39 | ||||
-rw-r--r-- | Userland/sh.cpp | 28 |
3 files changed, 62 insertions, 15 deletions
diff --git a/Userland/cat.cpp b/Userland/cat.cpp index b127bf2cc9..ab003a2a7d 100644 --- a/Userland/cat.cpp +++ b/Userland/cat.cpp @@ -1,7 +1,9 @@ -#include <LibC/stdio.h> -#include <LibC/unistd.h> -#include <LibC/errno.h> -#include <LibC/string.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> int main(int argc, char** argv) { diff --git a/Userland/kill.cpp b/Userland/kill.cpp index 573b58fe4c..10cc9c1b62 100644 --- a/Userland/kill.cpp +++ b/Userland/kill.cpp @@ -1,6 +1,7 @@ -#include <LibC/unistd.h> -#include <LibC/stdio.h> -#include <LibC/signal.h> +#include <unistd.h> +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> #include <AK/String.h> static unsigned parseUInt(const String& str, bool& ok) @@ -18,20 +19,36 @@ static unsigned parseUInt(const String& str, bool& ok) return value; } +static void print_usage_and_exit() +{ + printf("usage: kill [-signal] <PID>\n"); + exit(1); +} + int main(int argc, char** argv) { - if (argc < 2) { - printf("usage: kill <PID>\n"); - return 1; - } + if (argc != 2 && argc != 3) + print_usage_and_exit(); bool ok; - unsigned value = parseUInt(argv[1], ok); + unsigned signum = SIGTERM; + int pid_argi = 1; + if (argc == 3) { + pid_argi = 2; + if (argv[1][0] != '-') + print_usage_and_exit(); + signum = parseUInt(&argv[1][1], ok); + if (!ok) { + printf("%s is not a valid signal number\n", &argv[1][1]); + return 2; + } + } + unsigned pid = parseUInt(argv[pid_argi], ok); if (!ok) { - printf("%s is not a valid PID\n", argv[1]); - return 2; + printf("%s is not a valid PID\n", argv[pid_argi]); + return 3; } - kill((pid_t)value, SIGKILL); + kill((pid_t)pid, signum); return 0; } diff --git a/Userland/sh.cpp b/Userland/sh.cpp index 1ec61c2ed4..5d8c224b9a 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -6,6 +6,7 @@ #include <LibC/stdlib.h> #include <LibC/utsname.h> #include <LibC/pwd.h> +#include <signal.h> #include <AK/FileSystemPath.h> struct GlobalState { @@ -32,6 +33,29 @@ static int sh_pwd(int, const char**) return 0; } +void did_receive_signal(int signum) +{ + printf("\nMy word, I've received a signal with number %d\n", signum); + //exit(0); +} + +static int sh_busy(int, const char**) +{ + struct sigaction sa; + sa.sa_handler = did_receive_signal; + sa.sa_flags = 0; + sa.sa_mask = 0; + sa.sa_restorer = nullptr; + int rc = sigaction(SIGUSR1, &sa, nullptr); + assert(rc == 0); + printf("listening for SIGUSR1 while looping in userspace...\n"); + for (;;) { + for (volatile int i = 0; i < 100000; ++i) + ; + } + return 0; +} + static int sh_fork(int, const char**) { pid_t pid = fork(); @@ -147,6 +171,10 @@ static bool handle_builtin(int argc, const char** argv, int& retval) retval = sh_fef(argc, argv); return true; } + if (!strcmp(argv[0], "busy")) { + retval = sh_busy(argc, argv); + return true; + } if (!strcmp(argv[0], "wt")) { retval = sh_wt(argc, argv); return true; |