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