diff --git a/ChangeLog b/ChangeLog index ed84679ddd..3c3a083f0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun May 11 01:10:31 2014 Nobuyoshi Nakada + + * signal.c (rb_f_kill): directly enqueue an ignored signal to self, + except for SIGSEGV and SIGBUS. [ruby-dev:48203] [Bug #9820] + Sat May 10 22:37:56 2014 Nobuyoshi Nakada * dir.c (push_glob): match in UTF-8 on Mac OS X. diff --git a/signal.c b/signal.c index 7dc4247220..82c9125c90 100644 --- a/signal.c +++ b/signal.c @@ -350,6 +350,9 @@ ruby_default_signal(int sig) raise(sig); } +static int signal_ignored(int sig); +static void signal_enque(int sig); + /* * call-seq: * Process.kill(signal, pid, ...) -> fixnum @@ -436,6 +439,8 @@ rb_f_kill(int argc, VALUE *argv) break; } + if (argc <= 1) return INT2FIX(0); + if (sig < 0) { sig = -sig; for (i=1; imain_thread) ? getpid() : -1; + int wakeup = 0; + for (i=1; imain_thread); } } rb_thread_execute_interrupts(rb_thread_current()); @@ -578,11 +611,32 @@ ruby_nativethread_signal(int signum, sighandler_t handler) #endif #endif -static RETSIGTYPE -sighandler(int sig) +static int +signal_ignored(int sig) +{ +#ifdef POSIX_SIGNAL + struct sigaction old; + (void)VALGRIND_MAKE_MEM_DEFINED(&old, sizeof(old)); + if (sigaction(sig, NULL, &old) < 0) return FALSE; + return old.sa_handler == SIG_IGN; +#else + sighandler_t old = signal(sig, SIG_DFL); + signal(sig, old); + return old == SIG_IGN; +#endif +} + +static void +signal_enque(int sig) { ATOMIC_INC(signal_buff.cnt[sig]); ATOMIC_INC(signal_buff.size); +} + +static RETSIGTYPE +sighandler(int sig) +{ + signal_enque(sig); rb_thread_wakeup_timer_thread(); #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) ruby_signal(sig, sighandler); diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb index 6493f6c7ef..70b6c2bb4c 100644 --- a/test/ruby/test_signal.rb +++ b/test/ruby/test_signal.rb @@ -276,4 +276,15 @@ EOS } } end if Process.respond_to?(:kill) and Signal.list.key?('HUP') + + def test_ignored_interrupt + bug9820 = '[ruby-dev:48203] [Bug #9820]' + assert_separately(['-', bug9820], <<-'end;') # begin + bug = ARGV.shift + trap(:INT, "IGNORE") + assert_nothing_raised(SignalException, bug) do + Process.kill(:INT, $$) + end + end; + end if Process.respond_to?(:kill) end