/* Copyright (C) 2008 Emmanuel Varoquaux This file is part of XOS. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sched.h" #include "proc.h" #include "idle.h" #include "proc_struct.h" #include #include #include #include static void generate_signal(struct proc_struct *proc, int sig) { if (proc->state == PS_ZOMBIE) return; if (proc->system) return; if (!sig) return; switch (sig) { case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: proc->signal &= ~(1UL << SIGCONT); break; case SIGCONT: proc->signal &= ~(1UL << SIGSTOP | 1UL << SIGTSTP | 1UL << SIGTTIN | 1UL << SIGTTOU); break; case SIGCHLD: case SIGURG: case SIGWINCH: return; /* signaux ignores par defaut */ } proc->signal |= 1UL << sig; if (proc->state != PS_RUNNING) { switch (proc->state) { case PS_WAITING_UNINTERRUPTIBLE: /* ininterruptible ! */ break; case PS_WAITING_INTERRUPTIBLE: condition_interrupt(proc); break; case PS_SLEEPING: sleep_interrupt(proc); break; case PS_STOPPED: if (sig == SIGKILL || sig == SIGCONT) stop_continue(proc); break; } } } void signal_init(struct proc_struct *proc, int system) { proc->system = system ? 1 : 0; proc->signal = 0; } int signal(struct proc_struct *proc, int sig) { int retval; int intr; disable_intr(intr); if (proc == idle) { retval = -EPERM; goto restore; } generate_signal(proc, sig); retval = 0; restore: restore_intr(intr); return retval; } void signal_group(struct proc_group_struct *proc_group, int sig) { int intr; struct proc_struct *proc; disable_intr(intr); for (proc = proc_group->first_proc; proc; proc = proc->group_next) { if (proc == idle) continue; generate_signal(proc, sig); } restore_intr(intr); } void signal_all(int sig) { int intr; struct proc_struct *proc; disable_intr(intr); for (proc = proc_list_first; proc; proc = proc->proc_list_next) { if (proc == idle) continue; generate_signal(proc, sig); } restore_intr(intr); } int deliver_signal() { int sig; int intr; disable_intr(intr); sig = 0; if (current->signal) { while (!(current->signal & 1UL << ++sig)); current->signal &= ~(1UL << sig); } restore_intr(intr); return sig; }