summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--NEWS10
-rw-r--r--process.c14
-rw-r--r--test/ruby/test_process.rb11
4 files changed, 41 insertions, 1 deletions
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 <akr@fsij.org>
+
+ * 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 <akr@fsij.org>
* 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'",