From 7a69a3583c2235c0ad3ad0705aa2f08cbe2d76bb Mon Sep 17 00:00:00 2001 From: akr Date: Mon, 5 May 2014 13:37:09 +0000 Subject: * process.c (check_exec_redirect): Open the file in write mode for redirect from [:out, :err]. Proposed and implemented by Yusuke Endoh. [ruby-dev:41430] [Feature #3348] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45828 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ NEWS | 10 ++++++++++ process.c | 14 +++++++++++++- test/ruby/test_process.rb | 11 +++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 217a515a85..09264d00a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Mon May 5 22:29:47 2014 Tanaka Akira + + * process.c (check_exec_redirect): Open the file in write mode for + redirect from [:out, :err]. + Proposed and implemented by Yusuke Endoh. + [ruby-dev:41430] [Feature #3348] + Mon May 5 21:52:35 2014 Tanaka Akira * ext/pathname/lib/pathname.rb (cleanpath_aggressive): make all diff --git a/NEWS b/NEWS index 681f0eea75..235370a5ba 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,11 @@ with all sufficient information, see the ChangeLog file. * New methods * IO#statfs returns filesystem information as File::Statfs. (experimental) +* Process + * Extended method: + * Process execution methods such as Process.spawn opens the file in write + mode for redirect from [:out, :err]. + * Symbol * New methods * Symbol.find(str) returns whether given string is defined as symbol or not. @@ -64,6 +69,11 @@ with all sufficient information, see the ChangeLog file. arguments of the lambda, if just an array is yielded and its length matches. +* Process + * Process execution methods such as Process.spawn opens the file in write + mode for redirect from [:out, :err]. + Before Ruby 2.2, it was opened in read mode. + === Stdlib updates (outstanding ones only) * Find, Pathname diff --git a/process.c b/process.c index f35af49071..7946b170b0 100644 --- a/process.c +++ b/process.c @@ -1595,7 +1595,19 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp) key = check_exec_redirect_fd(key, 1); if (FIXNUM_P(key) && (FIX2INT(key) == 1 || FIX2INT(key) == 2)) flags = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC); - else + else if (TYPE(key) == T_ARRAY) { + int i; + for (i = 0; i < RARRAY_LEN(key); i++) { + VALUE v = RARRAY_PTR(key)[i]; + VALUE fd = check_exec_redirect_fd(v, 1); + if (FIX2INT(fd) != 1 && FIX2INT(fd) != 2) break; + } + if (i == RARRAY_LEN(key)) + flags = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC); + else + flags = INT2NUM(O_RDONLY); + } + else flags = INT2NUM(O_RDONLY); perm = INT2FIX(0644); param = hide_obj(rb_ary_new3(3, hide_obj(EXPORT_DUP(path)), diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 0fe687fcb7..94fda02ebb 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -613,6 +613,17 @@ class TestProcess < Test::Unit::TestCase } end + def test_execopts_redirect_to_out_and_err + with_tmpchdir {|d| + ret = system(RUBY, "-e", 'STDERR.print "e"; STDOUT.print "o"', [:out, :err] => "foo") + assert_equal(true, ret) + assert_equal("eo", File.read("foo")) + ret = system(RUBY, "-e", 'STDERR.print "E"; STDOUT.print "O"', [:err, :out] => "bar") + assert_equal(true, ret) + assert_equal("EO", File.read("bar")) + } + end + def test_execopts_redirect_dup2_child with_tmpchdir {|d| Process.wait spawn(RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'", -- cgit v1.2.3