about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-05-12 19:13:57 -0700
committerEric Wong <normalperson@yhbt.net>2011-05-12 19:13:57 -0700
commit1ec67bc61d534232b5eec5c3f32da362898c6508 (patch)
tree8a3ab33bfb07806b0744db56bb45457e90dc6717
parent83bdc390d98e9af4439c6db92679a9a84eb9f52a (diff)
downloadruby_io_splice-1ec67bc61d534232b5eec5c3f32da362898c6508.tar.gz
This way at least 1.8 users can have something akin to
IO.copy_stream.
-rw-r--r--lib/io/splice.rb4
-rw-r--r--lib/io/splice/mri_18.rb34
2 files changed, 38 insertions, 0 deletions
diff --git a/lib/io/splice.rb b/lib/io/splice.rb
index 54a3f04..574e681 100644
--- a/lib/io/splice.rb
+++ b/lib/io/splice.rb
@@ -101,3 +101,7 @@ module IO::Splice
       rv
   end
 end
+if (! defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") &&
+   RUBY_VERSION.to_f <= 1.8
+  require "io/splice/mri_18"
+end
diff --git a/lib/io/splice/mri_18.rb b/lib/io/splice/mri_18.rb
new file mode 100644
index 0000000..ad20152
--- /dev/null
+++ b/lib/io/splice/mri_18.rb
@@ -0,0 +1,34 @@
+# :enddoc:
+require "io/nonblock"
+module IO::Splice
+  class << self
+    remove_method :full
+    remove_method :partial
+  end
+  def self.full(src, dst, len, src_offset)
+    dst.to_io.nonblock = src.to_io.nonblock = true
+    spliced = 0
+    case n = IO.trysplice(src, src_offset, dst, nil, len, IO::Splice::F_MOVE)
+    when :EAGAIN
+      src.to_io.wait
+      IO.select(nil, [dst])
+    when Integer
+      spliced += n
+      len -= n
+      src_offset += n if src_offset
+    when nil
+      break
+    end while len > 0
+    spliced
+  end
+
+  def self.partial(src, dst, len, src_offset)
+    dst.to_io.nonblock = src.to_io.nonblock = true
+    begin
+      src.to_io.wait
+      IO.select(nil, [dst])
+      rv = IO.trysplice(src, src_offset, dst, nil, len, IO::Splice::F_MOVE)
+    end while rv == :EAGAIN
+    rv
+  end
+end