Commit 773b93ee0684a9b9d1f0029a936a251411289027
1 parent
82c7e2a4
signal fix: update the host signal 'signal ignored' state to avoid unexpected -E…
…INTR values (ash fix) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@503 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
23 additions
and
29 deletions
linux-user/signal.c
... | ... | @@ -370,33 +370,6 @@ int queue_signal(int sig, target_siginfo_t *info) |
370 | 370 | } |
371 | 371 | } |
372 | 372 | |
373 | -#if defined(DEBUG_SIGNAL) | |
374 | -#ifdef __i386__ | |
375 | -static void dump_regs(struct ucontext *uc) | |
376 | -{ | |
377 | - fprintf(stderr, | |
378 | - "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" | |
379 | - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" | |
380 | - "EFL=%08x EIP=%08x\n", | |
381 | - uc->uc_mcontext.gregs[EAX], | |
382 | - uc->uc_mcontext.gregs[EBX], | |
383 | - uc->uc_mcontext.gregs[ECX], | |
384 | - uc->uc_mcontext.gregs[EDX], | |
385 | - uc->uc_mcontext.gregs[ESI], | |
386 | - uc->uc_mcontext.gregs[EDI], | |
387 | - uc->uc_mcontext.gregs[EBP], | |
388 | - uc->uc_mcontext.gregs[ESP], | |
389 | - uc->uc_mcontext.gregs[EFL], | |
390 | - uc->uc_mcontext.gregs[EIP]); | |
391 | -} | |
392 | -#else | |
393 | -static void dump_regs(struct ucontext *uc) | |
394 | -{ | |
395 | -} | |
396 | -#endif | |
397 | - | |
398 | -#endif | |
399 | - | |
400 | 373 | static void host_signal_handler(int host_signum, siginfo_t *info, |
401 | 374 | void *puc) |
402 | 375 | { |
... | ... | @@ -416,7 +389,6 @@ static void host_signal_handler(int host_signum, siginfo_t *info, |
416 | 389 | return; |
417 | 390 | #if defined(DEBUG_SIGNAL) |
418 | 391 | fprintf(stderr, "qemu: got signal %d\n", sig); |
419 | - dump_regs(puc); | |
420 | 392 | #endif |
421 | 393 | host_to_target_siginfo_noswap(&tinfo, info); |
422 | 394 | if (queue_signal(sig, &tinfo) == 1) { |
... | ... | @@ -429,11 +401,13 @@ int do_sigaction(int sig, const struct target_sigaction *act, |
429 | 401 | struct target_sigaction *oact) |
430 | 402 | { |
431 | 403 | struct emulated_sigaction *k; |
404 | + struct sigaction act1; | |
405 | + int host_sig; | |
432 | 406 | |
433 | 407 | if (sig < 1 || sig > TARGET_NSIG) |
434 | 408 | return -EINVAL; |
435 | 409 | k = &sigact_table[sig - 1]; |
436 | -#if defined(DEBUG_SIGNAL) && 0 | |
410 | +#if defined(DEBUG_SIGNAL) | |
437 | 411 | fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", |
438 | 412 | sig, (int)act, (int)oact); |
439 | 413 | #endif |
... | ... | @@ -448,6 +422,26 @@ int do_sigaction(int sig, const struct target_sigaction *act, |
448 | 422 | k->sa.sa_flags = tswapl(act->sa_flags); |
449 | 423 | k->sa.sa_restorer = tswapl(act->sa_restorer); |
450 | 424 | k->sa.sa_mask = act->sa_mask; |
425 | + | |
426 | + /* we update the host linux signal state */ | |
427 | + host_sig = target_to_host_signal(sig); | |
428 | + if (host_sig != SIGSEGV && host_sig != SIGBUS) { | |
429 | + sigfillset(&act1.sa_mask); | |
430 | + act1.sa_flags = SA_SIGINFO; | |
431 | + if (k->sa.sa_flags & TARGET_SA_RESTART) | |
432 | + act1.sa_flags |= SA_RESTART; | |
433 | + /* NOTE: it is important to update the host kernel signal | |
434 | + ignore state to avoid getting unexpected interrupted | |
435 | + syscalls */ | |
436 | + if (k->sa._sa_handler == TARGET_SIG_IGN) { | |
437 | + act1.sa_sigaction = (void *)SIG_IGN; | |
438 | + } else if (k->sa._sa_handler == TARGET_SIG_DFL) { | |
439 | + act1.sa_sigaction = (void *)SIG_DFL; | |
440 | + } else { | |
441 | + act1.sa_sigaction = host_signal_handler; | |
442 | + } | |
443 | + sigaction(host_sig, &act1, NULL); | |
444 | + } | |
451 | 445 | } |
452 | 446 | return 0; |
453 | 447 | } | ... | ... |