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