|
@@ -0,0 +1,134 @@
|
|
|
+#include <kernel/process.hpp>
|
|
|
+#include <kernel/signal.hpp>
|
|
|
+
|
|
|
+#include <signal.h>
|
|
|
+
|
|
|
+using kernel::signal_list;
|
|
|
+using signo_type = signal_list::signo_type;
|
|
|
+
|
|
|
+static void continue_process(int) { }
|
|
|
+
|
|
|
+static void stop_process(int)
|
|
|
+{
|
|
|
+ current_thread->attr.ready = 0;
|
|
|
+ current_thread->attr.wait = 1;
|
|
|
+ readythds->remove_all(current_thread);
|
|
|
+
|
|
|
+ schedule();
|
|
|
+}
|
|
|
+
|
|
|
+static void terminate_process(int signo)
|
|
|
+{
|
|
|
+ kill_current(signo);
|
|
|
+}
|
|
|
+
|
|
|
+static void terminate_process_with_core_dump(int signo)
|
|
|
+{
|
|
|
+ terminate_process(signo & 0x80);
|
|
|
+}
|
|
|
+
|
|
|
+static sig_t default_handlers[32] = {
|
|
|
+ nullptr,
|
|
|
+ terminate_process, // SIGHUP
|
|
|
+ terminate_process, // SIGINT
|
|
|
+ terminate_process_with_core_dump, // SIGQUIT
|
|
|
+ terminate_process_with_core_dump, // SIGILL
|
|
|
+ terminate_process_with_core_dump, // SIGTRAP
|
|
|
+ terminate_process_with_core_dump, // SIGABRT, SIGIOT
|
|
|
+ terminate_process_with_core_dump, // SIGBUS
|
|
|
+ terminate_process_with_core_dump, // SIGFPE
|
|
|
+ terminate_process, // SIGKILL
|
|
|
+ terminate_process, // SIGUSR1
|
|
|
+ terminate_process_with_core_dump, // SIGSEGV
|
|
|
+ terminate_process, // SIGUSR2
|
|
|
+ terminate_process, // SIGPIPE
|
|
|
+ terminate_process, // SIGALRM
|
|
|
+ terminate_process, // SIGTERM
|
|
|
+ terminate_process, // SIGSTKFLT
|
|
|
+ nullptr, // SIGCHLD
|
|
|
+ continue_process, // SIGCONT
|
|
|
+ stop_process, // SIGSTOP
|
|
|
+ stop_process, // SIGTSTP
|
|
|
+ stop_process, // SIGTTIN
|
|
|
+ stop_process, // SIGTTOU
|
|
|
+ nullptr, // SIGURG
|
|
|
+ terminate_process_with_core_dump, // SIGXCPU
|
|
|
+ terminate_process_with_core_dump, // SIGXFSZ
|
|
|
+ terminate_process, // SIGVTALRM
|
|
|
+ terminate_process, // SIGPROF
|
|
|
+ nullptr, // SIGWINCH
|
|
|
+ terminate_process, // SIGIO, SIGPOLL
|
|
|
+ terminate_process, // SIGPWR
|
|
|
+ terminate_process_with_core_dump, // SIGSYS, SIGUNUSED
|
|
|
+};
|
|
|
+
|
|
|
+signal_list::signal_list()
|
|
|
+ : m_mask(0)
|
|
|
+{
|
|
|
+ memcpy(m_handlers, default_handlers, sizeof(m_handlers));
|
|
|
+}
|
|
|
+
|
|
|
+void signal_list::on_exec()
|
|
|
+{
|
|
|
+ for (int i = 1; i < 32; ++i) {
|
|
|
+ if (m_handlers[i])
|
|
|
+ m_handlers[i] = default_handlers[i];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void signal_list::set(signo_type signal)
|
|
|
+{
|
|
|
+ if (m_mask & (1 << signal))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!m_handlers[signal])
|
|
|
+ return;
|
|
|
+
|
|
|
+ m_list.push_back(signal);
|
|
|
+ m_mask |= (1 << signal);
|
|
|
+}
|
|
|
+
|
|
|
+signo_type signal_list::handle()
|
|
|
+{
|
|
|
+ if (this->empty())
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ auto signal = m_list.front();
|
|
|
+ m_list.pop_front();
|
|
|
+
|
|
|
+ if (!m_handlers[signal])
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ m_handlers[signal](signal);
|
|
|
+
|
|
|
+ return signal;
|
|
|
+}
|
|
|
+
|
|
|
+void signal_list::after_signal(signo_type signal)
|
|
|
+{
|
|
|
+ this->m_mask &= ~(1 << signal);
|
|
|
+}
|
|
|
+
|
|
|
+void signal_list::get_mask(sigset_t* mask) const
|
|
|
+{
|
|
|
+ if (!mask)
|
|
|
+ return;
|
|
|
+
|
|
|
+ memset(mask, 0x00, sizeof(sigset_t));
|
|
|
+ for (int i = 1; i < 32; ++i) {
|
|
|
+ if (is_masked(i))
|
|
|
+ mask->__sig[(i-1)/4] |= 3 << (i-1) % 4 * 2;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void signal_list::set_mask(const sigset_t* mask)
|
|
|
+{
|
|
|
+ if (!mask)
|
|
|
+ return;
|
|
|
+
|
|
|
+ m_mask = 0;
|
|
|
+ for (int i = 1; i < 32; ++i) {
|
|
|
+ if (mask->__sig[(i-1)/4] & (3 << (i-1) % 4 * 2))
|
|
|
+ m_mask |= (1 << i);
|
|
|
+ }
|
|
|
+}
|