From 89e2951bde9b7f4e04a8f068bfde6756aebf74af Mon Sep 17 00:00:00 2001 From: kosaki Date: Tue, 12 Jul 2011 04:55:50 +0000 Subject: [PATCH] * signal.c (sig_trap): don't permit to change a signal handler which the interpreter reserved. * signal.c (reserved_signal_p): ditto. [Bug #2616] [ruby-core:27625] * test/ruby/test_signal.rb (TestSignal#test_reserved_signal): added a test for reserved signal. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32523 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++++++++ signal.c | 43 ++++++++++++++++++++++++++++++++++++++++ test/ruby/test_signal.rb | 25 +++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7189f39344..b17b133f7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Tue Jul 12 13:49:32 2011 KOSAKI Motohiro + + * signal.c (sig_trap): don't permit to change a signal handler which + the interpreter reserved. + * signal.c (reserved_signal_p): ditto. + [Bug #2616] [ruby-core:27625] + + * test/ruby/test_signal.rb (TestSignal#test_reserved_signal): + added a test for reserved signal. + Tue Jul 12 11:58:28 2011 NAKAMURA Usaku * win32/setup.mak: support x86-amd64 cross compile environment. diff --git a/signal.c b/signal.c index 618ed3f52d..7490de9f82 100644 --- a/signal.c +++ b/signal.c @@ -870,6 +870,45 @@ trap_ensure(struct trap_arg *arg) } #endif +int reserved_signal_p(int signo) +{ +/* Synchronous signal can't deliver to main thread */ +#ifdef SIGSEGV + if (signo == SIGSEGV) + return 1; +#endif +#ifdef SIGBUS + if (signo == SIGBUS) + return 1; +#endif +#ifdef SIGILL + if (signo == SIGILL) + return 1; +#endif +#ifdef SIGFPE + if (signo == SIGFPE) + return 1; +#endif + +/* used ubf internal see thread_pthread.c. */ +#ifdef SIGVTALRM + if (signo == SIGVTALRM) + return 1; +#endif + +/* On some OSs, wait() never return if SIGCHLD handler is installed. */ +#ifdef SIGCHLD + if (signo == SIGCHLD) + return 1; +#endif +#ifdef SIGCLD + if (signo == SIGCLD) + return 1; +#endif + + return 0; +} + /* * call-seq: * Signal.trap( signal, command ) -> obj @@ -912,6 +951,10 @@ sig_trap(int argc, VALUE *argv) } arg.sig = trap_signm(argv[0]); + if (reserved_signal_p(arg.sig)) { + rb_raise(rb_eArgError, "can't trap reserved signal"); + } + if (argc == 1) { arg.cmd = rb_block_proc(); arg.func = sighandler; diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb index c226fdd611..cd1f2c04b1 100644 --- a/test/ruby/test_signal.rb +++ b/test/ruby/test_signal.rb @@ -220,4 +220,29 @@ EOS t.close! assert_nil(error) end + + def test_reserved_signal + assert_raise(ArgumentError) { + Signal.trap(:SEGV) {} + } + assert_raise(ArgumentError) { + Signal.trap(:BUS) {} + } + assert_raise(ArgumentError) { + Signal.trap(:ILL) {} + } + assert_raise(ArgumentError) { + Signal.trap(:FPE) {} + } + assert_raise(ArgumentError) { + Signal.trap(:VTALRM) {} + } + assert_raise(ArgumentError) { + Signal.trap(:CHLD) {} + } + assert_raise(ArgumentError) { + Signal.trap(:CLD) {} + } + end + end