+ pq = &k->first;
+ if (sig < TARGET_SIGRTMIN) {
+ /* if non real time signal, we queue exactly one signal */
+ if (!k->pending)
+ q = &k->info;
+ else
+ return 0;
+ } else {
+ if (!k->pending) {
+ /* first signal */
+ q = &k->info;
+ } else {
+ q = alloc_sigqueue();
+ if (!q)
+ return -EAGAIN;
+ while (*pq != NULL)
+ pq = &(*pq)->next;
+ }
+ }
+ *pq = q;
+ q->info = *info;
+ q->next = NULL;
+ k->pending = 1;
+ /* signal that a new signal is pending */
+ signal_pending = 1;
+ return 1; /* indicates that the signal was queued */
+ }
+}
+
+#if defined(DEBUG_SIGNAL)
+#ifdef __i386__
+static void dump_regs(struct ucontext *uc)
+{
+ fprintf(stderr,
+ "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
+ "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
+ "EFL=%08x EIP=%08x\n",
+ uc->uc_mcontext.gregs[EAX],
+ uc->uc_mcontext.gregs[EBX],
+ uc->uc_mcontext.gregs[ECX],
+ uc->uc_mcontext.gregs[EDX],
+ uc->uc_mcontext.gregs[ESI],
+ uc->uc_mcontext.gregs[EDI],
+ uc->uc_mcontext.gregs[EBP],
+ uc->uc_mcontext.gregs[ESP],
+ uc->uc_mcontext.gregs[EFL],
+ uc->uc_mcontext.gregs[EIP]);
+}
+#else
+static void dump_regs(struct ucontext *uc)
+{
+}
+#endif
+
+#endif
+
+static void host_signal_handler(int host_signum, siginfo_t *info,
+ void *puc)
+{
+ int sig;
+ target_siginfo_t tinfo;
+
+ /* the CPU emulator uses some host signals to detect exceptions,
+ we we forward to it some signals */
+ if (host_signum == SIGSEGV || host_signum == SIGBUS) {
+ if (cpu_x86_signal_handler(host_signum, info, puc))
+ return;
+ }
+
+ /* get target signal number */
+ sig = host_to_target_signal(host_signum);
+ if (sig < 1 || sig > TARGET_NSIG)
+ return;
+#if defined(DEBUG_SIGNAL)
+ fprintf(stderr, "gemu: got signal %d\n", sig);
+ dump_regs(puc);
+#endif
+ host_to_target_siginfo_noswap(&tinfo, info);
+ if (queue_signal(sig, &tinfo) == 1) {
+ /* interrupt the virtual CPU as soon as possible */
+ cpu_x86_interrupt(global_env);