1/* test case for deprecated C API */ 2#include "ruby/ruby.h" 3#include "ruby/io.h" 4 5static fd_set * array2fdset(fd_set *fds, VALUE ary, int *max) 6{ 7 long i; 8 9 if (NIL_P(ary)) 10 return NULL; 11 12 FD_ZERO(fds); 13 Check_Type(ary, T_ARRAY); 14 for (i = 0; i < RARRAY_LEN(ary); i++) { 15 VALUE val = RARRAY_PTR(ary)[i]; 16 int fd; 17 18 Check_Type(val, T_FIXNUM); 19 fd = FIX2INT(val); 20 if (fd >= *max) 21 *max = fd + 1; 22 FD_SET(fd, fds); 23 } 24 25 return fds; 26} 27 28static void fdset2array(VALUE dst, fd_set *fds, int max) 29{ 30 int i; 31 32 rb_ary_clear(dst); 33 34 for (i = 0; i < max; i++) { 35 if (FD_ISSET(i, fds)) 36 rb_ary_push(dst, INT2NUM(i)); 37 } 38} 39 40static VALUE 41old_thread_select(VALUE klass, VALUE r, VALUE w, VALUE e, VALUE timeout) 42{ 43 struct timeval tv; 44 struct timeval *tvp = NULL; 45 fd_set rfds, wfds, efds; 46 fd_set *rp, *wp, *ep; 47 int rc; 48 int max = 0; 49 50 if (!NIL_P(timeout)) { 51 tv = rb_time_timeval(timeout); 52 tvp = &tv; 53 } 54 rp = array2fdset(&rfds, r, &max); 55 wp = array2fdset(&wfds, w, &max); 56 ep = array2fdset(&efds, e, &max); 57 rc = rb_thread_select(max, rp, wp, ep, tvp); 58 if (rc == -1) 59 rb_sys_fail("rb_wait_for_single_fd"); 60 61 if (rp) 62 fdset2array(r, &rfds, max); 63 if (wp) 64 fdset2array(w, &wfds, max); 65 if (ep) 66 fdset2array(e, &efds, max); 67 return INT2NUM(rc); 68} 69 70void 71Init_old_thread_select(void) 72{ 73 rb_define_singleton_method(rb_cIO, "old_thread_select", 74 old_thread_select, 4); 75} 76