From 3fc37d71c4a1a25c3a77464c614595703d63c2e6 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 19 Apr 2007 17:37:03 +0000 Subject: * eval.c (ruby_cleanup): re-send signal. [ruby-dev:30516] * eval_error.h (error_handle): no message when exiting by signal. * intern.h (rb_thread_signal_raise, ruby_default_signal): prototypes. * signal.c (esignal_init): takes a signal number and an optional signal name. * signal.c (interrupt_init): pass SIGINT always. * signal.c (ruby_default_signal): invoke system default signal handler. * signal.c (rb_f_kill): use NUM2PIDT instead of NUM2INT. * signal.c (rb_signal_exec, trap): handle SIGTERM. [ruby-dev:30505] * thread.c (rb_thread_signal_raise): now takes signal number instead of signal name. * thread.c (rb_thread_signal_exit): since rb_make_exception() calls #exception method, rb_class_new_instance() is not needed here. * yarvcore.h (struct rb_vm_struct), eval_jump.h (terminate_process): exit_code is no longer stored in VM. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- signal.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 12 deletions(-) (limited to 'signal.c') diff --git a/signal.c b/signal.c index 195939f434..d3810214cc 100644 --- a/signal.c +++ b/signal.c @@ -14,6 +14,8 @@ #include "ruby.h" #include "rubysig.h" +#include "node.h" +#include "yarvcore.h" #include #include @@ -196,6 +198,84 @@ ruby_signal_name(int no) return signo2signm(no); } +/* + * call-seq: + * SignalException.new(sig) => signal_exception + * + * Construct a new SignalException object. +sig+ should be a known + * signal name, or a signal number. + */ + +static VALUE +esignal_init(int argc, VALUE *argv, VALUE self) +{ + int argnum = 1; + VALUE sig = Qnil; + int signo; + const char *signm; + + if (argc > 0) { + sig = rb_check_to_integer(argv[0], "to_int"); + if (!NIL_P(sig)) argnum = 2; + } + if (argc < 1 || argnum < argc) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, argnum); + } + if (argnum == 2) { + signo = NUM2INT(sig); + if (signo < 0 || signo > NSIG) { + rb_raise(rb_eArgError, "invalid signal number (%d)", signo); + } + if (argc > 1) { + sig = argv[1]; + } + else { + signm = signo2signm(signo); + if (signm) { + sig = rb_sprintf("SIG%s", signm); + } + else { + sig = rb_sprintf("SIG%u", signo); + } + } + } + else { + signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig); + if (strncmp(signm, "SIG", 3) == 0) signm += 3; + signo = signm2signo(signm); + if (!signo) { + rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm); + } + if (SYMBOL_P(sig)) { + sig = rb_str_new2(signm); + } + } + rb_call_super(1, &sig); + rb_iv_set(self, "signo", INT2NUM(signo)); + + return self; +} + +static VALUE +interrupt_init(int argc, VALUE *argv, VALUE self) +{ + VALUE args[2]; + + rb_scan_args(argc, argv, "01", &args[1]); + args[0] = INT2FIX(SIGINT); + return rb_call_super(argc + 1, args); +} + +void +ruby_default_signal(int sig) +{ +#ifndef MACOS_UNUSE_SIGNAL + signal(sig, SIG_DFL); + raise(sig); +#endif +} + /* * call-seq: * Process.kill(signal, pid, ...) => fixnum @@ -223,6 +303,9 @@ ruby_signal_name(int no) VALUE rb_f_kill(int argc, VALUE *argv) { +#ifndef HAS_KILLPG +#define killpg(pg, sig) kill(-(pg), sig) +#endif int negative = 0; int sig; int i; @@ -275,22 +358,17 @@ rb_f_kill(int argc, VALUE *argv) if (sig < 0) { sig = -sig; for (i=1; i -#include "yarvcore.h" - static RETSIGTYPE sighandler(int sig) { @@ -498,6 +573,9 @@ rb_signal_exec(rb_thread_t *th, int sig) #ifdef SIGQUIT case SIGQUIT: #endif +#ifdef SIGTERM + case SIGTERM: +#endif #ifdef SIGALRM case SIGALRM: #endif @@ -507,7 +585,7 @@ rb_signal_exec(rb_thread_t *th, int sig) #ifdef SIGUSR2 case SIGUSR2: #endif - rb_thread_signal_raise(th, signo2signm(sig)); + rb_thread_signal_raise(th, sig); break; } } @@ -638,6 +716,9 @@ trap(struct trap_arg *arg) #ifdef SIGQUIT case SIGQUIT: #endif +#ifdef SIGTERM + case SIGTERM: +#endif #ifdef SIGALRM case SIGALRM: #endif @@ -898,6 +979,11 @@ Init_signal(void) rb_define_module_function(mSignal, "trap", sig_trap, -1); rb_define_module_function(mSignal, "list", sig_list, 0); + rb_define_method(rb_eSignal, "initialize", esignal_init, -1); + rb_attr(rb_eSignal, rb_intern("signo"), 1, 0, 0); + rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message")); + rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); + install_sighandler(SIGINT, sighandler); #ifdef SIGHUP install_sighandler(SIGHUP, sighandler); -- cgit v1.2.3