diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-02-18 22:55:36 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-02-18 22:55:36 +0000 |
commit | 31e31b8a248ffa216223dad49f75efbdfca5df23 (patch) | |
tree | 7a2e4a2e20da5bd5d61f906f6d75dab2d3418e5f /linux-user/signal.c | |
parent | e63c3dc74bfb90e4522d075d0d5a7600c5145745 (diff) |
This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r-- | linux-user/signal.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c new file mode 100644 index 0000000000..2e0d599553 --- /dev/null +++ b/linux-user/signal.c @@ -0,0 +1,105 @@ +/* + * Emulation of Linux signal handling + * + * Copyright (c) 2003 Fabrice Bellard + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <signal.h> +#include <sys/ucontext.h> + +/* Algorithm strongly inspired from em86 : we queue the signals so + that we can handle them at precise points in the emulated code. */ + +struct emulated_sigaction { + struct target_sigaction sa; + int nb_pending; + struct target_siginfo info; +}; + +struct emulated_sigaction sigact_table[NSIG]; +int signal_pending; + +static inline int host_to_target_signal(int sig) +{ + return sig; +} + +static inline int target_to_host_signal(int sig) +{ + return sig; +} + +void signal_init(void) +{ + struct sigaction act; + int i; + + /* set all host signal handlers */ + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = host_signal_handler; + for(i = 1; i < NSIG; i++) { + sigaction(i, &sa, NULL); + } + + memset(sigact_table, 0, sizeof(sigact_table)); +} + +static void host_signal_handler(int host_signum, siginfo_t *info, + void *puc) +{ + struct ucontext *uc = puc; + int signum; + /* get target signal number */ + signum = host_to_target(host_signum); + if (signum >= TARGET_NSIG) + return; + /* we save the old mask */ + + +} + + +void process_pending_signals(void) +{ + int signum; + target_ulong _sa_handler; + + struct emulated_sigaction *esig; + + if (!signal_pending) + return; + + esig = sigact_table; + for(signum = 1; signum < TARGET_NSIG; signum++) { + if (esig->nb_pending != 0) + goto handle_signal; + esig++; + } + /* if no signal is pending, just return */ + signal_pending = 0; + return; + handle_signal: + _sa_handler = esig->sa._sa_handler; + if (_sa_handler == TARGET_SIG_DFL) { + /* default handling + } + + +} |