/* 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 "sys_proc.h" #include "sys_io.h" #include "current.h" #include "get_proc.h" #include "signal.h" #include #include #include #include #include #include static inline int get_rpl(const struct interrupted_instruction_struct *interrupted_instruction) { struct sel_data_struct sel_data; get_sel(&interrupted_instruction->cs, &sel_data); return sel_data.rpl; } int is_orphaned_pg(int pgid) { struct proc_group_struct *proc_group; if (!(proc_group = get_proc_group(pgid))) return 0; return is_orphaned_proc_group(proc_group); } void signal_pg(int pgid, int sig) { struct proc_group_struct *proc_group; if (!(proc_group = get_proc_group(pgid))) return; signal_group(proc_group, sig); } void preempt(const struct interrupted_instruction_struct *interrupted_instruction) { if (is_idle() || get_rpl(interrupted_instruction)) /* l'interruption n'a pas interrompu un appel systeme */ yield(); } int do_invalid_syscall() { return -ENOSYS; } void *const syscall_table[] = { NULL, do_exit, do_fork, do_exec, do_getpid, do_getpgid, do_setpgid, do_chdir, do_sbrk, do_sleep, do_wait, do_kill, do_uname, do_open, do_close, do_dup, do_dup2, do_pipe, do_fcntl, do_read, do_write, do_seek, do_stat, do_ioctl, do_create, do_remove, do_mkdir, do_rmdir, do_rename, do_mount, do_umount, do_reboot, do_gettime, do_mmap, do_munmap, do_mprotect }; const unsigned int syscall_table_size = sizeof syscall_table / sizeof *syscall_table; static void __attribute__ ((noreturn)) sh_terminate(int sig) { abort(sig); } static void __attribute__ ((noreturn)) sh_abort(int sig) { abort(sig); } static void sh_ignore(int sig) {} static void sh_stop(int sig) { stop(sig); } static void sh_continue(int sig) {} typedef void (*sighandler_t)(int); static const sighandler_t signal_handler[] = { NULL, sh_terminate, /* SIGHUP */ sh_terminate, /* SIGINT */ sh_abort, /* SIGQUIT */ sh_abort, /* SIGILL */ sh_abort, /* SIGTRAP */ sh_abort, /* SIGABRT */ sh_abort, /* SIGBUS */ sh_abort, /* SIGFPE */ sh_terminate, /* SIGKILL */ sh_terminate, /* SIGUSR1 */ sh_abort, /* SIGSEGV */ sh_terminate, /* SIGUSR2 */ sh_terminate, /* SIGPIPE */ sh_terminate, /* SIGALRM */ sh_terminate, /* SIGTERM */ sh_terminate, /* SIGSTKFLT */ sh_ignore, /* SIGCHLD */ sh_continue, /* SIGCONT */ sh_stop, /* SIGSTOP */ sh_stop, /* SIGTSTP */ sh_stop, /* SIGTTIN */ sh_stop, /* SIGTTOU */ sh_ignore, /* SIGURG */ sh_abort, /* SIGXCPU */ sh_abort, /* SIGXFSZ */ sh_terminate, /* SIGVTALRM */ sh_terminate, /* SIGPROF */ sh_ignore, /* SIGWINCH */ sh_terminate, /* SIGPOLL */ sh_terminate, /* SIGPWR */ sh_abort /* SIGSYS */ }; static void handle_signals() { int sig; while ((sig = deliver_signal())) signal_handler[sig](sig); } void do_bottom_half_it(const struct interrupted_instruction_struct *interrupted_instruction) { int rpl; rpl = get_rpl(interrupted_instruction); if (rpl) /* pas de signaux pour idle */ handle_signals(); if (is_idle() || rpl) /* l'interruption n'a pas interrompu un appel systeme */ reap_orphan_zombies(); } void do_bottom_half_syscall() { handle_signals(); reap_orphan_zombies(); }