Merge branch 'master' into signal-dev
[lunaix-os.git] / lunaix-os / kernel / signal.c
1 #include <lunaix/process.h>
2 #include <lunaix/sched.h>
3 #include <lunaix/signal.h>
4 #include <lunaix/syscall.h>
5
6 extern struct scheduler sched_ctx; /* kernel/sched.c */
7
8 void* default_handlers[_SIG_NUM] = {
9     // TODO: 添加默认handler
10 };
11
12 void
13 signal_dispatch()
14 {
15     // if (!(SEL_RPL(__current->intr_ctx.cs))) {
16     //     // 同特权级间调度不进行信号处理
17     //     return;
18     // }
19
20     if (!__current->sig_pending) {
21         // 没有待处理信号
22         return;
23     }
24
25     int sig_selected =
26       31 - __builtin_clz(__current->sig_pending & ~__current->sig_mask);
27
28     __current->sig_pending = __current->sig_pending & ~(1 << sig_selected);
29
30     if (!__current->sig_handler[sig_selected] &&
31         !default_handlers[sig_selected]) {
32         // 如果该信号没有handler,则忽略
33         return;
34     }
35
36     uintptr_t ustack = __current->ustack_top;
37
38     if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) {
39         // 用户栈没有空间存放信号上下文
40         return;
41     }
42
43     struct proc_sig* sig_ctx =
44       (struct proc_sig*)(ustack - sizeof(struct proc_sig));
45
46     sig_ctx->prev_context = __current->intr_ctx;
47     sig_ctx->sig_num = sig_selected;
48     sig_ctx->signal_handler = __current->sig_handler[sig_selected];
49
50     if (!sig_ctx->signal_handler) {
51         // 如果没有用户自定义的Handler,则使用系统默认Handler。
52         sig_ctx->signal_handler = default_handlers[sig_selected];
53     }
54
55     asm volatile("pushl %0\n"
56                  "jmp handle_signal" ::"r"(sig_ctx));
57 }
58
59 __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
60 {
61     __current->intr_ctx = sig_ctx->prev_context;
62     schedule();
63 }
64
65 __DEFINE_LXSYSCALL3(int,
66                     sigprocmask,
67                     int,
68                     how,
69                     const sigset_t,
70                     *set,
71                     sigset_t,
72                     *oldset)
73 {
74     *oldset = __current->sig_mask;
75     if (how == _SIG_BLOCK) {
76         __current->sig_mask |= *set;
77     } else if (how == _SIG_UNBLOCK) {
78         __current->sig_mask &= ~(*set);
79     } else if (how == _SIG_SETMASK) {
80         __current->sig_mask = *set;
81     } else {
82         return 0;
83     }
84     __current->sig_mask &= ~_SIGNAL_UNMASKABLE;
85     return 1;
86 }
87
88 __DEFINE_LXSYSCALL2(int, signal, int, signum, sighandler_t, handler)
89 {
90     if (signum < 0 || signum >= _SIG_NUM) {
91         return -1;
92     }
93
94     if (((1 << signum) & _SIGNAL_UNMASKABLE)) {
95         return -1;
96     }
97
98     __current->sig_handler[signum] = (void*)handler;
99
100     return 0;
101 }