summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb7
-rw-r--r--thread.c3
2 files changed, 10 insertions, 0 deletions
diff --git a/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb b/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
index d7bc827a6e..1141dd317c 100644
--- a/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
+++ b/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
@@ -22,6 +22,13 @@ class TestWaitForSingleFD < Test::Unit::TestCase
end
def test_wait_for_invalid_fd
+ # Negative FDs should not cause NoMemoryError or segfault when
+ # using select(). For now, match the poll() implementation
+ # used on Linux, which sleeps the given amount of time given
+ # when fd is negative (as documented in the Linux poll(2) manpage)
+ assert_equal 0, IO.wait_for_single_fd(-999, RB_WAITFD_IN, 0)
+ assert_equal 0, IO.wait_for_single_fd(-1, RB_WAITFD_OUT, 0)
+
# FreeBSD 8.2 or prior sticks this
# http://bugs.ruby-lang.org/issues/5524
skip if /freebsd[1-8]/ =~ RUBY_PLATFORM
diff --git a/thread.c b/thread.c
index 76fb1360c9..4d954c76de 100644
--- a/thread.c
+++ b/thread.c
@@ -3969,6 +3969,9 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
static rb_fdset_t *
init_set_fd(int fd, rb_fdset_t *fds)
{
+ if (fd < 0) {
+ return 0;
+ }
rb_fd_init(fds);
rb_fd_set(fd, fds);