Bug #2747
io.dup doesn't handle pos properly
| Status: | Rejected | Start date: | 02/15/2010 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | - | % Done: | 0% |
|
| Category: | core | |||
| Target version: | 2.0.0 | |||
| ruby -v: | ruby 1.9.2dev (2010-02-03) [x86_64-linux] |
Description
記録のために、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はどこから出てきたのかよく分かりません。
Related issues
History
Updated by kosaki (Motohiro KOSAKI) over 2 years ago
#2516 と関連しています
Updated by kosaki (Motohiro KOSAKI) over 2 years ago
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がずれているので、これもおかしい
Updated by kosaki (Motohiro KOSAKI) over 2 years ago
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が得られている。
Updated by mame (Yusuke Endoh) over 2 years ago
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>
Updated by mame (Yusuke Endoh) about 2 years ago
- Status changed from Open to Rejected
遠藤です。 1.9.2 では仕様ということで reject します。([ruby-core:28335] 他) わかりにくい挙動なことは確かなので、1.9.3 以降での改善を Feature チケットとして別に登録しておきます。 -- Yusuke Endoh <mame@tsg.ne.jp>