e$B$J$+$@$G$9!#e(B
[ruby-dev:30820]e$B$r;n$7$F$$$F5$$E$$$?$N$G$9$,!"e(B1.9e$B$G0J2<$N%3!<%Ie(B
e$B$,e(BSEGVe$B$7$^$9!#e(BQundefe$B$rJV$7$F$$$k$h$&$G$9!#e(B
p trap(:INT, trap(:INT, “EXIT”))
e$B$^$?!"e(Btrap(:EXIT)e$B$@$1$OG$0U$NJ8;zNs$rEO$;$k$^$^$K$J$C$F$$$^$9$,!"e(B
e$B$d$O$je(BSEGVe$B$7$^$9!#e(B
trap(:EXIT, “p”)
e$B$D$$$G$K!"0z?t$N%A%’%C%/$r@h$K:Q$^$9$h$&$K$7$F$_$^$7$?!#e(B
Index: signal.c
— signal.c (revision 12396)
+++ signal.c (working copy)
@@ -375,5 +375,4 @@ rb_f_kill(int argc, VALUE *argv)
static struct {
VALUE cmd;
- int safe;
} trap_list[NSIG];
static rb_atomic_t trap_pending_list[NSIG];
@@ -545,4 +544,13 @@ sigpipe(int sig)
#endif
+static void
+signal_exec(VALUE cmd, int sig)
+{
- rb_proc_t *proc;
- VALUE signum = INT2FIX(sig);
- GetProcPtr(cmd, proc);
- th_invoke_proc(GET_THREAD(), proc, proc->block.self, 1, &signum);
+}
void
rb_trap_exit(void)
@@ -553,5 +561,5 @@ rb_trap_exit(void)
trap_list[0].cmd = 0;
- rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)),
trap_list[0].safe);
- signal_exec(trap_exit, 0);
}
#endif
@@ -594,8 +602,5 @@ rb_signal_exec(rb_thread_t *th, int sig)
}
else {
- rb_proc_t *proc;
- VALUE signum = INT2FIX(sig);
- GetProcPtr(cmd, proc);
- th_invoke_proc(th, proc, proc->block.self, 1, &signum);
- signal_exec(cmd, sig);
}
}
@@ -625,21 +630,20 @@ struct trap_arg {
endif
#endif
- VALUE sig, cmd;
- int sig;
- sighandler_t func;
- VALUE cmd;
};
-static VALUE
-trap(struct trap_arg *arg)
+static sighandler_t
+trap_handler(VALUE *cmd)
{
- sighandler_t func, oldfunc;
- VALUE command, oldcmd;
- int sig = -1;
- const char *s;
- sighandler_t func = 0;
- VALUE command;
- func = sighandler;
- if (NIL_P(arg->cmd)) {
- if (NIL_P(*cmd)) {
func = SIG_IGN;
}
else {
- command = rb_check_string_type(arg->cmd);
- command = rb_check_string_type(cmd);
if (!NIL_P(command)) {
SafeStringValue(command); / taint check */
@@ -666,29 +670,47 @@ trap(struct trap_arg *arg)
case 4:
if (strncmp(RSTRING_PTR(command), “EXIT”, 4) == 0) {
-
arg->cmd = Qundef;
-
func = sighandler;
-
}*cmd = Qundef;
break;
} -
if (!func) {
- rb_raise(rb_eArgError, “wrong trap - %s”, RSTRING_PTR(command));
-
}
- }
- else {
-
rb_proc_t *proc;
-
GetProcPtr(*cmd, proc);
-
}func = sighandler;
}
if (func == SIG_IGN || func == SIG_DFL) {
- command = 0;
- }
- else {
- command = arg->cmd;
- *cmd = 0;
}
- switch (TYPE(arg->sig)) {
- return func;
+}
+static int
+trap_signm(VALUE vsig)
+{
- int sig = -1;
- const char *s;
- switch (TYPE(vsig)) {
case T_FIXNUM:
- sig = FIX2INT(arg->sig);
-
sig = FIX2INT(vsig);
-
if (sig < 0 || sig >= NSIG) {
-
rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
-
}
break;case T_SYMBOL:
- s = rb_id2name(SYM2ID(arg->sig));
- s = rb_id2name(SYM2ID(vsig));
if (!s) rb_raise(rb_eArgError, “bad signal”);
goto str_signal;
-
case T_STRING:
- s = RSTRING_PTR(arg->sig);
-
default:
-
s = StringValuePtr(vsig);
str_signal:
@@ -700,7 +722,4 @@ trap(struct trap_arg *arg)
}
- if (sig < 0 || sig >= NSIG) {
- rb_raise(rb_eArgError, “invalid signal number (%d)”, sig);
- }
#if defined(HAVE_SETITIMER)
if (sig == SIGVTALRM) {
@@ -708,4 +727,10 @@ trap(struct trap_arg *arg)
}
#endif
- return sig;
+}
+static sighandler_t
+default_handler(sighandler_t func, int sig)
+{
if (func == SIG_DFL) {
switch (sig) {
@@ -748,14 +773,29 @@ trap(struct trap_arg *arg)
}
}
+
- return func;
+}
+static VALUE
+trap(struct trap_arg *arg)
+{
- sighandler_t oldfunc, func = arg->func;
- VALUE oldcmd, command = arg->cmd;
- int sig = arg->sig;
- oldfunc = ruby_signal(sig, func);
oldcmd = trap_list[sig].cmd;
- if (!oldcmd) {
-
switch (oldcmd) {
-
case 0:
if (oldfunc == SIG_IGN) oldcmd = rb_str_new2(“IGNORE”);
else if (oldfunc == sighandler) oldcmd = rb_str_new2(“DEFAULT”);
else oldcmd = Qnil; -
break;
-
case Qundef:
-
oldcmd = rb_str_new2(“EXIT”);
-
break;
}trap_list[sig].cmd = command;
-
trap_list[sig].safe = rb_safe_level();
/* enable at least specified signal. */
#ifndef _WIN32
@@ -834,10 +874,12 @@ sig_trap(int argc, VALUE *argv)
} -
arg.sig = argv[0];
- arg.sig = trap_signm(argv[0]);
if (argc == 1) {
arg.cmd = rb_block_proc(); - arg.func = sighandler;
}
else if (argc == 2) {
arg.cmd = argv[1]; - arg.func = default_handler(trap_handler(&arg.cmd), arg.sig);
}