Index: test/test_io.rb
===================================================================
--- test/test_io.rb	(revision 4779)
+++ test/test_io.rb	(working copy)
@@ -184,6 +184,36 @@
     f.close
   end
 
+  def test_open
+    ensure_files @file
+
+    assert_raises(ArgumentError) { io = IO.open }
+
+    f = File.open(@file)
+    assert_raises(ArgumentError) { io = IO.open(f.fileno, "r", :gratuitous) }
+    io = IO.open(f.fileno, "r")
+    assert_equal(f.fileno, io.fileno)
+    assert(!io.closed?)
+    io.close
+    assert(io.closed?)
+
+    assert(!f.closed?)
+    assert_raises(Errno::EBADF) { f.close }
+  end
+
+  def test_open_with_block
+    ensure_files @file
+
+    f = File.open(@file)
+    IO.open(f.fileno, "r") do |io|
+      assert_equal(f.fileno, io.fileno)
+      assert(!io.closed?)
+    end
+
+    assert(!f.closed?)
+    assert_raises(Errno::EBADF) { f.close }
+  end
+
   def test_delete
     ensure_files @file, @file2, @file3
     # Test deleting files
Index: src/org/jruby/RubyIO.java
===================================================================
--- src/org/jruby/RubyIO.java	(revision 4779)
+++ src/org/jruby/RubyIO.java	(working copy)
@@ -543,6 +543,23 @@
         return this;
     }
 
+    @JRubyMethod(name = "open", required = 1, optional = 1, frame = true, meta = true)
+    public static IRubyObject open(IRubyObject recv, IRubyObject[] args, Block block) {
+        Ruby runtime = recv.getRuntime();
+        RubyIO io = new RubyIO(runtime, (RubyClass) recv);
+        io.initialize(args, block);
+
+        if (block.isGiven()) {
+            try {
+                return block.yield(runtime.getCurrentContext(), io);
+            } finally {
+                io.close();
+            }
+        }
+
+        return io;
+    }
+
     // This appears to be some windows-only mode.  On a java platform this is a no-op
     @JRubyMethod(name = "binmode")
     public IRubyObject binmode() {

