summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-02 14:59:25 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-02 14:59:25 +0000
commit3a76a401967aca5a5386e980f26a7bd925da64b6 (patch)
tree9126bfc47ee662b8a7e2e47d28de217bed3fc948
parent0c767620cd00ec0739debea2b2a33f0f3e3ab65f (diff)
* 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
-rw-r--r--ChangeLog16
-rw-r--r--configure.in48
-rw-r--r--io.c52
-rw-r--r--rubyio.h1
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 <nobu.nokada@softhome.net>
+
+ * 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 <nobu.nokada@softhome.net>
* 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 <stdio.h>
+
+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)