From 70845ee5091380b02a252006cfeb8c402a315df8 Mon Sep 17 00:00:00 2001
From: Eric Wong <e@80x24.org>
Date: Fri, 11 Dec 2015 19:51:15 +0000
Subject: [PATCH] IO#advise avoids raising Errno::ENOSYS

As it is just a hint the kernel is free to ignore,
IO#advise already succeeds when posix_fadvise is not
available build time at all.  Following that, if posix_fadvise
was available at build time but not implemented in the running
kernel, we should also ignore it.

* io.c (do_io_advise): do not raise on ENOSYS
* test/ruby/test_io.rb (test_advise): do not skip on Errno::ENOSYS
  (test_advise_pipe): ditto
---
 io.c                 | 2 +-
 test/ruby/test_io.rb | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/io.c b/io.c
index d5bd2fc..c8c13f8 100644
--- a/io.c
+++ b/io.c
@@ -8586,7 +8586,7 @@ do_io_advise(rb_io_t *fptr, VALUE advice, off_t offset, off_t len)
     ias.len    = len;
 
     rv = (int)rb_thread_io_blocking_region(io_advise_internal, &ias, fptr->fd);
-    if (rv) {
+    if (rv && rv != ENOSYS) {
 	/* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
 	   it returns the error code. */
 	VALUE message = rb_sprintf("%"PRIsVALUE" "
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index a237fa3..ad9e4fa 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2565,8 +2565,6 @@ def test_advise
             ret = assert_nothing_raised(lambda { os_and_fs(tf.path) }) {
               begin
                 t.advise(adv, offset, len)
-              rescue Errno::ENOSYS
-                skip
               rescue Errno::EINVAL => e
                 if /linux/ =~ RUBY_PLATFORM && (Etc.uname[:release].split('.').map(&:to_i) <=> [3,6]) < 0
                   next # [ruby-core:65355] tmpfs is not supported
@@ -3007,8 +3005,8 @@ def test_advise_pipe
     # we don't know if other platforms have a real posix_fadvise()
     with_pipe do |r,w|
       # Linux 2.6.15 and earlier returned EINVAL instead of ESPIPE
-      assert_raise(Errno::ESPIPE, Errno::EINVAL, Errno::ENOSYS) { r.advise(:willneed) }
-      assert_raise(Errno::ESPIPE, Errno::EINVAL, Errno::ENOSYS) { w.advise(:willneed) }
+      assert_raise(Errno::ESPIPE, Errno::EINVAL) { r.advise(:willneed) }
+      assert_raise(Errno::ESPIPE, Errno::EINVAL) { w.advise(:willneed) }
     end
   end if /linux/ =~ RUBY_PLATFORM
 
-- 
EW

