From: nobu.nakada@... Date: 2002-10-02T19:41:35+09:00 Subject: [ruby-dev:18439] Re: rubicon on EWS4800 なかだです。 At Wed, 2 Oct 2002 18:48:50 +0900, Tanaka Akira wrote: > > うーん、てことは1.6にもバックポートする必要あり? > > どうなんでしょうね。 > > 悪影響が出る可能性が低い変更なのでバックポートしても問題ないと思います > が。 とりあえずやってみましたが、そうかFMODE_WBUFも追加しなきゃいけ ないのか…。 Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.68.2.38 diff -u -2 -p -r1.68.2.38 configure.in --- configure.in 2 Oct 2002 04:28:00 -0000 1.68.2.38 +++ configure.in 2 Oct 2002 10:21:49 -0000 @@ -195,8 +195,12 @@ human*) ac_cv_func_getpgrp_void=yes;; beos*) ;; cygwin*) rb_cv_have_daylight=no + rb_cv_need_io_flush_between_rw=no + rb_cv_need_io_flush_before_seek=no ac_cv_var_tzname=no ac_cv_func_setitimer=no ;; mingw*) LIBS="-lwsock32 -lmsvcrt $LIBS" + rb_cv_need_io_flush_between_rw=no + rb_cv_need_io_flush_before_seek=no ac_cv_header_a_out_h=no ac_cv_header_pwd_h=no @@ -439,4 +443,48 @@ else fi +AC_DEFUN(RUBY_CHECK_IO_NEED_FLUSH, +[AC_CACHE_CHECK(whether need to flush [$1], [$2], + [AC_TRY_RUN([ +#include + +char *fn = "conftest.dat"; +char *wombat = "wombat\n"; +char *koara = "koara\n"; + +int main() +{ + char buf[BUFSIZ]; + FILE *f; + int r = 1; + + if (!(f = fopen(fn, "w+"))) return 1; + fputs(wombat, f); + fflush(f); + fseek(f, 0, 0); + if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail; + ]ifelse(index($2,between_rw),-1,fflush(f);)[ + fputs(koara, f); + ]ifelse(index($2,before_seek),-1,fflush(f);)[ + fseek(f, 0, 0); + ]ifelse(index($2,between_rw),-1,fflush(f);)[ + if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail; + if (!fgets(buf, BUFSIZ, f) || strcmp(buf, koara)) goto fail; + r = 0; + fail: + fclose(f); + unlink(fn); + return r; +} +], [$2]=no, [$2]=yes, [$2]=yes)])]) + +RUBY_CHECK_IO_NEED_FLUSH(between R/W, rb_cv_need_io_flush_between_rw) +RUBY_CHECK_IO_NEED_FLUSH(before seek, rb_cv_need_io_flush_before_seek) +if test "$rb_cv_need_io_flush_between_rw" = yes; then + AC_DEFINE(NEED_IO_FLUSH_BETWEEN_RW, 1) +fi +if test "$rb_cv_need_io_flush_before_seek" = yes; then + AC_DEFINE(NEED_IO_FLUSH_BEFORE_SEEK, 1) +fi + dnl default value for $KANJI DEFAULT_KCODE="KCODE_NONE" Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.69.2.28 diff -u -2 -p -r1.69.2.28 io.c --- io.c 1 Aug 2002 04:54:35 -0000 1.69.2.28 +++ io.c 2 Oct 2002 10:37:05 -0000 @@ -152,4 +152,27 @@ rb_io_check_closed(fptr) } +static void io_fflush _((FILE *, const char *)); + +#if NEED_IO_FLUSH_BEFORE_SEEK +static OpenFile * +flush_before_seek(fptr) + OpenFile *fptr; +{ + int mode = fptr->mode; + if (mode & FMODE_RBUF) { + if (!fptr->f2) io_fflush(fptr->f, fptr); + } + if (mode & FMODE_WBUF) { + io_fflush((fptr->f2 ? fptr->f2 : fptr->f), fptr); + } + return fptr; +} +#else +#define flush_before_seek(fptr) fptr +#endif + +#define io_seek(fptr, ofs, whence) fseek(flush_before_seek(fptr)->f, ofs, whence) +#define io_tell(fptr) ftell(flush_before_seek(fptr)->f) + void rb_io_check_readable(fptr) @@ -159,4 +182,11 @@ rb_io_check_readable(fptr) rb_raise(rb_eIOError, "not opened for reading"); } +#if NEED_IO_FLUSH_BETWEEN_RW + if ((fptr->mode & FMODE_WBUF) && !fptr->f2) { + io_fflush(fptr->f, fptr->path); + fptr->mode &= ~FMODE_WBUF; + } + fptr->mode |= FMODE_RBUF; +#endif } @@ -168,4 +198,10 @@ rb_io_check_writable(fptr) rb_raise(rb_eIOError, "not opened for writing"); } +#if NEED_IO_FLUSH_BETWEEN_RW + if ((fptr->mode & FMODE_RBUF) && !fptr->f2) { + io_fflush(fptr->f, fptr->path); + fptr->mode &= ~FMODE_RBUF; + } +#endif } @@ -262,4 +298,7 @@ io_write(io, str) io_fflush(f, fptr->path); } + else { + fptr->mode |= FMODE_WBUF; + } return INT2FIX(n); @@ -305,5 +344,5 @@ rb_io_tell(io) GetOpenFile(io, fptr); - pos = ftell(fptr->f); + pos = io_tell(fptr); if (ferror(fptr->f)) rb_sys_fail(fptr->path); @@ -333,5 +372,5 @@ rb_io_seek(argc, argv, io) GetOpenFile(io, fptr); - pos = fseek(fptr->f, NUM2INT(offset), whence); + pos = io_seek(fptr, NUM2INT(offset), whence); if (pos != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); @@ -348,5 +387,5 @@ rb_io_set_pos(io, offset) GetOpenFile(io, fptr); - pos = fseek(fptr->f, NUM2INT(offset), SEEK_SET); + pos = io_seek(fptr, NUM2INT(offset), SEEK_SET); if (pos != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); @@ -362,5 +401,5 @@ rb_io_rewind(io) GetOpenFile(io, fptr); - if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path); + if (io_seek(fptr, 0L, 0) != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); if (io == current_file) { @@ -518,5 +557,5 @@ read_all(port) ) { - pos = ftell(fptr->f); + pos = io_tell(fptr); if (st.st_size > pos && pos >= 0) { siz = st.st_size - pos + 1; @@ -1853,6 +1892,6 @@ io_reopen(io, nfile) } if ((orig->mode & FMODE_READABLE) && pos >= 0) { - fseek(fptr->f, pos, SEEK_SET); - fseek(orig->f, pos, SEEK_SET); + io_seek(fptr, pos, SEEK_SET); + io_seek(orig, pos, SEEK_SET); } Index: rubyio.h =================================================================== RCS file: /cvs/ruby/src/ruby/rubyio.h,v retrieving revision 1.9.2.1 diff -u -2 -p -r1.9.2.1 rubyio.h --- rubyio.h 17 Dec 2001 08:13:17 -0000 1.9.2.1 +++ rubyio.h 2 Oct 2002 10:32:33 -0000 @@ -32,4 +32,6 @@ typedef struct OpenFile { #define FMODE_BINMODE 4 #define FMODE_SYNC 8 +#define FMODE_WBUF 16 +#define FMODE_RBUF 32 #define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr) -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦