From 3a76a401967aca5a5386e980f26a7bd925da64b6 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 2 Oct 2002 14:59:25 +0000 Subject: * configure.in (RUBY_CHECK_IO_NEED_FLUSH): check whether fflush() is needed. * io.c (flush_before_seek): flush before seek if buffered data may remain. * io.c (rb_io_check_readable): flush if the last operation was write. * io.c (rb_io_check_writable): flush if the last operation was read. * rubyio.h (FMODE_RBUF): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 16 ++++++++++++++++ configure.in | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ io.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- rubyio.h | 1 + 4 files changed, 108 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b060d7a3a..5c6a0e440c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Wed Oct 2 23:32:48 2002 Nobuyoshi Nakada + + * configure.in (RUBY_CHECK_IO_NEED_FLUSH): check whether fflush() + is needed. + + * io.c (flush_before_seek): flush before seek if buffered data + may remain. + + * io.c (rb_io_check_readable): flush if the last operation was + write. + + * io.c (rb_io_check_writable): flush if the last operation was + read. + + * rubyio.h (FMODE_RBUF): added. + Wed Oct 2 23:09:20 2002 Nobuyoshi Nakada * io.c (rb_io_wait_readable): handle retryable errors. diff --git a/configure.in b/configure.in index 8310f89523..90d2230f6b 100644 --- a/configure.in +++ b/configure.in @@ -249,11 +249,15 @@ darwin*) LIBS="-lobjc $LIBS";; 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__setjmp=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 ac_cv_header_utime_h=no @@ -569,6 +573,50 @@ else fi 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" diff --git a/io.c b/io.c index bad70da8ae..ccb00739c1 100644 --- a/io.c +++ b/io.c @@ -182,6 +182,29 @@ rb_io_check_closed(fptr) } } +static void io_fflush _((FILE *, OpenFile *)); + +#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) fseeko(flush_before_seek(fptr)->f, ofs, whence) +#define io_tell(fptr) ftello(flush_before_seek(fptr)->f) + void rb_io_check_readable(fptr) OpenFile *fptr; @@ -189,6 +212,12 @@ rb_io_check_readable(fptr) if (!(fptr->mode & FMODE_READABLE)) { 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); + } + fptr->mode |= FMODE_RBUF; +#endif } void @@ -198,6 +227,11 @@ rb_io_check_writable(fptr) if (!(fptr->mode & FMODE_WRITABLE)) { 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); + } +#endif } int @@ -402,7 +436,7 @@ rb_io_tell(io) off_t pos; GetOpenFile(io, fptr); - pos = ftello(fptr->f); + pos = io_tell(fptr); if (ferror(fptr->f)) rb_sys_fail(fptr->path); return OFFT2NUM(pos); } @@ -422,7 +456,7 @@ rb_io_seek(io, offset, whence) off_t pos; GetOpenFile(io, fptr); - pos = fseeko(fptr->f, NUM2OFFT(offset), whence); + pos = io_seek(fptr, NUM2OFFT(offset), whence); if (pos != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); @@ -453,7 +487,7 @@ rb_io_set_pos(io, offset) off_t pos; GetOpenFile(io, fptr); - pos = fseeko(fptr->f, NUM2OFFT(offset), SEEK_SET); + pos = io_seek(fptr, NUM2OFFT(offset), SEEK_SET); if (pos != 0) rb_sys_fail(fptr->path); clearerr(fptr->f); @@ -467,7 +501,7 @@ rb_io_rewind(io) OpenFile *fptr; GetOpenFile(io, fptr); - if (fseeko(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) { gets_lineno -= fptr->lineno; @@ -680,7 +714,7 @@ remain_size(fptr) #endif ) { - pos = ftello(fptr->f); + pos = io_tell(fptr); if (st.st_size > pos && pos >= 0) { siz = st.st_size - pos + 1; if (siz > LONG_MAX) { @@ -705,7 +739,7 @@ read_all(fptr, siz) READ_CHECK(fptr->f); if (!siz) siz = BUFSIZ; str = rb_tainted_str_new(0, siz); - pos = ftello(fptr->f); + pos = io_tell(fptr); for (;;) { n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f); if (pos > 0 && n == 0 && bytes == 0) { @@ -2207,7 +2241,7 @@ io_reopen(io, nfile) if (fptr == orig) return io; if (orig->mode & FMODE_READABLE) { - pos = ftello(orig->f); + pos = io_tell(orig); } if (orig->f2) { io_fflush(orig->f2, orig); @@ -2241,8 +2275,8 @@ io_reopen(io, nfile) fptr->f = rb_fdopen(fd, mode); } if ((orig->mode & FMODE_READABLE) && pos >= 0) { - fseeko(fptr->f, pos, SEEK_SET); - fseeko(orig->f, pos, SEEK_SET); + io_seek(fptr, pos, SEEK_SET); + io_seek(orig, pos, SEEK_SET); } if (fptr->f2) { diff --git a/rubyio.h b/rubyio.h index 80ad45932e..377a66b719 100644 --- a/rubyio.h +++ b/rubyio.h @@ -32,6 +32,7 @@ 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) -- cgit v1.2.3