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,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 | static void host_signal_handler(int host_signum, siginfo_t *info, | 373 | static void host_signal_handler(int host_signum, siginfo_t *info, |
| 401 | void *puc) | 374 | void *puc) |
| 402 | { | 375 | { |
| @@ -416,7 +389,6 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | @@ -416,7 +389,6 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | ||
| 416 | return; | 389 | return; |
| 417 | #if defined(DEBUG_SIGNAL) | 390 | #if defined(DEBUG_SIGNAL) |
| 418 | fprintf(stderr, "qemu: got signal %d\n", sig); | 391 | fprintf(stderr, "qemu: got signal %d\n", sig); |
| 419 | - dump_regs(puc); | ||
| 420 | #endif | 392 | #endif |
| 421 | host_to_target_siginfo_noswap(&tinfo, info); | 393 | host_to_target_siginfo_noswap(&tinfo, info); |
| 422 | if (queue_signal(sig, &tinfo) == 1) { | 394 | if (queue_signal(sig, &tinfo) == 1) { |
| @@ -429,11 +401,13 @@ int do_sigaction(int sig, const struct target_sigaction *act, | @@ -429,11 +401,13 @@ int do_sigaction(int sig, const struct target_sigaction *act, | ||
| 429 | struct target_sigaction *oact) | 401 | struct target_sigaction *oact) |
| 430 | { | 402 | { |
| 431 | struct emulated_sigaction *k; | 403 | struct emulated_sigaction *k; |
| 404 | + struct sigaction act1; | ||
| 405 | + int host_sig; | ||
| 432 | 406 | ||
| 433 | if (sig < 1 || sig > TARGET_NSIG) | 407 | if (sig < 1 || sig > TARGET_NSIG) |
| 434 | return -EINVAL; | 408 | return -EINVAL; |
| 435 | k = &sigact_table[sig - 1]; | 409 | k = &sigact_table[sig - 1]; |
| 436 | -#if defined(DEBUG_SIGNAL) && 0 | 410 | +#if defined(DEBUG_SIGNAL) |
| 437 | fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", | 411 | fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", |
| 438 | sig, (int)act, (int)oact); | 412 | sig, (int)act, (int)oact); |
| 439 | #endif | 413 | #endif |
| @@ -448,6 +422,26 @@ int do_sigaction(int sig, const struct target_sigaction *act, | @@ -448,6 +422,26 @@ int do_sigaction(int sig, const struct target_sigaction *act, | ||
| 448 | k->sa.sa_flags = tswapl(act->sa_flags); | 422 | k->sa.sa_flags = tswapl(act->sa_flags); |
| 449 | k->sa.sa_restorer = tswapl(act->sa_restorer); | 423 | k->sa.sa_restorer = tswapl(act->sa_restorer); |
| 450 | k->sa.sa_mask = act->sa_mask; | 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 | return 0; | 446 | return 0; |
| 453 | } | 447 | } |