From: nobu.nakada@... Date: 2002-09-30T16:30:22+09:00 Subject: [ruby-dev:18420] Re: rubicon on EWS4800 なかだです。 At Mon, 30 Sep 2002 11:51:49 +0900, WATANABE Tetsuya wrote: > このパッチのよろしくないところは、fseek のエラー処理 > (エラーになるか確認したかったため)と「struct OpenFile > の mode」の bit を増やしているところです。 やってることはほぼ同じだと思います。ただ、[ruby-dev:18396]によ るとfseek()の前にもfflush()が必要なように見えるんですが。 このパッチを当てたconfigureで、whether need to flushのテストの 結果はどうなるでしょうか。とくにbefore seek。 Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.142 diff -u -2 -p -r1.142 configure.in --- configure.in 25 Sep 2002 07:03:01 -0000 1.142 +++ configure.in 29 Sep 2002 23:07:32 -0000 @@ -251,5 +251,8 @@ beos*) ;; cygwin*) rb_cv_have_daylight=no ac_cv_var_tzname=no - ac_cv_func__setjmp=no;; + ac_cv_func__setjmp=no + rb_cv_need_io_flush_between_rw=no + rb_cv_need_io_flush_before_seek=no + ;; mingw*) LIBS="-lwsock32 -lmsvcrt $LIBS" ac_cv_header_a_out_h=no @@ -267,4 +270,6 @@ mingw*) LIBS="-lwsock32 -lmsvcrt $LIBS" ac_cv_func_telldir=yes ac_cv_func_crypt=no + rb_cv_need_io_flush_between_rw=no + rb_cv_need_io_flush_before_seek=no ;; os2_emx*) LIBS="-lm $LIBS" @@ -568,4 +573,46 @@ 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 -o \ + "$rb_cv_need_io_flush_before_seek" = yes; then + AC_DEFINE(NEED_IO_FLUSH, 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.160 diff -u -2 -p -r1.160 io.c --- io.c 25 Sep 2002 07:03:01 -0000 1.160 +++ io.c 30 Sep 2002 06:18:36 -0000 @@ -183,4 +183,6 @@ rb_io_check_closed(fptr) } +static void io_fflush _((FILE *, OpenFile *)); + void rb_io_check_readable(fptr) @@ -190,4 +192,9 @@ rb_io_check_readable(fptr) rb_raise(rb_eIOError, "not opened for reading"); } +#if NEED_IO_FLUSH + if ((fptr->mode & FMODE_WBUF) && !fptr->f2) { + io_fflush(fptr->f, fptr); + } +#endif } @@ -199,4 +206,9 @@ rb_io_check_writable(fptr) rb_raise(rb_eIOError, "not opened for writing"); } +#if NEED_IO_FLUSH + if ((fptr->mode & FMODE_RBUF) && !fptr->f2) { + io_fflush(fptr->f, fptr); + } +#endif } @@ -248,5 +260,5 @@ io_fflush(f, fptr) TRAP_END; if (n == EOF) rb_sys_fail(fptr->path); - fptr->mode &= ~FMODE_WBUF; + fptr->mode &= ~(FMODE_WBUF|FMODE_RBUF); } @@ -389,4 +401,21 @@ rb_io_tell(io) #endif +#if NEED_IO_FLUSH +static void +flush_before_seek(fptr) + OpenFile *fptr; +{ + int mode = fptr->mode; + if (mode & FMODE_RBUF) { + io_fflush(fptr->f, fptr); + } + if (mode & FMODE_WBUF) { + io_fflush((fptr->f2 ? fptr->f2 : fptr->f), fptr); + } +} +#else +#define flush_before_seek(fptr) ((void)(fptr)) +#endif + static VALUE rb_io_seek(io, offset, whence) @@ -398,4 +427,5 @@ rb_io_seek(io, offset, whence) GetOpenFile(io, fptr); + flush_before_seek(fptr); pos = fseeko(fptr->f, NUM2OFFT(offset), whence); if (pos != 0) rb_sys_fail(fptr->path); @@ -429,4 +459,5 @@ rb_io_set_pos(io, offset) GetOpenFile(io, fptr); + flush_before_seek(fptr); pos = fseeko(fptr->f, NUM2OFFT(offset), SEEK_SET); if (pos != 0) rb_sys_fail(fptr->path); @@ -443,4 +474,5 @@ rb_io_rewind(io) GetOpenFile(io, fptr); + flush_before_seek(fptr); if (fseeko(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); @@ -472,4 +504,5 @@ rb_io_eof(io) if (ch != EOF) { ungetc(ch, fptr->f); + fptr->mode |= FMODE_RBUF; return Qfalse; } @@ -718,4 +751,5 @@ read_all(fptr, siz) if (bytes == 0) return rb_str_new(0,0); if (bytes != siz) rb_str_resize(str, bytes); + fptr->mode |= FMODE_RBUF; return str; @@ -755,4 +789,5 @@ io_read(argc, argv, io) rb_sys_fail(fptr->path); } + fptr->mode |= FMODE_RBUF; RSTRING(str)->len = n; RSTRING(str)->ptr[n] = '\0'; @@ -905,4 +940,5 @@ rb_io_getline_fast(fptr, delim) if (!NIL_P(str)) { + fptr->mode |= FMODE_RBUF; fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -960,4 +996,5 @@ rb_io_getline(rs, fptr) if (!NIL_P(str)) { + fptr->mode |= FMODE_RBUF; fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -2233,4 +2270,6 @@ io_reopen(io, nfile) } if ((orig->mode & FMODE_READABLE) && pos >= 0) { + flush_before_seek(fptr); + flush_before_seek(orig); fseeko(fptr->f, pos, SEEK_SET); fseeko(orig->f, pos, SEEK_SET); Index: rubyio.h =================================================================== RCS file: /cvs/ruby/src/ruby/rubyio.h,v retrieving revision 1.18 diff -u -2 -p -r1.18 rubyio.h --- rubyio.h 16 Aug 2002 02:52:25 -0000 1.18 +++ rubyio.h 21 Sep 2002 17:35:51 -0000 @@ -33,4 +33,5 @@ typedef struct OpenFile { #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はできる。 中田 伸悦