X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/2803826a2373620dbfce8a5bff1e6a01dd594953..cb529e7c1abcfe6b61241e47a780172031b82840:/lunaix-os/kernel/signal.c diff --git a/lunaix-os/kernel/signal.c b/lunaix-os/kernel/signal.c index 80a7098..c3a6c07 100644 --- a/lunaix-os/kernel/signal.c +++ b/lunaix-os/kernel/signal.c @@ -1,33 +1,45 @@ +#include +#include #include #include #include +#include #include #include extern struct scheduler sched_ctx; /* kernel/sched.c */ +void __USER__ +default_sighandler_term(int signum) +{ + _exit(signum); +} + void* default_handlers[_SIG_NUM] = { // TODO: 添加默认handler + [_SIGINT] = default_sighandler_term, + [_SIGTERM] = default_sighandler_term, }; // Referenced in kernel/asm/x86/interrupt.S void* signal_dispatch() { - // if (!(SEL_RPL(__current->intr_ctx.cs))) { - // // 同特权级间调度不进行信号处理 - // return 0; - // } - if (!__current->sig_pending) { // 没有待处理信号 return 0; } int sig_selected = - 31 - __builtin_clz(__current->sig_pending & ~__current->sig_mask); + 31 - __builtin_clz(__current->sig_pending & + ~(__current->sig_mask | __current->sig_inprogress)); - __current->sig_pending = __current->sig_pending & ~__SIGNAL(sig_selected); + __SIGCLEAR(__current->sig_pending, sig_selected); + + if (sig_selected == 0) { + // SIG0 is reserved + return 0; + } if (!__current->sig_handler[sig_selected] && !default_handlers[sig_selected]) { @@ -54,16 +66,58 @@ signal_dispatch() sig_ctx->signal_handler = default_handlers[sig_selected]; } - __current->sig_mask |= __SIGNAL(sig_selected); + __SIGSET(__current->sig_inprogress, sig_selected); return sig_ctx; } +int +signal_send(pid_t pid, int signum) +{ + if (signum < 0 || signum >= _SIG_NUM) { + __current->k_status = LXINVL; + return -1; + } + + struct proc_info* proc; + if (pid > 0) { + proc = get_process(pid); + goto send_single; + } else if (!pid) { + proc = __current; + goto send_grp; + } else if (pid < -1) { + proc = get_process(-pid); + goto send_grp; + } else { + // TODO: send to all process. + // But I don't want to support it yet. + __current->k_status = LXINVL; + return -1; + } + +send_grp: + struct proc_info *pos, *n; + llist_for_each(pos, n, &proc->grp_member, grp_member) + { + __SIGSET(pos->sig_pending, signum); + } + return 0; + +send_single: + if ((proc->state & PROC_TERMMASK)) { + __current->k_status = LXINVL; + return -1; + } + __SIGSET(proc->sig_pending, signum); + return 0; +} + __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx) { __current->intr_ctx = sig_ctx->prev_context; - __current->sig_mask &= ~__SIGNAL(sig_ctx->sig_num); __current->flags &= ~PROC_FINPAUSE; + __SIGCLEAR(__current->sig_inprogress, sig_ctx->sig_num); schedule(); } @@ -92,11 +146,11 @@ __DEFINE_LXSYSCALL3(int, __DEFINE_LXSYSCALL2(int, signal, int, signum, sighandler_t, handler) { - if (signum < 0 || signum >= _SIG_NUM) { + if (signum <= 0 || signum >= _SIG_NUM) { return -1; } - if (((1 << signum) & _SIGNAL_UNMASKABLE)) { + if ((__SIGNAL(signum) & _SIGNAL_UNMASKABLE)) { return -1; } @@ -116,4 +170,9 @@ __DEFINE_LXSYSCALL(int, pause) }) __current->k_status = EINTR; return -1; +} + +__DEFINE_LXSYSCALL2(int, kill, pid_t, pid, int, signum) +{ + return signal_send(pid, signum); } \ No newline at end of file