ruby-changes:40671
From: nobu <ko1@a...>
Date: Wed, 25 Nov 2015 21:24:06 +0900 (JST)
Subject: [ruby-changes:40671] nobu:r52750 (trunk): io.c: try to_io first
nobu 2015-11-25 21:23:42 +0900 (Wed, 25 Nov 2015) New Revision: 52750 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52750 Log: 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] Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 52749) +++ ChangeLog (revision 52750) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Nov 25 21:23:39 2015 Nobuyoshi Nakada <nobu@r...> + + * 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@r...> * io.c (argf_getpartial): should not resize str if the second Index: io.c =================================================================== --- io.c (revision 52749) +++ io.c (revision 52750) @@ -10573,54 +10573,57 @@ copy_stream_body(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L10573 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; Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 52749) +++ test/ruby/test_io.rb (revision 52750) @@ -3,6 +3,7 @@ require 'test/unit' https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L3 require 'tmpdir' require "fcntl" require 'io/nonblock' +require 'pathname' require 'socket' require 'stringio' require 'timeout' @@ -888,6 +889,17 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L889 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 { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/