Bug #2747
closedio.dup doesn't handle pos properly
Description
Updated by kosaki (Motohiro KOSAKI) almost 15 years ago
=begin
[ruby-dev:39479]) (Rejected)" href="/issues/2516">#2516 と関連しています
=end
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
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
Updated by mame (Yusuke Endoh) over 14 years ago
=begin
kosaki さん
遠藤です。
2010年2月15日21:40 Motohiro KOSAKI redmine@ruby-lang.org:
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 mame@tsg.ne.jp
=end
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 mame@tsg.ne.jp
=end