summaryrefslogtreecommitdiff
path: root/kernel/sys_signal.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
commit8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch)
treeaa739deaac0266f17c4e91b333957501cb1ea2e9 /kernel/sys_signal.cc
parent3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff)
downloadlume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.gz
lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.xz
Remove old code
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'kernel/sys_signal.cc')
-rw-r--r--kernel/sys_signal.cc351
1 files changed, 0 insertions, 351 deletions
diff --git a/kernel/sys_signal.cc b/kernel/sys_signal.cc
deleted file mode 100644
index 8b459d5..0000000
--- a/kernel/sys_signal.cc
+++ /dev/null
@@ -1,351 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* Copyright (C) 2026 Richard Qin */
-
-/*
- * sys_signal.cc — Signal-related system calls
- *
- * Implements:
- * sys_kill (SYS_kill = 129)
- * sys_rt_sigaction (SYS_rt_sigaction = 134)
- * sys_rt_sigprocmask (SYS_rt_sigprocmask = 135)
- * sys_rt_sigreturn (SYS_rt_sigreturn = 139)
- *
- * Reference: Linux kernel/signal.c, arch/riscv/kernel/signal.c
- */
-
-#include <lume/signal.h>
-#include <lume/signal_types.h>
-#include <lume/signal_nr.h>
-#include <lume/task.h>
-#include <lume/errno.h>
-#include <lume/uaccess.h>
-#include <lume/kprintf.h>
-#include <lume/klog.h>
-#include <lume/new.h>
-#include <lume/pgrp.h>
-
-/* From signal.cc */
-extern int send_signal(int sig, kernel_siginfo* info, TaskControlBlock* task);
-
-/* From task.cc */
-extern list_node g_all_tasks;
-extern Spinlock g_task_list_lock;
-
-/* ================================================================== */
-/* Helper: find task by PID */
-/* ================================================================== */
-
-static TaskControlBlock* find_task_by_pid(int32 pid)
-{
- LockGuard guard(g_task_list_lock);
- list_node* node = g_all_tasks.next;
- while (node != &g_all_tasks) {
- auto* task = list_entry<TaskControlBlock, &TaskControlBlock::all_link>(node);
- if (task->pid == pid) return task;
- node = node->next;
- }
- return nullptr;
-}
-
-/* ================================================================== */
-/* sys_kill — send a signal to a process */
-/* ================================================================== */
-
-/*
- * Deliver `sig` to the thread-group leader represented by `sig_st`.
- * sighand is allocated eagerly at fork/exec time, so we just trust
- * that the leader has one; send_signal returns -ESRCH if not.
- */
-static int deliver_to_group(signal_struct* sig_st, int sig,
- kernel_siginfo* info)
-{
- if (!sig_st || !sig_st->leader) return 0;
- if (send_signal(sig, info, sig_st->leader) == 0) return 1;
- return 0;
-}
-
-int64 sys_kill(uint64 a0, uint64 a1, uint64, uint64, uint64, uint64)
-{
- int32 pid = static_cast<int32>(a0);
- int sig = static_cast<int>(a1);
-
- if (sig < 0 || sig > _NSIG) return -EINVAL;
-
- TaskControlBlock* curr = current_task();
- if (!curr) return -ESRCH;
-
- kernel_siginfo info{};
- info.si_signo = sig;
- info.si_code = 0; /* SI_USER */
- info._sifields._kill._pid = curr->pid;
- info._sifields._kill._uid = 0;
-
- /* pid > 0: deliver to that thread group's leader. */
- if (pid > 0) {
- TaskControlBlock* target = find_task_by_pid(pid);
- if (!target) return -ESRCH;
- /* Group signal: prefer the thread-group leader if available. */
- if (target->signal && target->signal->leader)
- target = target->signal->leader;
- if (sig == 0) return 0;
- return send_signal(sig, &info, target);
- }
-
- /* pid == 0: every member of caller's process group. */
- if (pid == 0) {
- if (!curr->signal) return -ESRCH;
- if (sig == 0) return 0;
- int delivered = 0;
- int32 target_pgid = curr->signal->pgid;
- for_each_pgrp_member(target_pgid, [&](signal_struct* s) {
- delivered += deliver_to_group(s, sig, &info);
- });
- return delivered > 0 ? 0 : -ESRCH;
- }
-
- /* pid == -1: every process the caller may signal, except init.
- * We approximate "every" with "every thread-group leader on every
- * pgrp bucket". This is rare in practice (BusyBox doesn't use it
- * during normal shell operation). */
- if (pid == -1) {
- if (sig == 0) return 0;
- int delivered = 0;
- LockGuard guard(g_pgrp_lock);
- for (auto& bucket : g_pgrp_hash) {
- list_node* node = bucket.next;
- while (node != &bucket) {
- list_node* next = node->next;
- auto* s = list_entry<signal_struct,
- &signal_struct::pgrp_link>(node);
- if (s->leader && s->leader->pid != 1)
- delivered += deliver_to_group(s, sig, &info);
- node = next;
- }
- }
- return delivered > 0 ? 0 : -ESRCH;
- }
-
- /* pid < -1: every member of pgrp |pid|. */
- int32 target_pgid = -pid;
- if (sig == 0) {
- bool any = false;
- for_each_pgrp_member(target_pgid, [&](signal_struct*) { any = true; });
- return any ? 0 : -ESRCH;
- }
- int delivered = 0;
- for_each_pgrp_member(target_pgid, [&](signal_struct* s) {
- delivered += deliver_to_group(s, sig, &info);
- });
- return delivered > 0 ? 0 : -ESRCH;
-}
-
-/* ================================================================== */
-/* sys_tkill / sys_tgkill — send a signal to a specific thread */
-/* ================================================================== */
-
-static int64 do_tkill(int32 tgid, int32 tid, int sig)
-{
- if (sig < 0 || sig > _NSIG) return -EINVAL;
- if (tid <= 0) return -EINVAL;
- TaskControlBlock* target = find_task_by_pid(tid);
- if (!target) return -ESRCH;
- /* tgid == -1 from tkill means "any tgid"; otherwise enforce match. */
- if (tgid != -1 && target->tgid != tgid) return -ESRCH;
-
- if (sig == 0) return 0;
-
- kernel_siginfo info{};
- info.si_signo = sig;
- info.si_code = 0; /* SI_TKILL would be -6; userland rarely checks */
- info._sifields._kill._pid = current_task() ? current_task()->pid : 0;
- info._sifields._kill._uid = 0;
- return send_signal(sig, &info, target);
-}
-
-int64 sys_tkill(uint64 a0, uint64 a1, uint64, uint64, uint64, uint64)
-{
- return do_tkill(-1,
- static_cast<int32>(a0),
- static_cast<int>(a1));
-}
-
-int64 sys_tgkill(uint64 a0, uint64 a1, uint64 a2, uint64, uint64, uint64)
-{
- return do_tkill(static_cast<int32>(a0),
- static_cast<int32>(a1),
- static_cast<int>(a2));
-}
-
-/* ================================================================== */
-/* sys_rt_sigaction — get/set signal disposition */
-/* ================================================================== */
-
-/*
- * User-space sigaction struct layout (RISC-V LP64):
- * uint64 sa_handler;
- * uint64 sa_flags;
- * uint64 sa_restorer; (SA_RESTORER)
- * sigset_t sa_mask; (8 bytes on LP64)
- */
-struct user_sigaction {
- uint64 sa_handler;
- uint64 sa_flags;
- uint64 sa_restorer;
- sigset_t sa_mask;
-};
-
-int64 sys_rt_sigaction(uint64 a0, uint64 a1, uint64 a2, uint64 a3,
- uint64, uint64)
-{
- int sig = static_cast<int>(a0);
- uint64 act_uaddr = a1; /* const struct sigaction __user * */
- uint64 oact_uaddr = a2; /* struct sigaction __user * */
- uint64 sigsetsize = a3;
-
- if (sig < 1 || sig > _NSIG) return -EINVAL;
- if (sig_kernel_only(sig)) return -EINVAL;
- if (sigsetsize != sizeof(sigset_t)) return -EINVAL;
-
- TaskControlBlock* curr = current_task();
- if (!curr || !curr->sighand) return -EINVAL;
-
- /* All reads/writes of the action table happen under siglock —
- * Linux's do_sigaction() also takes the same lock (kernel/signal.c). */
- user_sigaction old{};
- user_sigaction act{};
- bool have_new = (act_uaddr != 0);
-
- if (have_new) {
- int err = copy_from_user(&act, act_uaddr, sizeof(act));
- if (err < 0) return -EFAULT;
- }
-
- {
- LockGuard guard(curr->sighand->siglock);
- kernel_sigaction* ksa = &curr->sighand->action[sig - 1];
- old.sa_handler = ksa->sa_handler;
- old.sa_flags = ksa->sa_flags;
- old.sa_restorer = ksa->sa_restorer;
- old.sa_mask = ksa->sa_mask;
-
- if (have_new) {
- ksa->sa_handler = act.sa_handler;
- ksa->sa_flags = act.sa_flags;
- ksa->sa_restorer = act.sa_restorer;
- ksa->sa_mask = act.sa_mask;
- ksa->sa_mask.del(SIGKILL);
- ksa->sa_mask.del(SIGSTOP);
- }
- }
-
- if (oact_uaddr != 0) {
- int err = copy_to_user(oact_uaddr, &old, sizeof(old));
- if (err < 0) return -EFAULT;
- }
- return 0;
-}
-
-/* ================================================================== */
-/* sys_rt_sigprocmask — change signal blocked mask */
-/* ================================================================== */
-
-int64 sys_rt_sigprocmask(uint64 a0, uint64 a1, uint64 a2, uint64 a3,
- uint64, uint64)
-{
- int how = static_cast<int>(a0);
- uint64 set_uaddr = a1;
- uint64 oset_uaddr = a2;
- uint64 sigsetsize = a3;
-
- if (sigsetsize != sizeof(sigset_t)) return -EINVAL;
-
- TaskControlBlock* curr = current_task();
- if (!curr || !curr->sighand) return -EINVAL;
-
- sigset_t newset{};
- bool have_new = (set_uaddr != 0);
- if (have_new) {
- int err = copy_from_user(&newset, set_uaddr, sizeof(sigset_t));
- if (err < 0) return -EFAULT;
- newset.del(SIGKILL);
- newset.del(SIGSTOP);
- }
-
- sigset_t old{};
- {
- /* Linux: kernel/signal.c:do_sigprocmask() also holds siglock
- * across read+update so the snapshot is atomic vs. concurrent
- * signal delivery. */
- LockGuard guard(curr->sighand->siglock);
- old = curr->blocked;
- if (have_new) {
- switch (how) {
- case SIG_BLOCK:
- curr->blocked = curr->blocked | newset;
- break;
- case SIG_UNBLOCK:
- curr->blocked = curr->blocked & ~newset;
- break;
- case SIG_SETMASK:
- curr->blocked = newset;
- break;
- default:
- return -EINVAL;
- }
- }
- }
-
- if (oset_uaddr != 0) {
- int err = copy_to_user(oset_uaddr, &old, sizeof(sigset_t));
- if (err < 0) return -EFAULT;
- }
- return 0;
-}
-
-/* ================================================================== */
-/* sys_rt_sigreturn — restore context after signal handler */
-/* ================================================================== */
-
-/* Arch-specific: implemented in arch/riscv/signal.cc */
-extern int64 arch_sigreturn(arch::TrapFrame* tf);
-
-int64 sys_rt_sigreturn(uint64, uint64, uint64, uint64, uint64, uint64)
-{
- TaskControlBlock* curr = current_task();
- if (!curr || !curr->trapframe) return -EINVAL;
-
- return arch_sigreturn(curr->trapframe);
-}
-
-/* ================================================================== */
-/* sys_rt_sigtimedwait (SYS_rt_sigtimedwait = 137) */
-/* ================================================================== */
-#include <lume/timer.h>
-#include <lume/sched.h>
-
-struct linux_timespec {
- int64 tv_sec;
- int64 tv_nsec;
-};
-
-int64 sys_rt_sigtimedwait(uint64 /* set_ptr */, uint64 /* info_ptr */, uint64 timeout_ptr, uint64 /* sigsetsize */, uint64, uint64)
-{
- /*
- * COMPATIBILITY STUB:
- * LumeOS lacks full real-time signal queues and timed waiting mechanism.
- * When BusyBox init runs out of children to reap, it calls this to wait
- * for incoming signals (like SIGCHLD) with a timeout.
- * We simulate the timeout by yielding the CPU, then return -EAGAIN (Try again)
- * which tells user space that the timeout expired without receiving a signal.
- */
- if (timeout_ptr != 0) {
- linux_timespec req;
- if (copy_from_user(&req, timeout_ptr, sizeof(req)) == 0) {
- uint64 target = g_jiffies + (req.tv_sec * 100) + (req.tv_nsec / 10000000);
- while (g_jiffies < target) {
- schedule();
- }
- }
- }
- return -EAGAIN;
-}