* eval.c (rb_eval_cmd, rb_thread_trap_eval): restore safe level.

* gc.c (define_final, run_final): preserve and restore safe level for
  finalizers.  [ruby-core:03058]

* signal.c (signal_exec, rb_trap_exit, trap): preserve and restore
  safe level for signal handlers.  [ruby-dev:23829]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2004-06-29 01:31:37 +00:00
parent 63dedc7de4
commit ac3c46901c
5 changed files with 59 additions and 29 deletions

View File

@ -1,3 +1,13 @@
Tue Jun 29 10:31:19 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_eval_cmd, rb_thread_trap_eval): restore safe level.
* gc.c (define_final, run_final): preserve and restore safe level for
finalizers. [ruby-core:03058]
* signal.c (signal_exec, rb_trap_exit, trap): preserve and restore
safe level for signal handlers. [ruby-dev:23829]
Mon Jun 28 14:57:56 2004 Jeff Mitchell <quixoticsycophant@yahoo.com> Mon Jun 28 14:57:56 2004 Jeff Mitchell <quixoticsycophant@yahoo.com>
* configure.in, lib/mkmf.rb (LIBPATHFLAG): use double quotes due to * configure.in, lib/mkmf.rb (LIBPATHFLAG): use double quotes due to

33
eval.c
View File

@ -1667,19 +1667,29 @@ jump_tag_but_local_jump(state, val)
} }
VALUE VALUE
rb_eval_cmd(cmd, arg, tcheck) rb_eval_cmd(cmd, arg, level)
VALUE cmd, arg; VALUE cmd, arg;
int tcheck; int level;
{ {
int state; int state;
VALUE val = Qnil; /* OK */ VALUE val = Qnil; /* OK */
struct SCOPE *saved_scope; struct SCOPE *saved_scope;
volatile int safe = ruby_safe_level; volatile int safe = ruby_safe_level;
if (OBJ_TAINTED(cmd)) {
level = 4;
}
if (TYPE(cmd) != T_STRING) { if (TYPE(cmd) != T_STRING) {
PUSH_ITER(ITER_NOT); PUSH_ITER(ITER_NOT);
PUSH_TAG(PROT_NONE);
ruby_safe_level = level;
if ((state = EXEC_TAG()) == 0) {
val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr); val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr);
}
ruby_safe_level = safe;
POP_TAG();
POP_ITER(); POP_ITER();
if (state) JUMP_TAG(state);
return val; return val;
} }
@ -1692,9 +1702,7 @@ rb_eval_cmd(cmd, arg, tcheck)
ruby_frame->self = ruby_top_self; ruby_frame->self = ruby_top_self;
PUSH_CREF(ruby_wrapper ? ruby_wrapper : rb_cObject); PUSH_CREF(ruby_wrapper ? ruby_wrapper : rb_cObject);
if (tcheck && OBJ_TAINTED(cmd)) { ruby_safe_level = level;
ruby_safe_level = 4;
}
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
@ -9537,9 +9545,9 @@ thread_reset_raised()
static void rb_thread_ready _((rb_thread_t)); static void rb_thread_ready _((rb_thread_t));
static VALUE static VALUE
rb_trap_eval(cmd, sig) rb_trap_eval(cmd, sig, safe)
VALUE cmd; VALUE cmd;
int sig; int sig, safe;
{ {
int state; int state;
VALUE val = Qnil; /* OK */ VALUE val = Qnil; /* OK */
@ -9550,7 +9558,7 @@ rb_trap_eval(cmd, sig)
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT); PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0); val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), safe);
} }
POP_ITER(); POP_ITER();
POP_TAG(); POP_TAG();
@ -9760,7 +9768,7 @@ static int th_raise_argc;
static VALUE th_raise_argv[2]; static VALUE th_raise_argv[2];
static NODE *th_raise_node; static NODE *th_raise_node;
static VALUE th_cmd; static VALUE th_cmd;
static int th_sig; static int th_sig, th_safe;
static char *th_signm; static char *th_signm;
#define RESTORE_NORMAL 1 #define RESTORE_NORMAL 1
@ -9852,7 +9860,7 @@ rb_thread_switch(n)
rb_interrupt(); rb_interrupt();
break; break;
case RESTORE_TRAP: case RESTORE_TRAP:
rb_trap_eval(th_cmd, th_sig); rb_trap_eval(th_cmd, th_sig, th_safe);
break; break;
case RESTORE_RAISE: case RESTORE_RAISE:
ruby_frame->last_func = 0; ruby_frame->last_func = 0;
@ -11784,9 +11792,9 @@ rb_thread_signal_raise(sig)
} }
void void
rb_thread_trap_eval(cmd, sig) rb_thread_trap_eval(cmd, sig, safe)
VALUE cmd; VALUE cmd;
int sig; int sig, safe;
{ {
rb_thread_critical = 0; rb_thread_critical = 0;
if (!rb_thread_dead(curr_thread)) { if (!rb_thread_dead(curr_thread)) {
@ -11796,6 +11804,7 @@ rb_thread_trap_eval(cmd, sig)
} }
th_cmd = cmd; th_cmd = cmd;
th_sig = sig; th_sig = sig;
th_safe = safe;
curr_thread = main_thread; curr_thread = main_thread;
rb_thread_restore_context(curr_thread, RESTORE_TRAP); rb_thread_restore_context(curr_thread, RESTORE_TRAP);
} }

13
gc.c
View File

@ -1674,6 +1674,8 @@ undefine_final(os, obj)
return obj; return obj;
} }
#define NODE_FINAL NODE_LIT
/* /*
* call-seq: * call-seq:
* ObjectSpace.define_finalizer(obj, aProc=proc()) * ObjectSpace.define_finalizer(obj, aProc=proc())
@ -1702,6 +1704,8 @@ define_final(argc, argv, os)
need_call_final = 1; need_call_final = 1;
FL_SET(obj, FL_FINALIZE); FL_SET(obj, FL_FINALIZE);
block = (VALUE)rb_node_newnode(NODE_FINAL, block, ruby_safe_level, 0);
if (!finalizer_table) { if (!finalizer_table) {
finalizer_table = st_init_numtable(); finalizer_table = st_init_numtable();
} }
@ -1732,7 +1736,7 @@ static VALUE
run_single_final(args) run_single_final(args)
VALUE *args; VALUE *args;
{ {
rb_eval_cmd(args[0], args[1], 0); rb_eval_cmd(args[0], args[1], (int)args[2]);
return Qnil; return Qnil;
} }
@ -1742,17 +1746,20 @@ run_final(obj)
{ {
long i; long i;
int status, critical_save = rb_thread_critical; int status, critical_save = rb_thread_critical;
VALUE args[2], table; VALUE args[3], table;
rb_thread_critical = Qtrue; rb_thread_critical = Qtrue;
args[1] = rb_ary_new3(1, rb_obj_id(obj)); /* make obj into id */ args[1] = rb_ary_new3(1, rb_obj_id(obj)); /* make obj into id */
args[2] = (VALUE)ruby_safe_level;
for (i=0; i<RARRAY(finalizers)->len; i++) { for (i=0; i<RARRAY(finalizers)->len; i++) {
args[0] = RARRAY(finalizers)->ptr[i]; args[0] = RARRAY(finalizers)->ptr[i];
rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status);
} }
if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) { if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {
for (i=0; i<RARRAY(table)->len; i++) { for (i=0; i<RARRAY(table)->len; i++) {
args[0] = RARRAY(table)->ptr[i]; NODE *final = (NODE *)RARRAY(table)->ptr[i];
args[0] = final->nd_lit;
args[2] = final->nd_nth;
rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status);
} }
} }

View File

@ -215,7 +215,7 @@ VALUE rb_thread_run _((VALUE));
VALUE rb_thread_kill _((VALUE)); VALUE rb_thread_kill _((VALUE));
VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*)); VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));
void rb_thread_interrupt _((void)); void rb_thread_interrupt _((void));
void rb_thread_trap_eval _((VALUE, int)); void rb_thread_trap_eval _((VALUE, int, int));
void rb_thread_signal_raise _((char*)); void rb_thread_signal_raise _((char*));
int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *)); int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *));
void rb_thread_wait_for _((struct timeval)); void rb_thread_wait_for _((struct timeval));

View File

@ -298,7 +298,10 @@ rb_f_kill(argc, argv)
return INT2FIX(i-1); return INT2FIX(i-1);
} }
static VALUE trap_list[NSIG]; static struct {
VALUE cmd;
int safe;
} trap_list[NSIG];
static rb_atomic_t trap_pending_list[NSIG]; static rb_atomic_t trap_pending_list[NSIG];
rb_atomic_t rb_trap_pending; rb_atomic_t rb_trap_pending;
rb_atomic_t rb_trap_immediate; rb_atomic_t rb_trap_immediate;
@ -311,8 +314,8 @@ rb_gc_mark_trap_list()
int i; int i;
for (i=0; i<NSIG; i++) { for (i=0; i<NSIG; i++) {
if (trap_list[i]) if (trap_list[i].cmd)
rb_gc_mark(trap_list[i]); rb_gc_mark(trap_list[i].cmd);
} }
#endif /* MACOS_UNUSE_SIGNAL */ #endif /* MACOS_UNUSE_SIGNAL */
} }
@ -366,7 +369,7 @@ static void
signal_exec(sig) signal_exec(sig)
int sig; int sig;
{ {
if (trap_list[sig] == 0) { if (trap_list[sig].cmd == 0) {
switch (sig) { switch (sig) {
case SIGINT: case SIGINT:
rb_thread_interrupt(); rb_thread_interrupt();
@ -391,7 +394,7 @@ signal_exec(sig)
} }
} }
else { else {
rb_thread_trap_eval(trap_list[sig], sig); rb_thread_trap_eval(trap_list[sig].cmd, sig, trap_list[sig].safe);
} }
} }
@ -458,11 +461,11 @@ void
rb_trap_exit() rb_trap_exit()
{ {
#ifndef MACOS_UNUSE_SIGNAL #ifndef MACOS_UNUSE_SIGNAL
if (trap_list[0]) { if (trap_list[0].cmd) {
VALUE trap_exit = trap_list[0]; VALUE trap_exit = trap_list[0].cmd;
trap_list[0] = 0; trap_list[0].cmd = 0;
rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), 0); rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), trap_list[0].safe);
} }
#endif #endif
} }
@ -620,14 +623,15 @@ trap(arg)
} }
} }
oldfunc = ruby_signal(sig, func); oldfunc = ruby_signal(sig, func);
oldcmd = trap_list[sig]; oldcmd = trap_list[sig].cmd;
if (!oldcmd) { if (!oldcmd) {
if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT"); else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
else oldcmd = Qnil; else oldcmd = Qnil;
} }
trap_list[sig] = command; trap_list[sig].cmd = command;
trap_list[sig].safe = ruby_safe_level;
/* enable at least specified signal. */ /* enable at least specified signal. */
#ifndef _WIN32 #ifndef _WIN32
#ifdef HAVE_SIGPROCMASK #ifdef HAVE_SIGPROCMASK
@ -794,7 +798,7 @@ init_sigchld(sig)
if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
ruby_signal(sig, oldfunc); ruby_signal(sig, oldfunc);
} else { } else {
trap_list[sig] = 0; trap_list[sig].cmd = 0;
} }
#ifndef _WIN32 #ifndef _WIN32