Project

General

Profile

Actions

Bug #2747

closed

io.dup doesn't handle pos properly

Added by kosaki (Motohiro KOSAKI) almost 15 years ago. Updated about 12 years ago.

Status:
Rejected
Assignee:
-
Target version:
ruby -v:
ruby 1.9.2dev (2010-02-03) [x86_64-linux]
Backport:
[ruby-dev:40424]

Description

=begin
記録のために、IRCから転記します。

duptest.rb

f1 = File.new("foo.txt")
f2 = f1.dup()
p f1.pos
p f2.gets
p f1.pos
p f2.pos

foo.txt

1
2
3

このようなテストプログラムを実行すると、

0
"1\n"
6
2

となります。dupはf1とf2で同じposが返るべきであるし、6はどこから出てきたのかよく分かりません。
=end


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #2516: IO#reopen Compatibility (original: [ruby-dev:39479])Rejectednobu (Nobuyoshi Nakada)12/23/2009Actions
Actions #1

Updated by kosaki (Motohiro KOSAKI) almost 15 years ago

=begin
[ruby-dev:39479]) (Rejected)" href="/issues/2516">#2516 と関連しています
=end

Actions #2

Updated by kosaki (Motohiro KOSAKI) almost 15 years ago

=begin
1.8.6での挙動

% /usr/bin/ruby -v duptest.rb
ruby 1.8.6 (2009-08-04 patchlevel 383) [x86_64-linux]
0
"1\n"
0
2

f1とf2のposがずれているので、これもおかしい

=end

Actions #3

Updated by kosaki (Motohiro KOSAKI) almost 15 years ago

=begin
6の秘密はstraceが教えてくれている

dup(4) = 5
lseek(4, 0, SEEK_CUR) = 0
lseek(5, 0, SEEK_SET) = 0
lseek(4, 0, SEEK_CUR) = 0
write(1, "0\n", 20
) = 2
read(5, "1\n2\n3\n", 8192) = 6
write(1, ""1\n"\n", 6"1\n"
) = 6
lseek(4, 0, SEEK_CUR) = 6
write(1, "6\n", 26
) = 2
lseek(5, -4, SEEK_CUR) = 2
lseek(5, 0, SEEK_CUR) = 2
write(1, "2\n", 22
)

read(f2, buf, 8192)でバッファリング読み込みしたあと、オフセットを戻すのを忘れて
lseek(f1, 0, SEEK_CUR) でposを読み込むのでファイル終端のposが得られている。

=end

Actions #4

Updated by mame (Yusuke Endoh) over 14 years ago

=begin
kosaki さん
遠藤です。

2010年2月15日21:40 Motohiro KOSAKI :

6の秘密はstraceが教えてくれている

snip

read(f2, buf, 8192)でバッファリング読み込みしたあと、オフセットを戻すのを忘れて
lseek(f1, 0, SEEK_CUR) でposを読み込むのでファイル終端のposが得られている。

dup の前後でバッファを共有していないのが問題ですよね。

しかし、バッファは現在 rb_io_t 構造体に直接埋め込まれてしまっています。
rb_io_t の定義を変えないと、バッファを共有させるのは難しい気がします。

rb_io_t は公開 API であり、etc/ 以下だけでなくいくつかの 3rd party の
拡張ライブラリで実際に使われています。下手にいじると、バイナリ互換性の
問題が起きてしまいそうです。

設計上のバグなんですが、バイナリ互換性を崩してでも修正したいほど重大な
問題ではないと思います。なので 1.9.2 では、

「IO#dup や reopen の元になった IO はもう使ってはいけない (close
しかしてはならない) 。バグだが当面 WONTFIX である。」

と宣言してしまい、いつか他の要因でバイナリ互換性を捨てる際 (遅くとも
2.0) に、あわせて修正するのがいいのではないかと思いました。

もちろん、バイナリ互換性に影響のない形で修正できるなら、それが一番いい
と思います (ただし、煩わしい workaround のせいでひどくメンテナンス性が
落ちるとしたら考えもの) 。

今考えている修正方針の案などがあれば教えてください。

--
Yusuke ENDOH

=end

Actions #5

Updated by mame (Yusuke Endoh) over 14 years ago

  • Status changed from Open to Rejected

=begin
遠藤です。

1.9.2 では仕様ということで reject します。([ruby-core:28335] 他)

わかりにくい挙動なことは確かなので、1.9.3 以降での改善を Feature
チケットとして別に登録しておきます。

--
Yusuke Endoh
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0