[#30549] [ANN] Ruby 1.8.6 has been released — "Akinori MUSHA" <knu@...>

 Ruby 1.8.6 をリリースしました。

14 messages 2007/03/12

[#30553] help: lib/shell for ruby 1.9 — keiju@... (Keiju ISHITSUKA)

けいじゅ@いしつかです.

13 messages 2007/03/13
[#30585] Re: help: lib/shell for ruby 1.9 — Yukihiro Matsumoto <matz@...> 2007/03/15

まつもと ゆきひろです

[#30587] Re: help: lib/shell for ruby 1.9 — keiju@... (石塚圭樹) 2007/03/15

けいじゅ@いしつかです.

[#30588] Re: help: lib/shell for ruby 1.9 — Yukihiro Matsumoto <matz@...> 2007/03/15

まつもと ゆきひろです

[ruby-dev:30519] Re: [BUG?] SIGTERM の取り扱い

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-03-09 21:14:45 UTC
List: ruby-dev #30519
なかだです。

At Fri, 9 Mar 2007 10:42:22 +0900,
Hidetoshi NAGAI wrote in [ruby-dev:30516]:
> > > |> # メッセージが "ruby: SIGTERM (SignalException)" となってしまうのが
> > > |> # 少し格好悪い気もしますが...
> > > |
> > > |どうなるのがいいんでしょう。トップレベルまで抜けたところで、
> > > |SIG_DFLに戻して再度kill()?
> > > 
> > > トップレベルで例外がrb_eSignalのとき、メッセージを出さずに終
> > > 了するのがよいのではないかと。
> > 
> > 親プロセスではWIFSIGNALEDとかWTERMSIGが取れることを期待している
> > のではないかと思ったんですが、そこまでは必要なし?
> 
> 必要なのでしょうね.
> 最初は _exit(SIGTERM) でもいいのかなとも思いましたが (^_^;,
> 確かに SIG_DFL で始末してもらわないと具合いが悪そうです.
> 
> # 「じゃあ HUP, QUIT はいいのか?」って話もありますが...

SignalExceptionとInterruptの関係が微妙ですが。

  $ trap ":" 2
  $ for sig in HUP INT QUIT TERM; do
  >   echo $sig; ./ruby -esleep & usleep 100000; kill -$sig $!; fg
  >   echo $?; echo ----------
  > done
  HUP
  [1] 25936
  ./ruby -esleep
  ハングアップ
  129
  ----------
  INT
  [1] 25938
  ./ruby -esleep
  -e:1:in `sleep': Interrupt
          from -e:1

  130
  ----------
  QUIT
  [1] 25940
  ./ruby -esleep
  終了 (core dumped)
  131
  ----------
  TERM
  [1] 25943
  ./ruby -esleep
  終了しました
  143
  ----------


Index: intern.h
===================================================================
--- intern.h	(revision 12021)
+++ intern.h	(working copy)
@@ -212,5 +212,5 @@ VALUE rb_thread_create _((VALUE (*)(ANYA
 void rb_thread_interrupt _((void));
 void rb_thread_trap_eval _((VALUE, int, int));
-void rb_thread_signal_raise _((char*));
+void rb_thread_signal_raise _((int));
 void rb_thread_signal_exit _((void));
 int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *));
@@ -395,4 +395,5 @@ 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, VALUE*));
Index: eval.c
===================================================================
--- eval.c	(revision 12021)
+++ eval.c	(working copy)
@@ -1493,4 +1493,7 @@ error_handle(ex)
 	    status = sysexit_status(ruby_errinfo);
 	}
+	else if (rb_obj_is_instance_of(ruby_errinfo, rb_eSignal)) {
+	    /* no message when exiting by signal */
+	}
 	else {
 	    error_print();
@@ -1580,7 +1583,13 @@ ruby_cleanup(ex)
     POP_TAG();
 
-    if (err && rb_obj_is_kind_of(err, rb_eSystemExit)) {
-	VALUE st = rb_iv_get(err, "status");
-	return NUM2INT(st);
+    if (err) {
+	if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
+	    VALUE st = rb_iv_get(err, "status");
+	    return NUM2INT(st);
+	}
+	else if (rb_obj_is_kind_of(err, rb_eSignal)) {
+	    VALUE sig = rb_iv_get(err, "signo");
+	    ruby_default_signal(NUM2INT(sig));
+	}
     }
     return ex;
@@ -10156,5 +10165,4 @@ static NODE *th_raise_node;
 static VALUE th_cmd;
 static int   th_sig, th_safe;
-static char *th_signm;
 
 #define RESTORE_NORMAL		1
@@ -10262,5 +10270,5 @@ rb_thread_switch(n)
 	break;
       case RESTORE_SIGNAL:
-	rb_raise(rb_eSignal, "SIG%s", th_signm);
+	rb_thread_signal_raise(th_sig);
 	break;
       case RESTORE_EXIT:
@@ -12263,11 +12271,13 @@ rb_thread_interrupt()
 void
 rb_thread_signal_raise(sig)
-    char *sig;
+    int sig;
 {
-    if (sig == 0) return;	/* should not happen */
     rb_thread_critical = 0;
     if (curr_thread == main_thread) {
+	VALUE argv[1];
+
 	rb_thread_ready(curr_thread);
-	rb_raise(rb_eSignal, "SIG%s", sig);
+	argv[0] = INT2FIX(sig);
+	rb_exc_raise(rb_class_new_instance(1, argv, rb_eSignal));
     }
     rb_thread_ready(main_thread);
@@ -12277,5 +12287,5 @@ rb_thread_signal_raise(sig)
 	}
     }
-    th_signm = sig;
+    th_sig = sig;
     curr_thread = main_thread;
     rb_thread_restore_context(curr_thread, RESTORE_SIGNAL);
Index: signal.c
===================================================================
--- signal.c	(revision 12021)
+++ signal.c	(working copy)
@@ -171,5 +171,5 @@ static struct signals {
 static int
 signm2signo(nm)
-    char *nm;
+    const char *nm;
 {
     struct signals *sigs;
@@ -201,4 +201,91 @@ ruby_signal_name(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(argc, argv, self)
+    int argc;
+    VALUE *argv;
+    VALUE self;
+{
+    int argnum = 1;
+    VALUE sig = Qnil;
+    int signo;
+    const char *signm;
+    char tmpnm[(sizeof(int)*CHAR_BIT)/3+4];
+
+    if (argc > 0) {
+	sig = argv[0];
+	if (FIXNUM_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 = FIX2INT(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) {
+		snprintf(tmpnm, sizeof(tmpnm), "SIG%s", signm);
+	    }
+	    else {
+		snprintf(tmpnm, sizeof(tmpnm), "SIG%u", signo);
+	    }
+	    sig = rb_str_new2(signm = tmpnm);
+	}
+    }
+    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(self, mesg)
+    VALUE self, mesg;
+{
+    VALUE argv[2];
+
+    argv[0] = INT2FIX(SIGINT);
+    argv[1] = mesg;
+    return rb_call_super(2, argv);
+}
+
+void
+ruby_default_signal(sig)
+    int sig;
+{
+#ifndef MACOS_UNUSE_SIGNAL
+    extern rb_pid_t getpid _((void));
+
+    signal(sig, SIG_DFL);
+    kill(getpid(), sig);
+#endif
+}
+
+/*
  *  call-seq:
  *     Process.kill(signal, pid, ...)    => fixnum
@@ -414,4 +501,7 @@ signal_exec(sig)
 	  case SIGQUIT:
 #endif
+#ifdef SIGTERM
+	  case SIGTERM:
+#endif
 #ifdef SIGALRM
 	  case SIGALRM:
@@ -423,5 +513,5 @@ signal_exec(sig)
 	  case SIGUSR2:
 #endif
-	    rb_thread_signal_raise(signo2signm(sig));
+	    rb_thread_signal_raise(sig);
 	    break;
 	}
@@ -681,4 +771,7 @@ trap(arg)
 	  case SIGQUIT:
 #endif
+#ifdef SIGTERM
+	  case SIGTERM:
+#endif
 #ifdef SIGALRM
 	  case SIGALRM:
@@ -976,4 +1069,9 @@ Init_signal()
     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


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread