Bug #1755
closedIO#reopen Doesn't Fully Associate with Given Stream on 1.9; Ignores pos on 1.8
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
Updated by runpaint (Run Paint Run Run) over 15 years ago
=begin
('io-reopen2.rb' should be 'io-reopen.rb' in the above examples. :-()
=end
Updated by yugui (Yuki Sonoda) over 15 years ago
- Assignee set to nobu (Nobuyoshi Nakada)
=begin
=end
Updated by nobu (Nobuyoshi Nakada) over 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r24144.
=end
Updated by runpaint (Run Paint Run Run) over 15 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
Updated by matz (Yukihiro Matsumoto) over 15 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
Updated by runpaint (Run Paint Run Run) over 15 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
Updated by ujihisa (Tatsuhiro Ujihisa) almost 15 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 [ruby-dev:39479]) (Rejected)" href="/issues/2516">#2516¶
http://redmine.ruby-lang.org/issues/show/2516¶
=end
Updated by mame (Yusuke Endoh) over 14 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