[Bug #2516] IO#reopen Compatibility (original: )

e$B%A%1%C%He(B #2516 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B1sF#$G$9!#e(B

IO#reopen e$B$K$D$$$FD4$Y$F$$$k$N$G$9$,!"$5$C$Q$j$o$+$j$^$;$s!#e(B

$ cat foo.txt
1
2
3

1.8: e$BESCf0LCV$Ne(B File e$B$Ke(B reopen e$B$7$?$iFI$_9~$a$J$$e(B

f1, f2 = File.new(“foo.txt”), File.new(“foo.txt”)
f2.gets
f1.reopen(f2)
p f1.gets #=> nil
p f1.gets #=> nil
p f1.gets #=> nil
p f1.pos #=> 2

1.9: reopen e$B$7$?8e$Oe(B get e$BAa$$!$A!)e(B pos

e$B$N7k2L$,0c$&e(B
f1, f2 = File.new(“foo.txt”), File.new(“foo.txt”)
f1.reopen(f2)
p f1.gets #=> “1\n”
p f2.gets #=> nil
p f1.pos #=> 2
p f2.pos #=> 2

f1, f2 = File.new(“foo.txt”), File.new(“foo.txt”)
f1.reopen(f2)
p f2.gets #=> “1\n”
p f1.gets #=> nil
p f1.pos #=> 6
p f2.pos #=> 2

reopen e$B$NA[Dj%f!<%9%1!<%9$C$F$I$s$J$s$G$7$g$&$+!#e(B
dup2
e$B$N$h$&$J$b$N$+$H;W$C$F$$$?$N$G$9$,!"$=$s$J5sF0$G$b$J$$$G$9$h$M!#e(B
e$B%f!<%9%1!<%9<!Bh$G$O!"e(Breopen e$B$N0z?t$KEO$5$l$?e(B IO e$B$Oe(B
close e$B$7$F$7$^$&e(B
e$BJ}$,:.Mp$7$J$/$F$9$`$H;W$$$^$9!#e(B

e$B$G$-$l$P%f!<%9%1!<%9$N5DO@$NA0$K5sF0$,JQ$o$C$?M}M3$rGD0.$7$?$+$C$?e(B

e$B$N$G$9$,!"2?$,%P%0$G2?$,;EMM$+$o$+$j$^$;$s$G$7$?!#e(B


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/2516

 1
 p f1.pos  #=> 2
 f1.reopen(f2)

    char buf[80];
    printf("pos %d\n", ftell(f2));

pos 6

内部的には struct FILEが struct _IO_marker をポイントしていて、 _IO_markerは共有、そっちでpos管理している。

åå¿œãŒãªã„ã®ã§ã€èª°ã‚‚èˆˆå‘³ãŒãªã„ã®ã ã¨åˆ¤æ–­ã—ã¾ã™ã€‚é è—¤ã•ã‚“ã¨IRCで調整のうえ
kosakiがボールを握ることにしました。
現状 io.dup もposが狂った動きをしているので一緒に直すことになると思います。

たぶん、月末のTokyo Ruby KaigiのハンズオンでHello Worldとか

教えてもらいながら、内職ハックする事になりそう。

2010å¹´2月11æ—¥15:24 Yusuke E. [email protected]:

 2

 p f2.gets #=> “1\n”

できればユースケースの議論の前に挙動が変わった理由を把握したかった

のですが、何がバグで何が仕様かわかりませんでした。

Linuxだと同等の以下のCプログラムが

#include <stdio.h>

int main(void)
{
FILE *f1, *f2;
char buf[80];

    f1 = fopen("inputfile", "r+");
    printf("%s", fgets(buf, 80, f1));
    f2 = freopen("inputfile", "r+", f1);

    printf("%s", fgets(buf, 80, f1));
    printf("%s", fgets(buf, 80, f1));
    printf("%s", fgets(buf, 80, f1));

    printf("pos %d\n", ftell(f1));
    printf("pos %d\n", ftell(f2));

}

こうなります。

1
1
2
3
pos 6
pos 6

内部的には struct FILEが struct _IO_marker をポイントしていて、
_IO_markerは共有、そっちでpos管理している。

また SUSをみると

http://www.opengroup.org/onlinepubs/009695399/functions/freopen.html

最初に引数streamをflushしてcloseするよん。とか書いてあるけど、Linuxは単にdupしてるだけなんでcloseしてないみたい。なんか互換性の理由があるのかな?

IO系は見るからに標準Cライブラリの影響が色濃いので、これに合わせればいいんじゃないでしょうかねぇ・・・
nalshさんあたりが悲鳴を上げる恐れがありますが。

e$B1sF#$G$9!#e(B

2010e$BG/e(B2e$B7ne(B15e$BF|e(B13:25 KOSAKI Motohiro
[email protected]:

e$BH?1~$,$J$$$N$G!"C/$b6=L#$,$J$$$N$@$HH=CG$7$^$9!#1sF#$5$s$He(BIRCe$B$GD4@0$N$&$(e(B
kosakie$B$,%!<%k$r0.$k$3$H$K$7$^$7$?!#e(B
e$B8=>ue(B io.dup e$B$be(Bpose$B$,68$C$?F0$-$r$7$F$$$k$N$G0l=o$KD>$9$3$H$K$J$k$H;W$$$^$9!#e(B

IO e$B$H$+6=L#$J$$$N$G$h$m$7$/$*4j$$$7$^$9!#e(B

e$B$"$H!"e(BIRC e$B$GOC$7$?e(B pos
e$B$N$H$A68$C$?F0$-$K$D$$$F5-O?$G$9!#e(B

e$B!{e(B pos e$B$,Ii$K$J$ke(B

$ cat foo.txt
1
2
3

f1 = File.new(“foo.txt”)
f2 = File.new(“foo.txt”)
f2.gets
f1.reopen(f2)
f2.gets
f1.rewind
p f2.pos #=> -2

e$B!{e(B pos e$B$KI{:nMQ$,$"$ke(B

f1 = File.new(“foo.txt”)
f2 = File.new(“foo.txt”)
f2.gets
f1.reopen(f2)
f2.gets
p f1.pos #=> 6
p f2.pos #=> 4
p f1.pos #=> 4