From 6a0a2c9ab43d8d43e91581568a44fcfc63225409 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 10 Nov 2018 23:29:07 +0100 Subject: [PATCH] Some improvements to signals. - Add sigprocmask() and sigpending(). - Forked children inherit signal dispositions and masks. - Exec clears signal dispositions and masks. --- Kernel/Process.cpp | 39 +++++++++++++++++++++++++++++++++++++-- Kernel/Process.h | 4 +++- Kernel/Syscall.cpp | 2 ++ Kernel/Syscall.h | 2 ++ LibC/signal.cpp | 13 ++++++++++++- LibC/signal.h | 2 ++ LibC/sys/cdefs.h | 2 ++ 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f6e74782dbfc18..e3d6f21870bde2 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -227,6 +227,11 @@ int Process::sys$gethostname(char* buffer, size_t size) Process* Process::fork(RegisterDump& regs) { auto* child = new Process(String(m_name), m_uid, m_gid, m_pid, m_ring, m_cwd.copyRef(), m_executable.copyRef(), m_tty, this); + if (!child) + return nullptr; + + memcpy(child->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data)); + child->m_signal_mask = m_signal_mask; #ifdef FORK_DEBUG dbgprintf("fork: child=%p\n", child); #endif @@ -365,6 +370,9 @@ int Process::do_exec(const String& path, Vector&& arguments, Vector { int sys$dup(int oldfd); int sys$dup2(int oldfd, int newfd); int sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act); + int sys$sigprocmask(int how, const Unix::sigset_t* set, Unix::sigset_t* old_set); + int sys$sigpending(Unix::sigset_t*); int sys$getgroups(int size, gid_t*); int sys$setgroups(size_t, const gid_t*); @@ -247,7 +249,7 @@ class Process : public InlineLinkedListNode { size_t m_max_open_file_descriptors { 16 }; SignalActionData m_signal_action_data[32]; dword m_pending_signals { 0 }; - dword m_signal_mask { 0 }; + dword m_signal_mask { 0xffffffff }; byte m_termination_status { 0 }; byte m_termination_signal { 0 }; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 8dea51dd7baf05..2356e33a8e99be 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -159,6 +159,8 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2, current->sys$sigreturn(); ASSERT_NOT_REACHED(); return 0; + case Syscall::SC_sigprocmask: + return current->sys$sigprocmask((int)arg1, (const Unix::sigset_t*)arg2, (Unix::sigset_t*)arg3); default: kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 81fe7967325bb7..3cd39912aacbd0 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -54,6 +54,8 @@ __ENUMERATE_SYSCALL(getgroups) \ __ENUMERATE_SYSCALL(setgroups) \ __ENUMERATE_SYSCALL(sigreturn) \ + __ENUMERATE_SYSCALL(sigprocmask) \ + __ENUMERATE_SYSCALL(sigpending) \ #define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function)) diff --git a/LibC/signal.cpp b/LibC/signal.cpp index b3481283088fd0..32a08e32dcb80f 100644 --- a/LibC/signal.cpp +++ b/LibC/signal.cpp @@ -71,6 +71,18 @@ int sigismember(const sigset_t* set, int sig) return 0; } +int sigprocmask(int how, const sigset_t* set, sigset_t* old_set) +{ + int rc = Syscall::invoke(Syscall::SC_sigprocmask, (dword)how, (dword)set, (dword)old_set); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + +int sigpending(sigset_t* set) +{ + int rc = Syscall::invoke(Syscall::SC_sigpending, (dword)set); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + const char* sys_siglist[NSIG] = { #undef __SIGNAL #define __SIGNAL(a, b) b, @@ -78,5 +90,4 @@ const char* sys_siglist[NSIG] = { #undef __SIGNAL }; - } diff --git a/LibC/signal.h b/LibC/signal.h index 0cc5e5a142c411..99e32834468c1c 100644 --- a/LibC/signal.h +++ b/LibC/signal.h @@ -29,6 +29,8 @@ int sigfillset(sigset_t*); int sigaddset(sigset_t*, int sig); int sigdelset(sigset_t*, int sig); int sigismember(const sigset_t*, int sig); +int sigprocmask(int how, const sigset_t* set, sigset_t* old_set); +int sigpending(sigset_t*); #define NSIG 32 extern const char* sys_siglist[NSIG]; diff --git a/LibC/sys/cdefs.h b/LibC/sys/cdefs.h index 4c5f129ff8d6ae..05dc28aa56e6cd 100644 --- a/LibC/sys/cdefs.h +++ b/LibC/sys/cdefs.h @@ -17,5 +17,7 @@ #undef __P #define __P(a) a +#ifdef __cplusplus extern "C" int main(int, char**); +#endif