Project

General

Profile

Bug #1755

IO#reopen Doesn't Fully Associate with Given Stream on 1.9; Ignores pos on 1.8

Added by runpaint (Run Paint Run Run) over 10 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]
Backport:
[ruby-core:24240]

Description

=begin
$ cat io-reopen.rb
file1 = File.open('a')

file2 = File.open('b')

file1.gets # => "ant\n"
file2.gets # => "1\n"

file1.reopen(file2)

p file1.gets # => "2\n"

$ echo -e "ant\nbear\ncroc" >a
$ echo -e "1\n2\n3" >b
$ ruby -v io-reopen2.rb
ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]
"bear\n"

I have nothing against bears, but in this instance suspect 2 would be more appropriate. However, if we call file.pos before the #reopen, it works:

$ cat io-reopen.rb
file1 = File.open('a')

file2 = File.open('b')

file1.gets # => "ant\n"
file2.gets # => "1\n"

file1.pos # <--- Vital
file1.reopen(file2)

p file1.gets # => "2\n"

$ ruby -v io-reopen2.rb
ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]
"2\n"

Note that 1.8 prints nil in both cases because #reopen doesn't copy across the position. We must manually set file1.pos to file2.pos.

$ cat io-reopen.rb
file1 = File.open('a')

file2 = File.open('b')

file1.gets # => "ant\n"
file2.gets # => "1\n"

file1.reopen(file2)
file1.pos = file2.pos # <-- 1.8 doesn't copy across the pos

p file1.gets # => "2\n"

$ ruby8 -v io-reopen2.rb
ruby 1.8.8dev (2009-07-01) [i686-linux]
"2\n"
=end

History

#1

Updated by runpaint (Run Paint Run Run) over 10 years ago

=begin
('io-reopen2.rb' should be 'io-reopen.rb' in the above examples. :-()
=end

#2

Updated by yugui (Yuki Sonoda) over 10 years ago

  • Target version set to 1.9.2

=begin

=end

#3

Updated by yugui (Yuki Sonoda) over 10 years ago

  • Assignee set to nobu (Nobuyoshi Nakada)

=begin

=end

#4

Updated by nobu (Nobuyoshi Nakada) over 10 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r24144.
=end

#5

Updated by runpaint (Run Paint Run Run) over 10 years ago

=begin
Thanks, nobu. There's some related oddness, however:

$ echo -e "ant\nalien\n" > a
$ echo -e "bear\nbison\n" > b
$ cat reopen.rb

a = File.open('a')
b = File.open('b')
a.gets
b.reopen(a)
p b.gets

$ ruby -v reopen.rb
ruby 1.9.2dev (2009-08-02 trunk 24352) [i686-linux]
"alien\n"

$ ruby86 -v reopen.rb
ruby 1.8.6 (2009-07-20 patchlevel 381) [i686-linux]
nil

$ cat reopen2.rb
a = File.open('a')
b = File.open('b')
a.reopen(b)
a.gets
a.reopen(b)
p a.gets

$ ruby -v reopen2.rb
ruby 1.9.2dev (2009-08-02 trunk 24352) [i686-linux]
nil

$ ruby86 -v reopen2.rb
ruby 1.8.6 (2009-07-20 patchlevel 381) [i686-linux]
"bear\n"

Also, what are we to do about 1.8 not copying across the #pos? Will r24144 fix that, or shall I open a separate ticket for 1.8?

=end

#6

Updated by matz (Yukihiro Matsumoto) over 10 years ago

=begin
Hi,

In message "Re: [ruby-core:24686] [Bug #1755] IO#reopen Doesn't Fully Associate with Given Stream on 1.9; Ignores pos on 1.8"
on Sun, 2 Aug 2009 16:12:19 +0900, Run Paint Run Run redmine@ruby-lang.org writes:

|Thanks, nobu. There's some related oddness, however:

On your platform, ruby 1.8 seems to copy the position in the stream
when 1.9 don't. 1.8 does simply use dup2 + fdopen, where no standard
define if position information is shared among such file descriptors
or not, as far as I know. So it's up to stdio of the platform. 1.9
implements our own I/O, so we can define the behavior.

                        matz.

=end

#7

Updated by runpaint (Run Paint Run Run) over 10 years ago

=begin

On your platform, ruby 1.8 seems to copy the position in the stream
when 1.9 don't. 1.8 does simply use dup2 + fdopen, where no standard
define if position information is shared among such file descriptors
or not, as far as I know. So it's up to stdio of the platform. 1.9
implements our own I/O, so we can define the behavior.

Apologies for being dense, but does this apply only to copying across the #pos, or to all of the differences I described? IOW, is the behaviour below intentional on 1.9, i.e. by design, or operating-system dependent ("undefined")?

$ cat reopen.rb
File.open('f','w') do |f|
10000.times {|n| f.puts n }
end
a = File.open('f')
b = File.open('f')
a.reopen(b)
a.gets
a.reopen(b)
p a.gets

$ ruby -v reopen.rb
ruby 1.9.2dev (2009-09-03 trunk 24741) [i686-linux]
"60\n"
$ ruby8 -v reopen.rb
ruby 1.8.8dev (2009-09-04) [i686-linux]
"0\n"

=end

#8

Updated by ujihisa (Tatsuhiro Ujihisa) about 10 years ago

  • Status changed from Closed to Assigned

=begin
The last question from Run Paint Run Run doesn't seem to be answered yet.

# This issue is related to #2516
# http://redmine.ruby-lang.org/issues/show/2516
=end

#9

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Assigned to Closed

=begin
Hi,

This weird behavior is caused by buffering. This may be improved in
the future, but at least currently, is not a bug. [ruby-core:28335]

To avoid this, I recommend you to avoid IO#reopen. If it is really
needed, use only against IO that has never been read yet.

There is some tickets related to the same reason.
I'll close them and register new ticket to Feature tracker to improve
this issue.

--
Yusue Endoh mame@tsg.ne.jp
=end

Also available in: Atom PDF