[#18440] racc segv revisited — "Akinori MUSHA" <knu@...>

 次のバグの件なんですが、現時点では原因究明を含めて未解決という

24 messages 2002/10/02
[#18617] Re: racc segv revisited — "Akinori MUSHA" <knu@...> 2002/11/02

At Wed, 2 Oct 2002 23:19:59 +0900,

[ruby-dev:18426] Re: rubicon on EWS4800

From: nobu.nakada@...
Date: 2002-10-02 02:54:55 UTC
List: ruby-dev #18426
なかだです。

At Wed, 2 Oct 2002 10:13:07 +0900,
WATANABE Tetsuya wrote:
> HP-UX で動作の確認しました。OK でした。しばらく
> このパッチを入れたもので使ってみます。

[ruby-dev:18397]がSolarisで失敗したのも[ruby-dev:18420]がダメだっ
たのもEOFを別扱いにしようとしたのが原因といえるので、R/Wに関し
ては[ruby-dev:18345]をベースにしたほうがよさそうなのと、ftell()
を忘れてたので作り直しました。


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	2 Oct 2002 01:28:43 -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,48 @@ else
 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"
Index: io.c
===================================================================
RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.161
diff -u -2 -p -r1.161 io.c
--- io.c	30 Sep 2002 11:31:28 -0000	1.161
+++ io.c	2 Oct 2002 02:51:44 -0000
@@ -183,4 +183,27 @@ 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)
@@ -190,4 +213,10 @@ 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);
+    }
+    fptr->mode |= FMODE_RBUF;
+#endif
 }
 
@@ -199,4 +228,9 @@ 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);
+    }
+#endif
 }
 
@@ -378,5 +412,5 @@ rb_io_tell(io)
 
     GetOpenFile(io, fptr);
-    pos = ftello(fptr->f);
+    pos = io_tell(fptr);
     if (ferror(fptr->f)) rb_sys_fail(fptr->path);
     return OFFT2NUM(pos);
@@ -398,5 +432,5 @@ rb_io_seek(io, offset, whence)
 
     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);
@@ -429,5 +463,5 @@ rb_io_set_pos(io, offset)
 
     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);
@@ -443,5 +477,5 @@ rb_io_rewind(io)
 
     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) {
@@ -678,5 +712,5 @@ remain_size(fptr)
 	)
     {
-	pos = ftello(fptr->f);
+	pos = io_tell(fptr);
 	if (st.st_size > pos && pos >= 0) {
 	    siz = st.st_size - pos + 1;
@@ -703,5 +737,5 @@ read_all(fptr, siz)
     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);
@@ -2199,5 +2233,5 @@ 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) {
@@ -2233,6 +2267,6 @@ io_reopen(io, nfile)
     }
     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);
     }
 
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はできる。
    中田 伸悦

In This Thread