Commit 773b93ee0684a9b9d1f0029a936a251411289027

Authored by bellard
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 }
... ...