Index: src/org/jruby/RubyIO.java
===================================================================
RCS file: /var/cvs/jruby/jruby/src/org/jruby/RubyIO.java,v
retrieving revision 1.54
diff -r1.54 RubyIO.java
20c20
<  * Copyright (C) 2006 Evan Buswell <evan@heron.sytes.net>
---
>  * Copyright (C) 2006 Evan Buswell <ebuswell@gmail.com>
43d42
< import java.nio.channels.SelectableChannel;
810a810,816
>     public boolean getBlocking() {
> 	if(!(handler instanceof IOHandlerNio)) {
> 	    return true;
> 	}
> 	return ((IOHandlerNio) handler).getBlocking();
>     }
> 
829,837c835,846
<             
<             Channel channel = getChannel();
<             if (channel != null && channel instanceof SelectableChannel) {
<                 try {
<                     ((SelectableChannel)channel).configureBlocking(block);
<                 } catch (IOException e) {
<                     throw getRuntime().newIOError(e.getMessage());
<                 }
<             }         
---
> 
> 	    if(!(handler instanceof IOHandlerNio)) {
> 		// cryptic for the uninitiated...
> 		throw getRuntime().newNotImplementedError("FCNTL only works with Nio based handlers");
> 	    }
> 	
> 	    try {
> 		((IOHandlerNio) handler).setBlocking(block);
>             } catch (IOException e) {
> 		throw getRuntime().newIOError(e.getMessage());
> 	    }
> 
Index: src/org/jruby/runtime/builtin/meta/IOMetaClass.java
===================================================================
RCS file: /var/cvs/jruby/jruby/src/org/jruby/runtime/builtin/meta/IOMetaClass.java,v
retrieving revision 1.19
diff -r1.19 IOMetaClass.java
18c18
<  * Copyright (C) 2006 Evan Buswell <evan@heron.sytes.net>
---
>  * Copyright (C) 2006 Evan Buswell <ebuswell@gmail.com>
279,280c279
<             // make all sockets blocking again
<             List toReset = new ArrayList();
---
>             // make all sockets blocking as configured again
283c282,287
<                 toReset.add(key.channel());
---
> 		SelectableChannel channel = key.channel();
> 		synchronized(channel.blockingLock()) {
> 		    boolean blocking = ((RubyIO) key.attachment()).getBlocking();
> 		    key.cancel();
> 		    channel.configureBlocking(blocking);
> 		}
286,289d289
<             for (Iterator i = toReset.iterator(); i.hasNext(); ) {
<                 SelectableChannel channel = (SelectableChannel) i.next();
<                 channel.configureBlocking(true);
<             }
Index: src/org/jruby/util/IOHandlerNio.java
===================================================================
RCS file: /var/cvs/jruby/jruby/src/org/jruby/util/IOHandlerNio.java,v
retrieving revision 1.3
diff -r1.3 IOHandlerNio.java
14c14
<  * Copyright (C) 2006 Evan Buswell <evan@heron.sytes.net>
---
>  * Copyright (C) 2006 Evan Buswell <ebuswell@gmail.com>
38a39
> import java.nio.channels.SelectableChannel;
40c41
< import java.nio.channels.spi.AbstractSelectableChannel;
---
> import java.nio.channels.IllegalBlockingModeException;
53a55
>     private boolean blocking = true;
67,69d68
<         if (channel instanceof AbstractSelectableChannel) {
<             ((AbstractSelectableChannel)channel).configureBlocking(false);
<         }
101a101,117
>     public void setBlocking(boolean block) throws IOException {
> 	if(!(channel instanceof SelectableChannel))
> 	    return;
> 	synchronized(((SelectableChannel) channel).blockingLock()) {
> 	    blocking = block;
> 	    try {
> 		((SelectableChannel) channel).configureBlocking(block);
> 	    } catch(IllegalBlockingModeException e) {
> 		// ignore this; select() will set the correct mode when it is finished
> 	    }
> 	}
>     }
> 
>     public boolean getBlocking() {
> 	return blocking;
>     }
> 
109,123c125,131
<         boolean eof = false;
<         while (buffer.hasRemaining()) {
<         	int bytesRead = ((ReadableByteChannel) channel).read(buffer);
<         	if (bytesRead < 0) {
<                 eof = true;
<                 break;
<             }
<         	if (bytesRead == 0) {
<         	    // only should happen for nonblocking IO...break and allow the next call to try again
<         	    break;
<         	}
<         }
<         if (buffer.position() == 0 && eof == true) {
<             throw new EOFException();
<         }
---
> 	int bytes_read = 0;
> 	do {
> 	    bytes_read = ((ReadableByteChannel) channel).read(buffer);
> 	    if (bytes_read < 0) {
> 		throw new EOFException();
> 	    }
> 	} while(blocking && (bytes_read == 0));
151,166c159
<         checkReadable();
<         checkBuffered();
< 	
<         ByteBuffer buffer = ByteBuffer.allocate(length);
<         if (((ReadableByteChannel) channel).read(buffer) < 0) {
<             throw new EOFException();
<         }
<         byte[] ret;
<         if (buffer.hasRemaining()) {
<             buffer.flip();
<             ret = new byte[buffer.remaining()];
<             buffer.get(ret);
<         } else {
<             ret = buffer.array();
<         }
<         return RubyString.bytesToString(ret);
---
> 	return sysread(length);
