summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--io.c83
-rw-r--r--test/ruby/test_io.rb15
3 files changed, 65 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 4decc990db..5c141e2e2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Mar 30 11:27:54 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * io.c (copy_stream_body): use the arguments without conversion if
+ having read, readpartial, and write methods, than conversion by
+ to_path method. [ruby-core:68676] [Bug #11015]
+
Sun Mar 29 21:08:37 2015 SHIBATA Hiroshi <shibata.hiroshi@gmail.com>
* gc.c (objspace_allrefs_destruct_i): fix a typo.
diff --git a/io.c b/io.c
index 1d3677ad62..00b2bbcbe5 100644
--- a/io.c
+++ b/io.c
@@ -10515,52 +10515,57 @@ copy_stream_body(VALUE arg)
stp->total = 0;
- 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;
+ 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))) {
+ src_fd = -1;
}
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;
+ 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:
+ 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 ||
- !(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;
+ 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)) {
+ dst_fd = -1;
}
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;
+ 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:
+ GetOpenFile(dst_io, dst_fptr);
+ rb_io_check_writable(dst_fptr);
+ dst_fd = dst_fptr->fd;
}
stp->dst_fd = dst_fd;
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 81b99d55d1..c37d14c47f 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -873,6 +873,21 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_copy_stream_strio_to_tempfile
+ bug11015 = '[ruby-core:68676] [Bug #11015]'
+ # StringIO to Tempfile
+ src = StringIO.new("abcd")
+ dst = Tempfile.new("baz")
+ ret = IO.copy_stream(src, dst)
+ assert_equal(4, ret)
+ pos = dst.pos
+ dst.rewind
+ assert_equal("abcd", dst.read)
+ assert_equal(4, pos, bug11015)
+ ensure
+ dst.close!
+ end
+
def test_copy_stream_write_in_binmode
bug8767 = '[ruby-core:56518] [Bug #8767]'
mkcdtmpdir {