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 | } | ... | ... |