なかだです。

At Tue, 23 Dec 2003 13:10:17 +0900,
Tanaka Akira wrote:
> 次のように ungetc を使うと core を吐く場合があります。
> 
> akr@helium:~/ruby/ruby$ ./ruby -e 'open("zz", "w+") {|f| f.print "a"; f.ungetc ?x}'
> -e:1: [BUG] Segmentation fault
> ruby 1.8.1 (2003-12-22) [i686-linux]
> 
> Aborted (core dumped)

私のところではcoreは吐きませんでしたが、巨大なファイルができま
した。単にglibcのバグなのか、それともreadせずにungetc()すること
自体がそもそも未定義動作なのか。

$ cat ungetctest.c
#include <stdio.h>

int main()
{
    FILE *f = fopen("zz", "w+");
    if (!f) return 1;
    if (fwrite("a", 1, 1, f) < 1) {
        perror("fwrite");
        return 1;
    }
    printf("%d\n", ungetc('x', f));
    fclose(f);
    return 0;
}

$ make ungetctest
cc     ungetctest.c   -o ungetctest

$ rm -f zz

$ ./ungetctest
120

$ ls -l zz
-rw-r--r--    1 nobu     nakada   939317057 Dec 23 17:10 zz


Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.241 diff -u -2 -p -r1.241 io.c --- io.c 10 Dec 2003 08:26:31 -0000 1.241 +++ io.c 23 Dec 2003 08:21:48 -0000 @@ -1316,4 +1316,5 @@ rb_io_ungetc(io, c) GetOpenFile(io, fptr); rb_io_check_readable(fptr); + flush_before_seek(fptr); if (ungetc(cc, fptr->f) == EOF && cc != EOF)
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦