In article <01ed01c67309$01656540$6442a8c0@musicbox>,
  "Bill Kelly" <billk / cts.com> writes:

> No; the only exception I ever saw raised was EOFError from the
> readpartial.
>
> I included the EAGAIN handling because the code in
> lib/openssl/buffering.rb is written that way.  But, I was never
> sure it should be necessary, from what I'd seen in the io.c,
> win32/win32.c, and ext/socket/socket.c source.

I modified the document of readpartial.
I hope it makes the behaviour clear.

Index: io.c
===================================================================
RCS file: /src/ruby/io.c,v
retrieving revision 1.401
diff -u -p -r1.401 io.c
--- io.c        28 Mar 2006 01:50:11 -0000      1.401
+++ io.c        9 May 2006 02:10:04 -0000
@@ -1337,7 +1337,7 @@ io_getpartial(int argc, VALUE *argv, VAL
  *     r.readpartial(4096)      #=> "ghi\n"     ""              ""
  *
  *  Note that readpartial is nonblocking-flag insensitive.
- *  It blocks even if the nonblocking-flag is set.
+ *  It blocks on the situation IO#sysread causes Errno::EAGAIN.
  *
  *  Also note that readpartial behaves similar to sysread in blocking mode.
  *  The behavior is identical when the buffer is empty.

> From casually perusing the source, it appears to me as though
> EAGAIN/EWOULDBLOCK are being handled internally; so I'm unclear
> on why/when one would expect to need to handle them from ruby.
>
> (And, as yet, I've not seen an EAGAIN from readpartial or
> syswrite in my tests on either Linux or Windows... not that my
> tests have been by any means exhaustive... :)

IO#syswrite causes EAGAIN.

% ./ruby -rfcntl -ve '
r, w = IO.pipe
w.fcntl(Fcntl::F_SETFL, File::NONBLOCK|w.fcntl(Fcntl::F_GETFL))
p w.syswrite("a" * 70000)
p w.syswrite("a" * 70000)
'
ruby 1.9.0 (2006-05-01) [i686-linux]
65536
-e:5:in `IO#syswrite': Resource temporarily unavailable (Errno::EAGAIN)
        from -e:5

It is also possible on sockets.

% ./ruby -rsocket -rfcntl -ve '
a = TCPServer.new 20000
r = TCPSocket.new "localhost", 20000
w = a.accept
w.fcntl(Fcntl::F_SETFL, File::NONBLOCK|w.fcntl(Fcntl::F_GETFL))
p w.syswrite("a" * 70000)
p w.syswrite("a" * 70000)
p w.syswrite("a" * 70000)
p w.syswrite("a" * 70000)
p w.syswrite("a" * 70000)
'
ruby 1.9.0 (2006-05-01) [i686-linux]
65536
16384
-e:8:in `IO#syswrite': Resource temporarily unavailable (Errno::EAGAIN)
        from -e:8

The condition is
1. IO#syswrite
2. pipe/socket (kernel) buffer is full
3. Ruby has only one thread (No I/O multiplexing using select)
-- 
Tanaka Akira