1 #include <lunaix/process.h>
2 #include <lunaix/sched.h>
3 #include <lunaix/signal.h>
4 #include <lunaix/spike.h>
5 #include <lunaix/status.h>
6 #include <lunaix/syscall.h>
7 #include <lunaix/syslog.h>
11 #include <klibc/string.h>
13 extern struct scheduler sched_ctx; /* kernel/sched.c */
15 #define UNMASKABLE (sigset(SIGKILL) | sigset(SIGTERM))
16 #define TERMSIG (sigset(SIGSEGV) | sigset(SIGINT) | UNMASKABLE)
17 #define CORE (sigset(SIGSEGV))
20 signal_terminate(int errcode)
22 terminate_proc(errcode | PEXITSIG);
25 // Referenced in kernel/asm/x86/interrupt.S
29 if (!__current->sigctx.sig_pending) {
34 struct sighail* psig = &__current->sigctx;
35 struct sigact* prev_working = psig->inprogress;
36 sigset_t mask = psig->sig_mask | (prev_working ? prev_working->sa_mask : 0);
38 int sig_selected = 31 - __builtin_clz(psig->sig_pending & ~mask);
40 sigset_clear(psig->sig_pending, sig_selected);
42 struct sigact* action = &psig->signals[sig_selected];
44 if (sig_selected == 0) {
49 if (!action->sa_actor) {
50 if (sigset_test(TERMSIG, sig_selected)) {
51 signal_terminate(sig_selected);
58 ptr_t ustack = __current->ustack_top;
60 if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) {
65 struct proc_sig* sigframe =
66 (struct proc_sig*)((ustack - sizeof(struct proc_sig)) & ~0xf);
68 sigframe->sig_num = sig_selected;
69 sigframe->sigact = action->sa_actor;
70 sigframe->sighand = action->sa_handler;
72 sigframe->saved_ictx = __current->intr_ctx;
74 action->prev = prev_working;
75 psig->inprogress = action;
81 proc_clear_signal(struct proc_info* proc)
83 memset(&proc->sigctx, 0, sizeof(proc->sigctx));
87 proc_setsignal(struct proc_info* proc, int signum)
89 sigset_add(proc->sigctx.sig_pending, signum);
90 proc->sigctx.signals[signum].sender = __current->pid;
94 signal_send(pid_t pid, int signum)
96 if (signum < 0 || signum >= _SIG_NUM) {
97 __current->k_status = EINVAL;
101 pid_t sender_pid = __current->pid;
102 struct proc_info* proc;
105 proc = get_process(pid);
110 } else if (pid < -1) {
111 proc = get_process(-pid);
114 // TODO: send to all process.
115 // But I don't want to support it yet.
116 __current->k_status = EINVAL;
121 struct proc_info *pos, *n;
122 llist_for_each(pos, n, &proc->grp_member, grp_member)
124 struct sighail* sh = &pos->sigctx;
125 sigset_add(sh->sig_pending, signum);
126 sh->signals[signum].sender = sender_pid;
130 if (proc_terminated(proc)) {
131 __current->k_status = EINVAL;
135 sigset_add(proc->sigctx.sig_pending, signum);
136 proc->sigctx.signals[signum].sender = sender_pid;
141 __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
143 __current->intr_ctx = sig_ctx->saved_ictx;
145 struct sigact* current = __current->sigctx.inprogress;
147 __current->sigctx.inprogress = current->prev;
148 current->prev = NULL;
150 __current->sigctx.inprogress = NULL;
153 if (proc_terminated(__current)) {
154 __current->exit_code |= PEXITSIG;
155 } else if (sigset_test(CORE, sig_ctx->sig_num)) {
156 signal_terminate(sig_ctx->sig_num);
159 ptr_t ictx = (ptr_t)__current->intr_ctx;
162 Ensure our restored context is within kernel stack
164 This prevent user to forge their own context such that arbitrary code
165 can be executed as supervisor level
167 if (!within_kstack(ictx)) {
168 signal_terminate(SIGSEGV);
177 __DEFINE_LXSYSCALL3(int,
186 struct sighail* sh = &__current->sigctx;
187 *oldset = sh->sig_mask;
189 if (how == _SIG_BLOCK) {
190 sigset_union(sh->sig_mask, *set);
191 } else if (how == _SIG_UNBLOCK) {
192 sigset_intersect(sh->sig_mask, ~(*set));
193 } else if (how == _SIG_SETMASK) {
199 sigset_intersect(sh->sig_mask, ~UNMASKABLE);
203 __DEFINE_LXSYSCALL2(int, sys_sigaction, int, signum, struct sigaction*, action)
205 if (signum <= 0 || signum >= _SIG_NUM) {
209 if (sigset_test(UNMASKABLE, signum)) {
213 struct sigact* sa = &__current->sigctx.signals[signum];
215 sa->sa_actor = (void*)action->sa_sigaction;
216 sa->sa_handler = (void*)action->sa_handler;
217 sigset_union(sa->sa_mask, sigset(signum));
222 __DEFINE_LXSYSCALL(int, pause)
227 __current->k_status = EINTR;
231 __DEFINE_LXSYSCALL2(int, kill, pid_t, pid, int, signum)
233 return signal_send(pid, signum);
236 __DEFINE_LXSYSCALL1(int, sigpending, sigset_t, *sigset)
238 *sigset = __current->sigctx.sig_pending;
242 __DEFINE_LXSYSCALL1(int, sigsuspend, sigset_t, *mask)
244 sigset_t tmp = __current->sigctx.sig_mask;
245 __current->sigctx.sig_mask = (*mask) & ~UNMASKABLE;
250 __current->sigctx.sig_mask = tmp;