From cde467ee465cd821a71f068bfd89a6f6100d0175 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 10 Jul 2023 20:16:06 +0200 Subject: [PATCH] kernel: Support returning termination signals from waitpid --- apps/init.cpp | 9 ++++++++- kernel/src/sys/signal.cpp | 2 +- kernel/src/thread/Thread.cpp | 12 ++++++++++-- kernel/src/thread/Thread.h | 6 ++++-- libc/include/bits/waitpid.h | 2 ++ libc/include/sys/wait.h | 4 +++- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/init.cpp b/apps/init.cpp index 4f5d268a..131c2166 100644 --- a/apps/init.cpp +++ b/apps/init.cpp @@ -328,7 +328,14 @@ int main() { if (service.pid.has_value() && service.pid.value() == child) { - do_log("[init] service %s exited with status %d\n", service.name.chars(), WEXITSTATUS(status)); + if (WIFEXITED(status)) + { + do_log("[init] service %s exited with status %d\n", service.name.chars(), WEXITSTATUS(status)); + } + else + { + do_log("[init] service %s was terminated by signal %d\n", service.name.chars(), WTERMSIG(status)); + } if (service.restart) { diff --git a/kernel/src/sys/signal.cpp b/kernel/src/sys/signal.cpp index a0bfdd36..864fd1f8 100644 --- a/kernel/src/sys/signal.cpp +++ b/kernel/src/sys/signal.cpp @@ -62,7 +62,7 @@ Result sys_kill(Registers*, SyscallArgs args) if (target->is_kernel) return 0; if (signo == 0) return 0; - target->pending_signals |= 1 << (signo - 1); + target->send_signal(signo); return 0; } diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index 1e17f89c..6031fc55 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -4,6 +4,7 @@ #include "thread/Scheduler.h" #include #include +#include #include #include #include @@ -70,7 +71,7 @@ Result> Thread::resolve_atfile(int dirfd, const String& pa return VFS::resolve_path(path.chars(), this->auth, descriptor->inode, follow_last_symlink); } -[[noreturn]] void Thread::exit_and_signal_parent(u8 _status) +[[noreturn]] void Thread::exit_and_signal_parent(int _status) { if (this->id == 1) fail("the init process exited"); if (is_kernel) state = ThreadState::Dying; @@ -140,7 +141,8 @@ void Thread::process_pending_signals(Registers* current_regs) { case DefaultSignalAction::Ignore: return; // FIXME: Add signal exit codes. - case DefaultSignalAction::Terminate: exit_and_signal_parent(255); + case DefaultSignalAction::Terminate: exit_and_signal_parent(signo | _SIGBIT); + default: return; } } // If we fail to deliver the signal (usually because there's not enough space on the stack), execute the @@ -151,6 +153,12 @@ void Thread::process_pending_signals(Registers* current_regs) } } +void Thread::send_signal(int signo) +{ + check(signo > 0 && signo <= NSIG); + pending_signals |= 1 << (signo - 1); +} + bool FileDescriptor::should_append() { return flags & O_APPEND; diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index e568bb44..be90fab1 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -91,7 +91,7 @@ struct Thread : public LinkedListNode bool is_kernel { true }; - u8 status { 0 }; + int status { 0 }; mode_t umask { 0 }; @@ -110,7 +110,7 @@ struct Thread : public LinkedListNode PageDirectory* active_directory { nullptr }; - [[noreturn]] void exit_and_signal_parent(u8 status); + [[noreturn]] void exit_and_signal_parent(int status); bool is_idle() { @@ -144,6 +144,8 @@ struct Thread : public LinkedListNode Result push_mem_on_stack(const u8* mem, usize size); Result pop_mem_from_stack(u8* mem, usize size); + void send_signal(int signo); + static void init(); }; diff --git a/libc/include/bits/waitpid.h b/libc/include/bits/waitpid.h index 8b7922b4..2ed3b15e 100644 --- a/libc/include/bits/waitpid.h +++ b/libc/include/bits/waitpid.h @@ -3,6 +3,8 @@ #ifndef _BITS_WAITPID_H #define _BITS_WAITPID_H +#define _SIGBIT 0x100 + #define WNOHANG 1 #endif diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h index 4fa9c3e5..a10d9bf1 100644 --- a/libc/include/sys/wait.h +++ b/libc/include/sys/wait.h @@ -6,8 +6,10 @@ #include #include -#define WIFEXITED(ret) ((ret) | 0) +#define WIFEXITED(ret) (((ret)&_SIGBIT) == 0) #define WEXITSTATUS(ret) ((ret)&0xff) +#define WIFSIGNALED(ret) (((ret)&_SIGBIT) == _SIGBIT) +#define WTERMSIG(ret) ((ret)&0xff) #ifdef __cplusplus extern "C"