summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-25 12:23:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-25 12:23:42 +0000
commit7d92e5cf730596429fd33ce7a580112b28528662 (patch)
treeddb7a039269e625ad58f4bdc8b9caa2191055f32
parent012368007f0a7fce81a0083c96aa549c21141d05 (diff)
io.c: try to_io first
* io.c (copy_stream_body): try to_io conversion before read, readpartial, and write methods. [ruby-dev:49008] [Bug #11199] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52750 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--io.c75
-rw-r--r--test/ruby/test_io.rb12
3 files changed, 56 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 25905864c6..1bcd54ee5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Nov 25 21:23:39 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * io.c (copy_stream_body): try to_io conversion before read,
+ readpartial, and write methods. [ruby-dev:49008] [Bug #11199]
+
Wed Nov 25 10:55:21 2015 Shugo Maeda <shugo@ruby-lang.org>
* io.c (argf_getpartial): should not resize str if the second
diff --git a/io.c b/io.c
index 9d75c230f4..9306b81d18 100644
--- a/io.c
+++ b/io.c
@@ -10573,54 +10573,57 @@ copy_stream_body(VALUE arg)
stp->total = 0;
- if (src_io == argf) {
- src_fd = -1;
- }
- else if (RB_TYPE_P(src_io, T_FILE)) {
- goto io_src;
- }
- else if (!RB_TYPE_P(src_io, T_STRING) &&
- (rb_respond_to(src_io, id_read) ||
- rb_respond_to(src_io, id_readpartial))) {
+ if (src_io == argf ||
+ !(RB_TYPE_P(src_io, T_FILE) ||
+ RB_TYPE_P(src_io, T_STRING) ||
+ rb_respond_to(src_io, rb_intern("to_path")))) {
src_fd = -1;
}
else {
- VALUE args[2];
- FilePathValue(src_io);
- args[0] = src_io;
- args[1] = INT2NUM(O_RDONLY|common_oflags);
- src_io = rb_class_new_instance(2, args, rb_cFile);
- stp->src = src_io;
- stp->close_src = 1;
- io_src:
+ VALUE tmp_io = rb_io_check_io(src_io);
+ if (!NIL_P(tmp_io)) {
+ src_io = tmp_io;
+ }
+ else if (!RB_TYPE_P(src_io, T_FILE)) {
+ VALUE args[2];
+ FilePathValue(src_io);
+ args[0] = src_io;
+ args[1] = INT2NUM(O_RDONLY|common_oflags);
+ src_io = rb_class_new_instance(2, args, rb_cFile);
+ stp->src = src_io;
+ stp->close_src = 1;
+ }
GetOpenFile(src_io, src_fptr);
rb_io_check_byte_readable(src_fptr);
src_fd = src_fptr->fd;
}
stp->src_fd = src_fd;
- if (dst_io == argf) {
- dst_fd = -1;
- }
- else if (RB_TYPE_P(dst_io, T_FILE)) {
- dst_io = GetWriteIO(dst_io);
- stp->dst = dst_io;
- goto io_dst;
- }
- else if (!RB_TYPE_P(dst_io, T_STRING) &&
- rb_respond_to(dst_io, id_write)) {
+ if (dst_io == argf ||
+ !(RB_TYPE_P(dst_io, T_FILE) ||
+ RB_TYPE_P(dst_io, T_STRING) ||
+ rb_respond_to(dst_io, rb_intern("to_path")))) {
dst_fd = -1;
}
else {
- VALUE args[3];
- FilePathValue(dst_io);
- args[0] = dst_io;
- args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
- args[2] = INT2FIX(0666);
- dst_io = rb_class_new_instance(3, args, rb_cFile);
- stp->dst = dst_io;
- stp->close_dst = 1;
- io_dst:
+ VALUE tmp_io = rb_io_check_io(dst_io);
+ if (!NIL_P(tmp_io)) {
+ dst_io = tmp_io;
+ }
+ else if (!RB_TYPE_P(dst_io, T_FILE)) {
+ VALUE args[3];
+ FilePathValue(dst_io);
+ args[0] = dst_io;
+ args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
+ args[2] = INT2FIX(0666);
+ dst_io = rb_class_new_instance(3, args, rb_cFile);
+ stp->dst = dst_io;
+ stp->close_dst = 1;
+ }
+ else {
+ dst_io = GetWriteIO(dst_io);
+ stp->dst = dst_io;
+ }
GetOpenFile(dst_io, dst_fptr);
rb_io_check_writable(dst_fptr);
dst_fd = dst_fptr->fd;
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 12c4abdbe4..bb878ea148 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3,6 +3,7 @@ require 'test/unit'
require 'tmpdir'
require "fcntl"
require 'io/nonblock'
+require 'pathname'
require 'socket'
require 'stringio'
require 'timeout'
@@ -888,6 +889,17 @@ class TestIO < Test::Unit::TestCase
dst.close!
end
+ def test_copy_stream_pathname_to_pathname
+ bug11199 = '[ruby-dev:49008] [Bug #11199]'
+ mkcdtmpdir {
+ File.open("src", "w") {|f| f << "ok" }
+ src = Pathname.new("src")
+ dst = Pathname.new("dst")
+ IO.copy_stream(src, dst)
+ assert_equal("ok", IO.read("dst"), bug11199)
+ }
+ end
+
def test_copy_stream_write_in_binmode
bug8767 = '[ruby-core:56518] [Bug #8767]'
mkcdtmpdir {