[#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:18463] EWOULDBLOCK at IO#close/IO#flush

From: nobu.nakada@...
Date: 2002-10-08 23:06:05 UTC
List: ruby-dev #18463
なかだです。

Non-blockingモードで、IO#closeやIO#flushでEWOULDBLOCKが発生しま
す。

$ cat io/nonblock.rb
require "fcntl"
class IO
  def nonblock(nb)
    (fcntl(Fcntl::F_GETFL) & File::NONBLOCK) != 0
  end
  def nonblock=(nb)
    f = fcntl(Fcntl::F_GETFL)
    if nb
      f |= File::NONBLOCK
    else
      f &= ~File::NONBLOCK
    end
    fcntl(Fcntl::F_SETFL, f)
  end
end

$ cat t.rb
require 'io/nonblock'
STDOUT.nonblock = true
STDOUT.write("0123456789abcdef"*384)
STDOUT.flush
# STDOUT.close

$ ruby t.rb | sleep 1
t.rb:5:in `flush': Resource temporarily unavailable (Errno::EWOULDBLOCK)
        from t.rb:5

書き込み系だけで充分な気がするのですが、どうでしょうか。

あと、IO#writeの戻り値がおかしくなってます。すいません。


Index: io.c
===================================================================
RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.164
diff -u -2 -p -r1.164 io.c
--- io.c	8 Oct 2002 05:34:45 -0000	1.164
+++ io.c	8 Oct 2002 22:33:47 -0000
@@ -278,8 +278,12 @@ io_fflush(f, fptr)
 
     rb_thread_fd_writable(fileno(f));
-    TRAP_BEG;
-    n = fflush(f);
-    TRAP_END;
-    if (n == EOF) rb_sys_fail(fptr->path);
+    for (;;) {
+	TRAP_BEG;
+	n = fflush(f);
+	TRAP_END;
+	if (n != EOF) break;
+	if (!rb_io_wait_writable(fileno(f)))
+	    rb_sys_fail(fptr->path);
+    }
     fptr->mode &= ~FMODE_WBUF;
 }
@@ -375,5 +379,5 @@ io_write(io, str)
     } while (--n > 0);
 #else
-    for (; (r = fwrite(ptr, 1, n, f)) < n; ptr += r, n -= r) {
+    while (ptr += (r = fwrite(ptr, 1, n, f)), (n -= r) > 0) {
 	if (ferror(f)) {
 	    if (rb_io_wait_writable(fileno(f))) {
@@ -1278,11 +1282,18 @@ fptr_finalize(fptr, fin)
     if (fptr->f2) {
 	f2 = fileno(fptr->f2);
-	n2 = fclose(fptr->f2);
+	while ((n2 = fclose(fptr->f2)) < 0) {
+	    if (!rb_io_wait_writable(f2)) {
+		e = errno;
+		break;
+	    }
+	}
 	fptr->f2 = 0;
-	if (n2 < 0) e = errno;
     }
     if (fptr->f) {
 	f1 = fileno(fptr->f);
-	n1 = fclose(fptr->f);
+	while ((n1 = fclose(fptr->f)) < 0) {
+	    if (f2 != -1 || !(fptr->mode & FMODE_WBUF)) break;
+	    if (!rb_io_wait_writable(f1)) break;
+	}
 	fptr->f = 0;
 	if (n1 < 0 && errno == EBADF) {


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next