summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--eval.c35
-rw-r--r--eval_error.h11
-rw-r--r--eval_jump.h1
-rw-r--r--intern.h3
-rw-r--r--signal.c110
-rw-r--r--thread.c28
-rw-r--r--version.h6
-rw-r--r--yarvcore.h1
9 files changed, 169 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index 18daf8345..65c156553 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+Fri Apr 20 02:37:48 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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.
+
Thu Apr 19 18:37:49 2007 Koichi Sasada <ko1@atdot.net>
* eval.c, node.h, thread.c, yarvcore.[ch], eval_intern.h:
diff --git a/eval.c b/eval.c
index b72fbe44d..a7f5cbbd0 100644
--- a/eval.c
+++ b/eval.c
@@ -153,40 +153,41 @@ ruby_finalize(void)
int
ruby_cleanup(int ex)
{
- int state;
- volatile VALUE err = GET_THREAD()->errinfo;
+ int state, i;
+ volatile VALUE errs[2] = {GET_THREAD()->errinfo, 0};
rb_vm_t *vm = GET_THREAD()->vm;
- /* th->errinfo contains a NODE while break'ing */
- if (RTEST(err) && (TYPE(err) != T_NODE) &&
- rb_obj_is_kind_of(err, rb_eSystemExit)) {
- vm->exit_code = NUM2INT(rb_iv_get(err, "status"));
- }
- else {
- vm->exit_code = 0;
- }
-
GET_THREAD()->safe_level = 0;
Init_stack((void *)&state);
PUSH_THREAD_TAG();
if ((state = EXEC_TAG()) == 0) {
- if (GET_THREAD()->errinfo) {
- err = GET_THREAD()->errinfo;
- }
ruby_finalize_0();
}
else if (ex == 0) {
ex = state;
}
+ errs[1] = GET_THREAD()->errinfo;
rb_thread_terminate_all();
- GET_THREAD()->errinfo = err;
+ GET_THREAD()->errinfo = errs[0];
ex = error_handle(ex);
ruby_finalize_1();
POP_THREAD_TAG();
+ rb_thread_stop_timer_thread();
- if (vm->exit_code) {
- return vm->exit_code;
+ for (i = 2; i > 0; --i) {
+ VALUE err = errs[i];
+
+ /* th->errinfo contains a NODE while break'ing */
+ if (!RTEST(err) || (TYPE(err) == T_NODE)) continue;
+
+ if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
+ return sysexit_status(err);
+ }
+ else if (rb_obj_is_kind_of(err, rb_eSignal)) {
+ ruby_default_signal(NUM2INT(rb_iv_get(err, "signo")));
+ }
}
+
return ex;
}
diff --git a/eval_error.h b/eval_error.h
index 38e85a1d3..155986e83 100644
--- a/eval_error.h
+++ b/eval_error.h
@@ -233,14 +233,19 @@ error_handle(int ex)
warn_printf(": unexpected throw\n");
break;
case TAG_RAISE:
- case TAG_FATAL:
- if (rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
- status = sysexit_status(GET_THREAD()->errinfo);
+ case TAG_FATAL: {
+ VALUE errinfo = GET_THREAD()->errinfo;
+ if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
+ status = sysexit_status(errinfo);
+ }
+ else if (rb_obj_is_instance_of(errinfo, rb_eSignal)) {
+ /* no message when exiting by signal */
}
else {
error_print();
}
break;
+ }
default:
rb_bug("Unknown longjmp status %d", ex);
break;
diff --git a/eval_jump.h b/eval_jump.h
index aa2d84a3f..485723ecb 100644
--- a/eval_jump.h
+++ b/eval_jump.h
@@ -143,7 +143,6 @@ terminate_process(int status, const char *mesg, long mlen)
args[0] = INT2NUM(status);
args[1] = rb_str_new(mesg, mlen);
- vm->exit_code = status;
rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
}
diff --git a/intern.h b/intern.h
index 1f4c2d308..c4cd7a7d4 100644
--- a/intern.h
+++ b/intern.h
@@ -274,7 +274,7 @@ VALUE rb_thread_run(VALUE);
VALUE rb_thread_kill(VALUE);
VALUE rb_thread_create(VALUE (*)(ANYARGS), void*);
void rb_thread_trap_eval(VALUE, int, int);
-void rb_thread_signal_raise(void *, const char*); /* should pass literal */
+void rb_thread_signal_raise(void *, int);
void rb_thread_signal_exit(void *);
int rb_thread_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
void rb_thread_wait_for(struct timeval);
@@ -471,6 +471,7 @@ void posix_signal(int, RETSIGTYPE (*)(int));
void rb_trap_exit(void);
void rb_trap_exec(void);
const char *ruby_signal_name(int);
+void ruby_default_signal(int);
/* sprintf.c */
VALUE rb_f_sprintf(int, const VALUE*);
PRINTF_ARGS(VALUE rb_sprintf(const char*, ...), 1, 2);
diff --git a/signal.c b/signal.c
index 195939f43..d3810214c 100644
--- a/signal.c
+++ b/signal.c
@@ -14,6 +14,8 @@
#include "ruby.h"
#include "rubysig.h"
+#include "node.h"
+#include "yarvcore.h"
#include <signal.h>
#include <stdio.h>
@@ -197,6 +199,84 @@ ruby_signal_name(int 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<argc; i++) {
- int pid = NUM2INT(argv[i]);
-#ifdef HAS_KILLPG
- if (killpg(pid, sig) < 0)
-#else
- if (kill(-pid, sig) < 0)
-#endif
+ if (killpg(NUM2PIDT(argv[i]), sig) < 0)
rb_sys_fail(0);
}
}
else {
for (i=1; i<argc; i++) {
- Check_Type(argv[i], T_FIXNUM);
- if (kill(FIX2INT(argv[i]), sig) < 0)
+ if (kill(NUM2PIDT(argv[i]), sig) < 0)
rb_sys_fail(0);
}
}
+ rb_thread_polling();
return INT2FIX(i-1);
}
@@ -369,9 +447,6 @@ ruby_nativethread_signal(int signum, sighandler_t handler)
#endif
#endif
-#include <node.h>
-#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);
diff --git a/thread.c b/thread.c
index 05f484007..4c1fea317 100644
--- a/thread.c
+++ b/thread.c
@@ -751,31 +751,25 @@ rb_thread_raise(int argc, VALUE *argv, rb_thread_t *th)
}
void
-rb_thread_signal_raise(void *thptr, const char *sig)
+rb_thread_signal_raise(void *thptr, int sig)
{
- VALUE argv[1];
- char buf[BUFSIZ];
+ VALUE argv[2];
rb_thread_t *th = thptr;
-
- if (sig == 0) {
- return; /* should not happen */
- }
- snprintf(buf, BUFSIZ, "SIG%s", sig);
- argv[0] = rb_exc_new3(rb_eSignal, rb_str_new2(buf));
- rb_thread_raise(1, argv, th->vm->main_thread);
+
+ argv[0] = rb_eSignal;
+ argv[1] = INT2FIX(sig);
+ rb_thread_raise(2, argv, th->vm->main_thread);
}
void
rb_thread_signal_exit(void *thptr)
{
- VALUE argv[1];
- VALUE args[2];
+ VALUE argv[2];
rb_thread_t *th = thptr;
-
- args[0] = INT2NUM(EXIT_SUCCESS);
- args[1] = rb_str_new2("exit");
- argv[0] = rb_class_new_instance(2, args, rb_eSystemExit);
- rb_thread_raise(1, argv, th->vm->main_thread);
+
+ argv[0] = rb_eSystemExit;
+ argv[1] = rb_str_new2("exit");
+ rb_thread_raise(2, argv, th->vm->main_thread);
}
int
diff --git a/version.h b/version.h
index a9e65bde1..371c56162 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-04-19"
+#define RUBY_RELEASE_DATE "2007-04-20"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20070419
+#define RUBY_RELEASE_CODE 20070420
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 19
+#define RUBY_RELEASE_DAY 20
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];
diff --git a/yarvcore.h b/yarvcore.h
index 4961adfc7..56d17f065 100644
--- a/yarvcore.h
+++ b/yarvcore.h
@@ -345,7 +345,6 @@ typedef struct rb_vm_struct {
int thread_abort_on_exception;
unsigned long trace_flag;
- int exit_code;
/* object management */
VALUE mark_object_ary;