commit dd7bc67e5574e7d15045363e8503f9d62dc1b516
parent a99dbe17933f176b1b79f6a524179c249e80ec88
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 22 Nov 2021 11:30:26 +0100
os::exec: add kill
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 118 insertions(+), 0 deletions(-)
diff --git a/os/exec/process+freebsd.ha b/os/exec/process+freebsd.ha
@@ -132,3 +132,62 @@ export fn check(stat: *status) (void | !exit_status) = {
};
return exit(stat);
};
+
+// An enumeration of all known signals. Only a subset of these are defined by
+// POSIX, consult the specification for details:
+//
+// https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
+export type signal = enum int {
+ SIGHUP = rt::SIGHUP,
+ SIGINT = rt::SIGINT,
+ SIGQUIT = rt::SIGQUIT,
+ SIGILL = rt::SIGILL,
+ SIGTRAP = rt::SIGTRAP,
+ SIGABRT = rt::SIGABRT,
+ SIGFPE = rt::SIGFPE,
+ SIGKILL = rt::SIGKILL,
+ SIGBUS = rt::SIGBUS,
+ SIGSEGV = rt::SIGSEGV,
+ SIGSYS = rt::SIGSYS,
+ SIGPIPE = rt::SIGPIPE,
+ SIGALRM = rt::SIGALRM,
+ SIGTERM = rt::SIGTERM,
+ SIGSTOP = rt::SIGSTOP,
+ SIGTSTP = rt::SIGTSTP,
+ SIGCONT = rt::SIGCONT,
+ SIGCHLD = rt::SIGCHLD,
+ SIGTTIN = rt::SIGTTIN,
+ SIGTTOU = rt::SIGTTOU,
+ SIGIO = rt::SIGIO,
+ SIGXCPU = rt::SIGXCPU,
+ SIGXFSZ = rt::SIGXFSZ,
+ SIGVTALRM = rt::SIGVTALRM,
+ SIGPROF = rt::SIGPROF,
+ SIGWINCH = rt::SIGWINCH,
+ SIGINFO = rt::SIGINFO,
+ SIGUSR1 = rt::SIGUSR1,
+ SIGUSR2 = rt::SIGUSR2,
+ SIGTHR = rt::SIGTHR,
+ SIGLWP = rt::SIGLWP,
+ SIGLIBRT = rt::SIGLIBRT,
+};
+
+// Sends a signal to a child process. If no variadic arguments are provided, the
+// program is terminated in a platform-specific manner. You may provide exactly
+// one variadic argument, the [[signal]] you wish to send, but this is only
+// supported on Unix-like systems.
+export fn kill(proc: process, sig: signal...) (void | errors::error) = {
+ const sig = if (len(sig) == 0) {
+ yield signal::SIGTERM;
+ } else if (len(sig) == 1) {
+ yield sig[0];
+ } else {
+ abort("os::exec::signal illegally called with more than one signal");
+ };
+ match (rt::kill(proc, sig)) {
+ case errno: rt::errno =>
+ return errors::errno(errno);
+ case void =>
+ return;
+ };
+};
diff --git a/os/exec/process+linux.ha b/os/exec/process+linux.ha
@@ -118,3 +118,62 @@ export fn check(stat: *status) (void | !exit_status) = {
};
return exit(stat);
};
+
+// An enumeration of all known signals. Only a subset of these are defined by
+// POSIX, consult the specification for details:
+//
+// https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
+export type signal = enum int {
+ SIGHUP = rt::SIGHUP,
+ SIGINT = rt::SIGINT,
+ SIGQUIT = rt::SIGQUIT,
+ SIGILL = rt::SIGILL,
+ SIGTRAP = rt::SIGTRAP,
+ SIGABRT = rt::SIGABRT,
+ SIGBUS = rt::SIGBUS,
+ SIGFPE = rt::SIGFPE,
+ SIGKILL = rt::SIGKILL,
+ SIGUSR1 = rt::SIGUSR1,
+ SIGSEGV = rt::SIGSEGV,
+ SIGUSR2 = rt::SIGUSR2,
+ SIGPIPE = rt::SIGPIPE,
+ SIGALRM = rt::SIGALRM,
+ SIGTERM = rt::SIGTERM,
+ SIGSTKFLT = rt::SIGSTKFLT,
+ SIGCHLD = rt::SIGCHLD,
+ SIGCONT = rt::SIGCONT,
+ SIGSTOP = rt::SIGSTOP,
+ SIGTSTP = rt::SIGTSTP,
+ SIGTTIN = rt::SIGTTIN,
+ SIGTTOU = rt::SIGTTOU,
+ SIGURG = rt::SIGURG,
+ SIGXCPU = rt::SIGXCPU,
+ SIGXFSZ = rt::SIGXFSZ,
+ SIGVTALRM = rt::SIGVTALRM,
+ SIGPROF = rt::SIGPROF,
+ SIGWINCH = rt::SIGWINCH,
+ SIGIO = rt::SIGIO,
+ SIGPOLL = rt::SIGPOLL,
+ SIGPWR = rt::SIGPWR,
+ SIGSYS = rt::SIGSYS,
+};
+
+// Sends a signal to a child process. If no variadic arguments are provided, the
+// program is terminated in a platform-specific manner. You may provide exactly
+// one variadic argument, the [[signal]] you wish to send, but this is only
+// supported on Unix-like systems.
+export fn kill(proc: process, sig: signal...) (void | errors::error) = {
+ const sig = if (len(sig) == 0) {
+ yield signal::SIGTERM;
+ } else if (len(sig) == 1) {
+ yield sig[0];
+ } else {
+ abort("os::exec::signal illegally called with more than one signal");
+ };
+ match (rt::kill(proc, sig)) {
+ case errno: rt::errno =>
+ return errors::errno(errno);
+ case void =>
+ return;
+ };
+};