diff --git a/ChangeLog b/ChangeLog index c4172f0325..0472fd347a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat Apr 26 00:47:43 2008 Tanaka Akira + + * process.c (rb_spawn_internal): new function to specify + default_close_others. + (rb_spawn): specify default_close_others true. + (rb_f_system): call rb_spawn_internal with default_close_others as + false. + Fri Apr 25 17:56:25 2008 Yukihiro Matsumoto * gc.c (free_unused_heaps): preserve last used heap segment to diff --git a/process.c b/process.c index 3ffd6d353e..25349b6da6 100644 --- a/process.c +++ b/process.c @@ -2544,14 +2544,26 @@ rb_syswait(rb_pid_t pid) } } -rb_pid_t -rb_spawn(int argc, VALUE *argv) +static rb_pid_t +rb_spawn_internal(int argc, VALUE *argv, int default_close_others) { rb_pid_t status; VALUE prog; struct rb_exec_arg earg; + int argc2 = argc; + VALUE *argv2 = argv, env = Qnil, opthash = Qnil; + VALUE close_others = ID2SYM(rb_intern("close_others")); - prog = rb_exec_initarg(argc, argv, Qtrue, &earg); + prog = rb_exec_getargs(&argc2, &argv2, Qtrue, &env, &opthash); + if (default_close_others) { + if (NIL_P(opthash)) { + opthash = rb_hash_new(); + RBASIC(opthash)->klass = 0; + } + if (!st_lookup(RHASH_TBL(opthash), close_others, 0)) + rb_hash_aset(opthash, close_others, Qtrue); + } + rb_exec_initarg2(prog, argc2, argv2, env, opthash, &earg); #if defined HAVE_FORK status = rb_fork(&status, rb_exec_atfork, &earg, earg.redirect_fds); @@ -2581,6 +2593,12 @@ rb_spawn(int argc, VALUE *argv) return status; } +rb_pid_t +rb_spawn(int argc, VALUE *argv) +{ + return rb_spawn_internal(argc, argv, Qtrue); +} + /* * call-seq: * system([env,] cmd [, arg, ...] [,options]) => true, false or nil @@ -2618,7 +2636,7 @@ rb_f_system(int argc, VALUE *argv) chfunc = signal(SIGCHLD, SIG_DFL); #endif - status = rb_spawn(argc, argv); + status = rb_spawn_internal(argc, argv, Qfalse); #if defined(HAVE_FORK) || defined(HAVE_SPAWNV) if (status > 0) { rb_syswait(status); diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index d8113d7180..e68f1070e6 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -419,9 +419,9 @@ class TestProcess < Test::Unit::TestCase assert_equal("ba\n", r.read) } with_pipe {|r, w| - Process.wait spawn("echo bi >&#{w.fileno}") + Process.wait spawn("exec 2>/dev/null; echo bi >&#{w.fileno}") w.close - assert_equal("bi\n", r.read) + assert_equal("", r.read) } with_pipe {|r, w| Process.wait fork { exec("echo bu >&#{w.fileno}") } @@ -464,6 +464,11 @@ class TestProcess < Test::Unit::TestCase assert_equal("", r.read) File.unlink("err") } + with_pipe {|r, w| + Process.wait spawn("echo bi >&#{w.fileno}", :close_others=>false) + w.close + assert_equal("bi\n", r.read) + } with_pipe {|r, w| Process.wait fork { exec("exec >/dev/null 2>err; echo mu >&#{w.fileno}", :close_others=>true) } w.close