about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2017-01-02 03:59:07 +0000
committerEric Wong <e@80x24.org>2017-01-04 21:17:30 +0000
commitd7bcfb1aed85dbd2ec96ba37e0c66f47b38300d6 (patch)
treec5a3f007480cc9263a0ffcf333af97b30c140798
parent15230756d31d404881fea1edbbe4bd7378066163 (diff)
downloadsleepy_penguin-d7bcfb1aed85dbd2ec96ba37e0c66f47b38300d6.tar.gz
Since we're breaking away from the old io_splice gem,
we have liberty to change the API when moving to a new
namespace.  This might allow us to simplify the common
case args and reduce the amount of C code we maintain.
-rw-r--r--ext/sleepy_penguin/splice.c207
-rw-r--r--lib/sleepy_penguin.rb4
-rw-r--r--lib/sleepy_penguin/splice.rb121
-rw-r--r--test/test_splice.rb57
-rw-r--r--test/test_splice_eintr.rb2
5 files changed, 179 insertions, 212 deletions
diff --git a/ext/sleepy_penguin/splice.c b/ext/sleepy_penguin/splice.c
index 4ce2557..59ddac7 100644
--- a/ext/sleepy_penguin/splice.c
+++ b/ext/sleepy_penguin/splice.c
@@ -35,117 +35,34 @@ static void *nogvl_splice(void *ptr)
                              a->len, a->flags);
 }
 
-static ssize_t do_splice(int argc, VALUE *argv, unsigned dflags)
+/* :nodoc: */
+static VALUE my_splice(VALUE mod, VALUE io_in, VALUE off_in,
+                        VALUE io_out, VALUE off_out,
+                        VALUE len, VALUE flags)
 {
         off_t i = 0, o = 0;
-        VALUE io_in, off_in, io_out, off_out, len, flags;
         struct copy_args a;
         ssize_t bytes;
-        ssize_t total = 0;
-
-        rb_scan_args(argc, argv, "51",
-                     &io_in, &off_in, &io_out, &off_out, &len, &flags);
 
         a.off_in = NIL_P(off_in) ? NULL : (i = NUM2OFFT(off_in), &i);
         a.off_out = NIL_P(off_out) ? NULL : (o = NUM2OFFT(off_out), &o);
         a.len = NUM2SIZET(len);
-        a.flags = NIL_P(flags) ? dflags : NUM2UINT(flags) | dflags;
+        a.flags = NUM2UINT(flags);
 
         for (;;) {
                 a.fd_in = check_fileno(io_in);
                 a.fd_out = check_fileno(io_out);
                 bytes = (ssize_t)IO_RUN(nogvl_splice, &a);
+                if (bytes == 0) return Qnil;
                 if (bytes < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        if (total > 0)
-                                return total;
-                        return bytes;
-                } else if (bytes == 0) {
-                        break;
-                } else {
-                        return bytes;
+                        switch (errno) {
+                        case EINTR: continue;
+                        case EAGAIN: return sym_EAGAIN;
+                        default: rb_sys_fail("splice");
+                        }
                 }
+                return SSIZET2NUM(bytes);
         }
-
-        return total;
-}
-
-/*
- * call-seq:
- *    SleepyPenguin.splice(io_in, off_in, io_out, off_out, len) => integer
- *    SleepyPenguin.splice(io_in, off_in, io_out, off_out, len, flags) => integer
- *
- * Splice +len+ bytes from/to a pipe.  Either +io_in+ or +io_out+
- * MUST be a pipe.  +io_in+ and +io_out+ may BOTH be pipes as of
- * Linux 2.6.31 or later.
- *
- * +off_in+ and +off_out+ if non-nil may be used to
- * specify an offset for the non-pipe file descriptor.
- *
- * +flags+ defaults to zero if unspecified.
- * +flags+ may be a bitmask of the following flags:
- *
- * * SleepyPenguin::F_MOVE
- * * SleepyPenguin::F_NONBLOCK
- * * SleepyPenguin::F_MORE
- *
- * Returns the number of bytes spliced.
- * Raises EOFError when +io_in+ has reached end of file.
- * Raises Errno::EAGAIN if the SleepyPenguin::F_NONBLOCK flag is set
- * and the pipe has no data to read from or space to write to.  May
- * also raise Errno::EAGAIN if the non-pipe descriptor has no data
- * to read from or space to write to.
- *
- * As splice never exposes buffers to userspace, it will not take
- * into account userspace buffering done by Ruby or stdio.  It is
- * also not subject to encoding/decoding filters under Ruby 1.9.
- *
- * Consider using SleepyPenguin.trysplice if +io_out+ is a pipe or if you are using
- * non-blocking I/O on both descriptors as it avoids the cost of raising
- * common Errno::EAGAIN exceptions.
- *
- * See manpage for full documentation:
- * http://kernel.org/doc/man-pages/online/pages/man2/splice.2.html
- */
-static VALUE my_splice(int argc, VALUE *argv, VALUE self)
-{
-        ssize_t n = do_splice(argc, argv, 0);
-
-        if (n == 0)
-                rb_eof_error();
-        if (n < 0)
-                rb_sys_fail("splice");
-        return SSIZET2NUM(n);
-}
-
-/*
- * call-seq:
- *    SleepyPenguin.trysplice(io_in, off_in, io_out, off_out, len) => integer
- *    SleepyPenguin.trysplice(io_in, off_in, io_out, off_out, len, flags) => integer
- *
- * Exactly like SleepyPenguin.splice, except +:EAGAIN+ is returned when either
- * the read or write end would block instead of raising Errno::EAGAIN.
- *
- * SleepyPenguin::F_NONBLOCK is always passed for the pipe descriptor,
- * but this can still block if the non-pipe descriptor is blocking.
- *
- * See SleepyPenguin.splice documentation for more details.
- *
- * This method is recommended whenever +io_out+ is a pipe.
- */
-static VALUE trysplice(int argc, VALUE *argv, VALUE self)
-{
-        ssize_t n = do_splice(argc, argv, SPLICE_F_NONBLOCK);
-
-        if (n == 0)
-                return Qnil;
-        if (n < 0) {
-                if (errno == EAGAIN)
-                        return sym_EAGAIN;
-                rb_sys_fail("splice");
-        }
-        return SSIZET2NUM(n);
 }
 
 struct tee_args {
@@ -163,111 +80,37 @@ static void *nogvl_tee(void *ptr)
         return (void *)tee(a->fd_in, a->fd_out, a->len, a->flags);
 }
 
-static ssize_t do_tee(int argc, VALUE *argv, unsigned dflags)
+/* :nodoc: */
+static VALUE my_tee(VALUE mod, VALUE io_in, VALUE io_out,
+                        VALUE len, VALUE flags)
 {
-        VALUE io_in, io_out, len, flags;
         struct tee_args a;
         ssize_t bytes;
-        ssize_t total = 0;
 
-        rb_scan_args(argc, argv, "31", &io_in, &io_out, &len, &flags);
         a.len = (size_t)NUM2SIZET(len);
-        a.flags = NIL_P(flags) ? dflags : NUM2UINT(flags) | dflags;
+        a.flags = NUM2UINT(flags);
 
         for (;;) {
                 a.fd_in = check_fileno(io_in);
                 a.fd_out = check_fileno(io_out);
                 bytes = (ssize_t)IO_RUN(nogvl_tee, &a);
+                if (bytes == 0) return Qnil;
                 if (bytes < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        if (total > 0)
-                                return total;
-                        return bytes;
-                } else if (bytes == 0) {
-                        break;
-                } else {
-                        return bytes;
+                        switch (errno) {
+                        case EINTR: continue;
+                        case EAGAIN: return sym_EAGAIN;
+                        default: rb_sys_fail("tee");
+                        }
                 }
+                return SSIZET2NUM(bytes);
         }
-
-        return total;
-}
-
-/*
- * call-seq:
- *   SleepyPenguin.tee(io_in, io_out, len) => integer
- *   SleepyPenguin.tee(io_in, io_out, len, flags) => integer
- *
- * Copies up to +len+ bytes of data from +io_in+ to +io_out+.  +io_in+
- * and +io_out+ must both refer to pipe descriptors.  +io_in+ and +io_out+
- * may not be endpoints of the same pipe.
- *
- * +flags+ may be zero (the default) or a combination of:
- * * SleepyPenguin::F_NONBLOCK
- *
- * Other splice-related flags are currently unimplemented in the
- * kernel and have no effect.
- *
- * Returns the number of bytes duplicated if successful.
- * Raises EOFError when +io_in+ is closed and emptied.
- * Raises Errno::EAGAIN when +io_in+ is empty and/or +io_out+ is full
- * and +flags+ contains SleepyPenguin::F_NONBLOCK
- *
- * Consider using SleepyPenguin.trytee if you are using
- * SleepyPenguin::F_NONBLOCK as it avoids the cost of raising
- * common Errno::EAGAIN exceptions.
- *
- * See manpage for full documentation:
- * http://kernel.org/doc/man-pages/online/pages/man2/tee.2.html
- */
-static VALUE my_tee(int argc, VALUE *argv, VALUE self)
-{
-        ssize_t n = do_tee(argc, argv, 0);
-
-        if (n == 0)
-                rb_eof_error();
-        if (n < 0)
-                rb_sys_fail("tee");
-
-        return SSIZET2NUM(n);
-}
-
-/*
- * call-seq:
- *    SleepyPenguin.trytee(io_in, io_out, len) => integer
- *    SleepyPenguin.trytee(io_in, io_out, len, flags) => integer
- *
- * Exactly like SleepyPenguin.tee, except +:EAGAIN+ is returned when either
- * the read or write end would block instead of raising Errno::EAGAIN.
- *
- * SleepyPenguin::F_NONBLOCK is always passed for the pipe descriptor,
- * but this can still block if the non-pipe descriptor is blocking.
- *
- * See SleepyPenguin.tee documentation for more details.
- */
-static VALUE trytee(int argc, VALUE *argv, VALUE self)
-{
-        ssize_t n = do_tee(argc, argv, SPLICE_F_NONBLOCK);
-
-        if (n == 0)
-                return Qnil;
-        if (n < 0) {
-                if (errno == EAGAIN)
-                        return sym_EAGAIN;
-                rb_sys_fail("tee");
-        }
-
-        return SSIZET2NUM(n);
 }
 
 void sleepy_penguin_init_splice(void)
 {
         VALUE mod = rb_define_module("SleepyPenguin");
-        rb_define_singleton_method(mod, "splice", my_splice, -1);
-        rb_define_singleton_method(mod, "trysplice", trysplice, -1);
-        rb_define_singleton_method(mod, "tee", my_tee, -1);
-        rb_define_singleton_method(mod, "trytee", trytee, -1);
+        rb_define_singleton_method(mod, "__splice", my_splice, 6);
+        rb_define_singleton_method(mod, "__tee", my_tee, 4);
 
         /*
          * Attempt to move pages instead of copying.  This is only a hint
diff --git a/lib/sleepy_penguin.rb b/lib/sleepy_penguin.rb
index 808c94a..63f293d 100644
--- a/lib/sleepy_penguin.rb
+++ b/lib/sleepy_penguin.rb
@@ -15,3 +15,7 @@ if defined?(SleepyPenguin::Inotify) &&
     # :startdoc
   end
 end
+
+if SleepyPenguin.respond_to?(:__splice) || SleepyPenguin.respond_to?(:__tee)
+  require_relative 'sleepy_penguin/splice'
+end
diff --git a/lib/sleepy_penguin/splice.rb b/lib/sleepy_penguin/splice.rb
new file mode 100644
index 0000000..5358ed5
--- /dev/null
+++ b/lib/sleepy_penguin/splice.rb
@@ -0,0 +1,121 @@
+# -*- encoding: binary -*-
+
+module SleepyPenguin
+  # call-seq:
+  #    SleepyPenguin.splice(io_in, io_out, len[, flags [, keywords]) => Integer
+  #
+  # Splice +len+ bytes from/to a pipe.  Either +io_in+ or +io_out+
+  # MUST be a pipe.  +io_in+ and +io_out+ may BOTH be pipes as of
+  # Linux 2.6.31 or later.
+  #
+  # +flags+ defaults to zero if unspecified.
+  # It may be an Integer bitmask, a Symbol, or Array of Symbols
+  #
+  # The integer bitmask may any combination of:
+  #
+  # * SleepyPenguin::F_MOVE - attempt to move pages instead of copying
+  #
+  # * SleepyPenguin::F_NONBLOCK - do not block on pipe I/O (only)
+  #
+  # * SleepyPenguin::F_MORE - indicates more data will be sent soon
+  #
+  # Symbols may be used as well to specify a single flag:
+  #
+  # * :move        - corresponds to F_MOVE
+  # * :nonblock    - corresponds to F_NONBLOCK
+  # * :more        - corresponds to F_MORE
+  #
+  # Or, an array of any combination of the above symbols.
+  #
+  # Keywords:
+  #
+  # :off_in and :off_out if non-nil may be used to
+  #  specify an offset for the respective non-pipe file descriptor.
+  #
+  # :exception defaults to +true+.  Setting it to +false+
+  # will return :EAGAIN symbol instead of raising Errno::EAGAIN.
+  # This will also return +nil+ instead of raising EOFError
+  # when +io_in+ is at the end.
+  #
+  # Raises EOFError when +io_in+ has reached end of file.
+  # Raises Errno::EAGAIN if the SleepyPenguin::F_NONBLOCK flag is set
+  # and the pipe has no data to read from or space to write to.  May
+  # also raise Errno::EAGAIN if the non-pipe descriptor has no data
+  # to read from or space to write to.
+  #
+  # As splice never exposes buffers to userspace, it will not take
+  # into account userspace buffering done by Ruby or stdio.  It is
+  # also not subject to encoding/decoding filters under Ruby 1.9+.
+  #
+  # Consider using `exception: false` if +io_out+ is a pipe or if you
+  # are using non-blocking I/O on both descriptors as it avoids the
+  # cost of raising common Errno::EAGAIN exceptions.
+  #
+  # See manpage for full documentation:
+  # http://man7.org/linux/man-pages/man2/splice.2.html
+  def self.splice(io_in, io_out, len, flags = 0,
+                  off_in: nil, off_out: nil, exception: true)
+    flags = __map_splice_flags(flags)
+    ret = __splice(io_in, off_in, io_out, off_out, len, flags)
+    exception ? __map_exc(ret) : ret
+  end
+
+  # call-seq:
+  #   SleepyPenguin.tee(io_in, io_out, len[, flags[, keywords]) => Integer
+  #
+  # Copies up to +len+ bytes of data from +io_in+ to +io_out+.  +io_in+
+  # and +io_out+ must both refer to pipe descriptors.  +io_in+ and +io_out+
+  # may not be endpoints of the same pipe.
+  #
+  # +flags+ may be zero (the default) or a combination of:
+  # * SleepyPenguin::F_NONBLOCK
+  #
+  # As a shortcut, the `:nonblock` symbol may be used instead.
+  #
+  # Other splice-related flags are currently unimplemented in the
+  # kernel and have no effect.
+  #
+  # Returns the number of bytes duplicated if successful.
+  # Raises EOFError when +io_in+ is closed and emptied.
+  # Raises Errno::EAGAIN when +io_in+ is empty and/or +io_out+ is full
+  # and +flags+ specifies non-blocking operation
+  #
+  # Keywords:
+  #
+  # :exception defaults to +true+.  Setting it to +false+
+  # will return :EAGAIN symbol instead of raising Errno::EAGAIN.
+  # This will also return +nil+ instead of raising EOFError
+  # when +io_in+ is at the end.
+  #
+  # Consider using `exception: false` if +io_out+ is a pipe or if you
+  # are using non-blocking I/O on both descriptors as it avoids the
+  # cost of raising common Errno::EAGAIN exceptions.
+  #
+  # See manpage for full documentation:
+  # http://man7.org/linux/man-pages/man2/tee.2.html
+  def self.tee(io_in, io_out, len, flags = 0, exception: true)
+    flags = __map_splice_flags(flags)
+    ret = __tee(io_in, io_out, len, flags)
+    exception ? __map_exc(ret) : ret
+  end if respond_to?(:__tee)
+
+  @__splice_f_map = { # :nodoc:
+    :nonblock => F_NONBLOCK,
+    :more => F_MORE,
+    :move => F_MOVE
+  }
+
+  def self.__map_splice_flags(flags) # :nodoc:
+    onef = @__splice_f_map[flags] and return onef
+    flags.respond_to?(:inject) ?
+        flags.inject(0) { |fl, sym| fl |= @__splice_f_map[sym] } : flags
+  end
+
+  def self.__map_exc(ret) # :nodoc:
+    case ret
+    when :EAGAIN then raise Errno::EAGAIN, 'Resource temporarily unavailable'
+    when nil then raise EOFError, 'end of file reached'
+    end
+    ret
+  end
+end
diff --git a/test/test_splice.rb b/test/test_splice.rb
index 475ba8b..71e0117 100644
--- a/test/test_splice.rb
+++ b/test/test_splice.rb
@@ -18,7 +18,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.splice(tmp.fileno, nil, wr.fileno, nil, size, 0)
+    nr = SleepyPenguin.splice(tmp.fileno, wr.fileno, size)
     assert_equal size, nr
     assert_equal str, rd.sysread(size)
   end
@@ -32,7 +32,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.splice(tmp, nil, wr, nil, size, 0)
+    nr = SleepyPenguin.splice(tmp, wr, size)
     assert_equal size, nr
     assert_equal str, rd.sysread(size)
   end
@@ -46,7 +46,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.splice(tmp, nil, wr, nil, size)
+    nr = SleepyPenguin.splice(tmp, wr, size)
     assert_equal size, nr
     assert_equal str, rd.sysread(size)
   end
@@ -60,7 +60,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.trysplice(tmp, nil, wr, nil, size)
+    nr = SleepyPenguin.splice(tmp, wr, size, :nonblock, exception: false)
     assert_equal size, nr
     assert_equal str, rd.sysread(size)
   end
@@ -78,7 +78,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.splice(io_ish, nil, wr, nil, size, 0)
+    nr = SleepyPenguin.splice(io_ish, wr, size)
     assert_equal size, nr
     assert_equal str, rd.sysread(size)
   end
@@ -93,7 +93,7 @@ class TestSplice < Test::Unit::TestCase
     assert_equal 5, tmp.syswrite(str)
     tmp.sysseek(0)
 
-    nr = SleepyPenguin.splice(tmp.fileno, off, wr.fileno, nil, len, 0)
+    nr = SleepyPenguin.splice(tmp.fileno, wr.fileno, len, off_in: off)
     assert_equal len, nr
     assert_equal 'de', rd.sysread(len)
   end
@@ -104,7 +104,7 @@ class TestSplice < Test::Unit::TestCase
     tmp = Tempfile.new('ruby_splice')
 
     assert_equal 5, wr.syswrite(str)
-    nr = SleepyPenguin.splice(rd.fileno, nil, tmp.fileno, 3, str.size, 0)
+    nr = SleepyPenguin.splice(rd.fileno, tmp.fileno, str.size, off_out: 3)
     assert_equal 5, nr
     tmp.sysseek(0)
     assert_equal "\0\0\0abcde", tmp.sysread(9)
@@ -115,25 +115,25 @@ class TestSplice < Test::Unit::TestCase
     tmp = Tempfile.new('ruby_splice')
 
     assert_raises(Errno::EAGAIN) {
-      SleepyPenguin.splice(rd.fileno, nil, tmp.fileno, 0, 5,
-                           SleepyPenguin::F_NONBLOCK)
+      SleepyPenguin.splice(rd.fileno, tmp.fileno, 5, :nonblock, off_out: 0)
     }
   end
 
   def test_trysplice_nonblock
     rd, wr = IO.pipe
     tmp = Tempfile.new('ruby_splice')
-    assert_equal :EAGAIN,
-           SleepyPenguin.trysplice(rd, nil, tmp, 0, 5,
-                                   SleepyPenguin::F_NONBLOCK)
+    assert_equal :EAGAIN, SleepyPenguin.splice(rd, tmp, 5, :nonblock,
+                                               off_out: 0, exception: false)
   end
 
   def test_trysplice_nonblock_noargs
     rd, wr = IO.pipe
     tmp = Tempfile.new('ruby_splice')
-    assert_equal :EAGAIN, SleepyPenguin.trysplice(rd, nil, tmp, 0, 5)
-    assert_equal :EAGAIN, SleepyPenguin.trysplice(rd, nil, tmp, 0, 5,
-                                                  SleepyPenguin::F_MORE)
+    assert_equal :EAGAIN, SleepyPenguin.splice(rd, tmp, 5, :nonblock,
+                                               off_out: 0, exception: false)
+    assert_equal :EAGAIN, SleepyPenguin.splice(rd, tmp, 5, [:more,:nonblock],
+                                               off_out: 0,
+                                               exception: false)
   end
 
   def test_splice_eof
@@ -142,12 +142,10 @@ class TestSplice < Test::Unit::TestCase
     wr.syswrite 'abc'
     wr.close
 
-    nr = SleepyPenguin.splice(rd.fileno, nil, tmp.fileno, 0, 5,
-                              SleepyPenguin::F_NONBLOCK)
+    nr = SleepyPenguin.splice(rd.fileno, tmp.fileno, 5, :nonblock, off_out: 0)
     assert_equal 3, nr
     assert_raises(EOFError) {
-      SleepyPenguin.splice(rd.fileno, nil, tmp.fileno, 0, 5,
-                           SleepyPenguin::F_NONBLOCK)
+      SleepyPenguin.splice(rd.fileno, tmp.fileno, 5, :nonblock, off_out: 0)
     }
   end
 
@@ -157,10 +155,10 @@ class TestSplice < Test::Unit::TestCase
     wr.syswrite 'abc'
     wr.close
 
-    nr = SleepyPenguin.trysplice(rd, nil, tmp, 0, 5, SleepyPenguin::F_NONBLOCK)
+    nr = SleepyPenguin.splice(rd, tmp, 5, off_out: 0, exception: false)
     assert_equal 3, nr
-    assert_nil SleepyPenguin.trysplice(rd, nil, tmp, 0, 5,
-                                       SleepyPenguin::F_NONBLOCK)
+    assert_nil SleepyPenguin.splice(rd, tmp, 5, :nonblock,
+                                    off_out: 0, exception: false)
   end
 
   def test_splice_nonblock_socket
@@ -170,7 +168,7 @@ class TestSplice < Test::Unit::TestCase
     rs = TCPSocket.new('127.0.0.1', port)
     rs.nonblock = true
     assert_raises(Errno::EAGAIN) {
-      SleepyPenguin.splice(rs, nil, wp, nil, 1024, 0)
+      SleepyPenguin.splice(rs, wp, 1024)
     }
     rs.close
     server.close
@@ -183,7 +181,7 @@ class TestSplice < Test::Unit::TestCase
     rdb, wrb = IO.pipe
 
     assert_equal 5, wra.syswrite(str)
-    nr = SleepyPenguin.tee(rda.fileno, wrb.fileno, size, 0)
+    nr = SleepyPenguin.tee(rda.fileno, wrb.fileno, size)
     assert_equal 5, nr
     assert_equal str, rdb.sysread(5)
     assert_equal str, rda.sysread(5)
@@ -196,7 +194,7 @@ class TestSplice < Test::Unit::TestCase
     rdb, wrb = IO.pipe
 
     assert_equal 5, wra.syswrite(str)
-    nr = SleepyPenguin.trytee(rda, wrb, size, 0)
+    nr = SleepyPenguin.tee(rda, wrb, size, :nonblock, exception: false)
     assert_equal 5, nr
     assert_equal str, rdb.sysread(5)
     assert_equal str, rda.sysread(5)
@@ -207,7 +205,7 @@ class TestSplice < Test::Unit::TestCase
     rdb, wrb = IO.pipe
     wra.close
     assert_raises(EOFError) {
-      SleepyPenguin.tee(rda.fileno, wrb.fileno, 4096, 0)
+      SleepyPenguin.tee(rda.fileno, wrb.fileno, 4096)
     }
   end
 
@@ -215,7 +213,7 @@ class TestSplice < Test::Unit::TestCase
     rda, wra = IO.pipe
     rdb, wrb = IO.pipe
     wra.close
-    assert_nil SleepyPenguin.trytee(rda, wrb, 4096)
+    assert_nil SleepyPenguin.tee(rda, wrb, 4096, :nonblock, exception: false)
   end
 
   def test_tee_nonblock
@@ -229,7 +227,8 @@ class TestSplice < Test::Unit::TestCase
   def test_trytee_nonblock
     rda, wra = IO.pipe
     rdb, wrb = IO.pipe
-    assert_equal :EAGAIN, SleepyPenguin.trytee(rda, wrb, 4096)
+    assert_equal :EAGAIN, SleepyPenguin.tee(rda, wrb, 4096, :nonblock,
+                                            exception: false)
   end
 
   def test_tee_io
@@ -239,7 +238,7 @@ class TestSplice < Test::Unit::TestCase
     rdb, wrb = IO.pipe
 
     assert_equal 5, wra.syswrite(str)
-    nr = SleepyPenguin.tee(rda, wrb, size, 0)
+    nr = SleepyPenguin.tee(rda, wrb, size)
     assert_equal 5, nr
     assert_equal str, rdb.sysread(5)
     assert_equal str, rda.sysread(5)
diff --git a/test/test_splice_eintr.rb b/test/test_splice_eintr.rb
index 3a5d96f..41b6dd0 100644
--- a/test/test_splice_eintr.rb
+++ b/test/test_splice_eintr.rb
@@ -27,7 +27,7 @@ class Test_Splice_EINTR < Test::Unit::TestCase
       sleep 0.01
       wr.write "HI"
     end
-    nr = SleepyPenguin.splice rd, nil, tmp, nil, 666
+    nr = SleepyPenguin.splice rd, tmp, 666
     assert_equal 2, nr
     assert_equal 1, @usr1
   end