diff options
Diffstat (limited to 'na/test/test_signal.cc')
| -rw-r--r-- | na/test/test_signal.cc | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/na/test/test_signal.cc b/na/test/test_signal.cc deleted file mode 100644 index 360b0e6..0000000 --- a/na/test/test_signal.cc +++ /dev/null @@ -1,193 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -/* - * test_signal.cc — Self-tests for signal infrastructure - * - * Tests the kernel-internal signal APIs directly (not via syscalls, - * since syscalls use copy_to_user which rejects kernel-space buffers). - */ - -#include <lume/selftest.h> -#include <lume/signal.h> -#include <lume/signal_types.h> -#include <lume/signal_nr.h> -#include <lume/task.h> -#include <lume/errno.h> -#include <lume/new.h> - -/* From signal.cc */ -extern int send_signal(int sig, kernel_siginfo* info, TaskControlBlock* task); - -/* Drain all queued sigqueue entries from a task's pending list */ -static void flush_pending(TaskControlBlock* task) -{ - task->pending.signal = sigset_t{}; - list_node* head = &task->pending.list; - while (head->next != head) { - list_node* node = head->next; - head->next = node->next; - node->next->prev = head; - auto* q = list_entry<sigqueue, &sigqueue::list>(node); - delete q; - } -} - -void selftest_signal() -{ - TaskControlBlock* curr = current_task(); - - /* Ensure sighand exists for this task */ - if (!curr->sighand) { - curr->sighand = new sighand_struct; - curr->sighand->init(); - } - - /* Ensure pending list is initialized */ - if (curr->pending.list.next == nullptr) { - curr->pending.list.next = &curr->pending.list; - curr->pending.list.prev = &curr->pending.list; - curr->pending.signal = sigset_t{}; - } - - /* ---- send_signal queues a signal ---- */ - st_begin("signal: send_signal queues to pending"); - { - curr->pending.signal = sigset_t{}; - - kernel_siginfo info{}; - info.si_signo = SIGUSR1; - info.si_code = 0; - - int ret = send_signal(SIGUSR1, &info, curr); - ST_ASSERT_EQ(ret, 0); - ST_ASSERT(curr->pending.signal.has(SIGUSR1)); - - flush_pending(curr); - } - st_pass(); - - /* ---- send_signal: invalid signal returns -EINVAL ---- */ - st_begin("signal: send_signal invalid sig returns -EINVAL"); - { - int ret = send_signal(0, nullptr, curr); - ST_ASSERT_EQ(ret, -EINVAL); - - ret = send_signal(_NSIG + 1, nullptr, curr); - ST_ASSERT_EQ(ret, -EINVAL); - } - st_pass(); - - /* ---- send_signal: null task returns -ESRCH ---- */ - st_begin("signal: send_signal null task returns -ESRCH"); - { - int ret = send_signal(SIGUSR1, nullptr, nullptr); - ST_ASSERT_EQ(ret, -ESRCH); - } - st_pass(); - - /* ---- duplicate standard signal is coalesced ---- */ - st_begin("signal: duplicate standard signal coalesced"); - { - curr->pending.signal = sigset_t{}; - - send_signal(SIGUSR1, nullptr, curr); - ST_ASSERT(curr->pending.signal.has(SIGUSR1)); - - int ret = send_signal(SIGUSR1, nullptr, curr); - ST_ASSERT_EQ(ret, 0); - - flush_pending(curr); - } - st_pass(); - - /* ---- sigset_t: add/del/has ---- */ - st_begin("signal: sigset_t add/del/has"); - { - sigset_t s{}; - ST_ASSERT(!s.has(SIGUSR1)); - s.add(SIGUSR1); - ST_ASSERT(s.has(SIGUSR1)); - s.del(SIGUSR1); - ST_ASSERT(!s.has(SIGUSR1)); - } - st_pass(); - - /* ---- sigset_t: bitwise operators ---- */ - st_begin("signal: sigset_t bitwise OR and AND"); - { - sigset_t a{}; - a.add(SIGUSR1); - sigset_t b{}; - b.add(SIGUSR2); - - sigset_t c = a | b; - ST_ASSERT(c.has(SIGUSR1)); - ST_ASSERT(c.has(SIGUSR2)); - - sigset_t d = c & a; - ST_ASSERT(d.has(SIGUSR1)); - ST_ASSERT(!d.has(SIGUSR2)); - } - st_pass(); - - /* ---- blocked mask: direct manipulation ---- */ - st_begin("signal: blocked mask direct manipulation"); - { - sigset_t saved = curr->blocked; - curr->blocked = sigset_t{}; - - curr->blocked.add(SIGUSR1); - curr->blocked.add(SIGUSR2); - ST_ASSERT(curr->blocked.has(SIGUSR1)); - ST_ASSERT(curr->blocked.has(SIGUSR2)); - - curr->blocked.del(SIGUSR1); - ST_ASSERT(!curr->blocked.has(SIGUSR1)); - ST_ASSERT(curr->blocked.has(SIGUSR2)); - - curr->blocked = saved; - } - st_pass(); - - /* ---- sighand action table ---- */ - st_begin("signal: sighand action table defaults to SIG_DFL"); - { - /* All handlers should default to SIG_DFL (0) */ - kernel_sigaction* ka = &curr->sighand->action[SIGUSR1 - 1]; - ST_ASSERT_EQ(ka->sa_handler, (uint64)SIG_DFL); - - /* Set a handler and verify */ - ka->sa_handler = 0x12345678ULL; - ST_ASSERT_EQ(ka->sa_handler, (uint64)0x12345678ULL); - - /* Reset */ - ka->sa_handler = SIG_DFL; - } - st_pass(); - - /* ---- sig_kernel_only rejects SIGKILL/SIGSTOP handlers ---- */ - st_begin("signal: SIGKILL/SIGSTOP are kernel-only"); - { - ST_ASSERT(sig_kernel_only(SIGKILL)); - ST_ASSERT(sig_kernel_only(SIGSTOP)); - ST_ASSERT(!sig_kernel_only(SIGUSR1)); - ST_ASSERT(!sig_kernel_only(SIGINT)); - } - st_pass(); - - /* ---- sig_default_action correctness ---- */ - st_begin("signal: sig_default_action returns correct actions"); - { - ST_ASSERT_EQ((int)sig_default_action(SIGCHLD), (int)SIG_ACT_IGN); - ST_ASSERT_EQ((int)sig_default_action(SIGKILL), (int)SIG_ACT_TERM); - ST_ASSERT_EQ((int)sig_default_action(SIGSTOP), (int)SIG_ACT_STOP); - ST_ASSERT_EQ((int)sig_default_action(SIGCONT), (int)SIG_ACT_CONT); - ST_ASSERT_EQ((int)sig_default_action(SIGSEGV), (int)SIG_ACT_CORE); - } - st_pass(); - - /* Clean up */ - flush_pending(curr); - curr->blocked = sigset_t{}; -} |
