なかだです。

http://pc11.2ch.net/test/read.cgi/tech/1188014743/716 で見掛けた
のですが、DOSISHなシステムで改行コードがLFのファイルを読もうとす
ると、おかしなことになるようです。

$ ./ruby -v -e 'p ARGF.pos; p ARGF.eof?; p ARGF.pos' COPYING
ruby 1.8.6 (2007-10-18 revision 13735) [i386-mingw32]
0
false
-e:1: [BUG] rb_sys_fail(COPYING) - errno == 0
ruby 1.8.6 (2007-10-18) [i386-mingw32]

$ ./ruby -v -e 'p ARGF.getc; p ARGF.pos' COPYING
ruby 1.8.6 (2007-10-18 revision 13735) [i386-mingw32]
82
-e:1: [BUG] rb_sys_fail(COPYING) - errno == 0
ruby 1.8.6 (2007-10-18) [i386-mingw32]

これは、VC runtimeのstdioはtext modeの変換をfile descriptorレベ
ルに任せているため、fseek()の中では、削られたかも知れないデータ
を類推して結果を補正しているためです。

根本的には、VCのstdioの設計ではCR+LF以外の改行を含むファイルに対
するseek/tellの動作は不定ということがあるのですが、異常終了して
しまうのはあんまりなので、とりあえずerrnoもチェックするようにし
ておく、というのはどうでしょうか。


Index: io.c =================================================================== --- io.c (revision 13735) +++ io.c (working copy) @@ -246,4 +246,5 @@ flush_before_seek(fptr) io_fflush(GetWriteFile(fptr), fptr); } + errno = 0; return fptr; } @@ -669,5 +670,5 @@ rb_io_tell(io) GetOpenFile(io, fptr); pos = io_tell(fptr); - if (pos < 0) rb_sys_fail(fptr->path); + if (pos < 0 && errno) rb_sys_fail(fptr->path); return OFFT2NUM(pos); } @@ -684,5 +685,5 @@ rb_io_seek(io, offset, whence) GetOpenFile(io, fptr); pos = io_seek(fptr, pos, whence); - if (pos < 0) rb_sys_fail(fptr->path); + if (pos < 0 && errno) rb_sys_fail(fptr->path); clearerr(fptr->f);
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦