aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-12 04:55:50 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-12 04:55:50 +0000
commit89e2951bde9b7f4e04a8f068bfde6756aebf74af (patch)
tree4139a5a7fe3f0973f2129507b37656b536d6bd6e
parent888d8e93e1149991e2edaa5ddb78c11f803b4063 (diff)
downloadruby-89e2951bde9b7f4e04a8f068bfde6756aebf74af.tar.gz
* 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
-rw-r--r--ChangeLog10
-rw-r--r--signal.c43
-rw-r--r--test/ruby/test_signal.rb25
3 files changed, 78 insertions, 0 deletions
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 <kosaki.motohiro@gmail.com>
+
+ * 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 <usa@ruby-lang.org>
* 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