diff --git a/ChangeLog b/ChangeLog index d081251f5c..52be7c1e55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat Apr 26 21:30:40 2008 Tanaka Akira + + * include/ruby/intern.h (rb_hash_dup): declared. + + * hash.c (rb_hash_dup): new function. + + * process.c (rb_spawn_internal): don't modify option hash. + Sat Apr 26 18:36:31 2008 Nobuyoshi Nakada * io.c, signal.c, thread.c, thread_win32.c, include/ruby/intern.h: diff --git a/hash.c b/hash.c index 006b5f85d8..89c470f9e4 100644 --- a/hash.c +++ b/hash.c @@ -228,6 +228,19 @@ rb_hash_new(void) return hash_alloc(rb_cHash); } +VALUE +rb_hash_dup(VALUE hash) +{ + VALUE ret = hash_alloc(RBASIC(hash)->klass); + if (!RHASH_EMPTY_P(hash)) + RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl); + if (FL_TEST(hash, HASH_PROC_DEFAULT)) { + FL_SET(ret, HASH_PROC_DEFAULT); + } + RHASH(ret)->ifnone = RHASH(hash)->ifnone; + return ret; +} + static void rb_hash_modify_check(VALUE hash) { diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 5272079df7..4df92419b4 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -344,6 +344,7 @@ void st_foreach_safe(struct st_table *, int (*)(ANYARGS), st_data_t); void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE); VALUE rb_hash(VALUE); VALUE rb_hash_new(void); +VALUE rb_hash_dup(VALUE); VALUE rb_hash_freeze(VALUE); VALUE rb_hash_aref(VALUE, VALUE); VALUE rb_hash_lookup(VALUE, VALUE); diff --git a/process.c b/process.c index cb0ab4f4ac..6a1b84fa5e 100644 --- a/process.c +++ b/process.c @@ -2560,6 +2560,10 @@ rb_spawn_internal(int argc, VALUE *argv, int default_close_others) opthash = rb_hash_new(); RBASIC(opthash)->klass = 0; } + if (RBASIC(opthash)->klass) { + opthash = rb_hash_dup(opthash); + RBASIC(opthash)->klass = 0; + } if (!st_lookup(RHASH_TBL(opthash), close_others, 0)) rb_hash_aset(opthash, close_others, Qtrue); } diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index e68f1070e6..36cc5d14a7 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -500,6 +500,21 @@ class TestProcess < Test::Unit::TestCase } end + def test_execopts_modification + h = {} + Process.wait spawn(EnvUtil.rubybin, '-e', '', h) + assert_equal({}, h) + + h = {} + system(EnvUtil.rubybin, '-e', '', h) + assert_equal({}, h) + + h = {} + io = IO.popen([EnvUtil.rubybin, '-e', '', h]) + io.close + assert_equal({}, h) + end + def test_system str = "echo fofo" assert_nil(system([str, str]))