1 #include <lunaix/lunistd.h>
2 #include <lunaix/lxsignal.h>
3 #include <lunaix/process.h>
4 #include <lunaix/sched.h>
5 #include <lunaix/signal.h>
6 #include <lunaix/spike.h>
7 #include <lunaix/status.h>
8 #include <lunaix/syscall.h>
10 extern struct scheduler sched_ctx; /* kernel/sched.c */
13 default_sighandler_term(int signum)
18 void* default_handlers[_SIG_NUM] = {
20 [_SIGINT] = default_sighandler_term, [_SIGTERM] = default_sighandler_term,
21 [_SIGKILL] = default_sighandler_term, [_SIGSEGV] = default_sighandler_term,
22 [_SIGINT] = default_sighandler_term,
25 // Referenced in kernel/asm/x86/interrupt.S
29 if (!__current->sig_pending) {
35 31 - __builtin_clz(__current->sig_pending &
36 ~(__current->sig_mask | __current->sig_inprogress));
38 __SIGCLEAR(__current->sig_pending, sig_selected);
40 if (sig_selected == 0) {
45 if (!__current->sig_handler[sig_selected] &&
46 !default_handlers[sig_selected]) {
51 uintptr_t ustack = __current->ustack_top & ~0xf;
53 if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) {
58 struct proc_sig* sig_ctx =
59 (struct proc_sig*)(ustack - sizeof(struct proc_sig));
61 sig_ctx->prev_context = __current->intr_ctx;
62 sig_ctx->sig_num = sig_selected;
63 sig_ctx->signal_handler = __current->sig_handler[sig_selected];
65 if (!sig_ctx->signal_handler) {
66 // 如果没有用户自定义的Handler,则使用系统默认Handler。
67 sig_ctx->signal_handler = default_handlers[sig_selected];
70 __SIGSET(__current->sig_inprogress, sig_selected);
76 signal_send(pid_t pid, int signum)
78 if (signum < 0 || signum >= _SIG_NUM) {
79 __current->k_status = LXINVL;
83 struct proc_info* proc;
85 proc = get_process(pid);
90 } else if (pid < -1) {
91 proc = get_process(-pid);
94 // TODO: send to all process.
95 // But I don't want to support it yet.
96 __current->k_status = LXINVL;
101 struct proc_info *pos, *n;
102 llist_for_each(pos, n, &proc->grp_member, grp_member)
104 __SIGSET(pos->sig_pending, signum);
109 if (PROC_TERMINATED(proc->state)) {
110 __current->k_status = LXINVL;
113 __SIGSET(proc->sig_pending, signum);
117 __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
119 __current->intr_ctx = sig_ctx->prev_context;
120 __current->flags &= ~PROC_FINPAUSE;
121 __SIGCLEAR(__current->sig_inprogress, sig_ctx->sig_num);
125 __DEFINE_LXSYSCALL3(int,
134 *oldset = __current->sig_mask;
135 if (how == _SIG_BLOCK) {
136 __current->sig_mask |= *set;
137 } else if (how == _SIG_UNBLOCK) {
138 __current->sig_mask &= ~(*set);
139 } else if (how == _SIG_SETMASK) {
140 __current->sig_mask = *set;
144 __current->sig_mask &= ~_SIGNAL_UNMASKABLE;
148 __DEFINE_LXSYSCALL2(int, signal, int, signum, sighandler_t, handler)
150 if (signum <= 0 || signum >= _SIG_NUM) {
154 if ((__SIGNAL(signum) & _SIGNAL_UNMASKABLE)) {
158 __current->sig_handler[signum] = (void*)handler;
163 __DEFINE_LXSYSCALL(int, pause)
165 __current->flags |= PROC_FINPAUSE;
167 __SYSCALL_INTERRUPTIBLE({
168 while ((__current->flags & PROC_FINPAUSE)) {
172 __current->k_status = EINTR;
176 __DEFINE_LXSYSCALL2(int, kill, pid_t, pid, int, signum)
178 return signal_send(pid, signum);