Ruby  1.9.3p448(2013-06-27revision41675)
wait.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  io/wait.c -
4 
5  $Author: kosaki $
6  created at: Tue Aug 28 09:08:06 JST 2001
7 
8  All the files in this distribution are covered under the Ruby's
9  license (see the file COPYING).
10 
11 **********************************************************************/
12 
13 #include "ruby.h"
14 #include "ruby/io.h"
15 
16 #include <sys/types.h>
17 #if defined(HAVE_SYS_IOCTL_H)
18 #include <sys/ioctl.h>
19 #endif
20 #if defined(FIONREAD_HEADER)
21 #include FIONREAD_HEADER
22 #endif
23 
24 #ifdef HAVE_RB_W32_IOCTLSOCKET
25 #define ioctl ioctlsocket
26 #define ioctl_arg u_long
27 #define ioctl_arg2num(i) ULONG2NUM(i)
28 #else
29 #define ioctl_arg int
30 #define ioctl_arg2num(i) INT2NUM(i)
31 #endif
32 
33 #ifdef HAVE_RB_W32_IS_SOCKET
34 #define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd)
35 #else
36 #define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
37 #endif
38 
39 static VALUE io_ready_p _((VALUE io));
40 static VALUE io_wait _((int argc, VALUE *argv, VALUE io));
41 void Init_wait _((void));
42 
43 /*
44  * call-seq:
45  * io.nread -> int
46  *
47  * Returns number of bytes that can be read without blocking.
48  * Returns zero if no information available.
49  */
50 
51 static VALUE
53 {
54  rb_io_t *fptr;
55  int len;
56  ioctl_arg n;
57 
58  GetOpenFile(io, fptr);
60  len = rb_io_read_pending(fptr);
61  if (len > 0) return len;
62  if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
63  if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
64  if (n > 0) return ioctl_arg2num(n);
65  return INT2FIX(0);
66 }
67 
68 /*
69  * call-seq:
70  * io.ready? -> true, false or nil
71  *
72  * Returns true if input available without blocking, or false.
73  * Returns nil if no information available.
74  */
75 
76 static VALUE
78 {
79  rb_io_t *fptr;
80  ioctl_arg n;
81 
82  GetOpenFile(io, fptr);
84  if (rb_io_read_pending(fptr)) return Qtrue;
85  if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qnil;
86  if (ioctl(fptr->fd, FIONREAD, &n)) return Qnil;
87  if (n > 0) return Qtrue;
88  return Qfalse;
89 }
90 
91 /*
92  * call-seq:
93  * io.wait -> IO, true, false or nil
94  * io.wait(timeout) -> IO, true, false or nil
95  *
96  * Waits until input is available or times out and returns self or nil when
97  * EOF is reached.
98  */
99 
100 static VALUE
102 {
103  rb_io_t *fptr;
104  int i;
105  ioctl_arg n;
106  VALUE timeout;
107  struct timeval timerec;
108  struct timeval *tv;
109 
110  GetOpenFile(io, fptr);
111  rb_io_check_readable(fptr);
112  rb_scan_args(argc, argv, "01", &timeout);
113  if (NIL_P(timeout)) {
114  tv = NULL;
115  }
116  else {
117  timerec = rb_time_interval(timeout);
118  tv = &timerec;
119  }
120 
121  if (rb_io_read_pending(fptr)) return Qtrue;
122  if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
123  i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
124  if (i < 0)
125  rb_sys_fail(0);
126  rb_io_check_closed(fptr);
127  if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
128  if (n > 0) return io;
129  return Qnil;
130 }
131 
132 /*
133  * IO wait methods
134  */
135 
136 void
138 {
139  rb_define_method(rb_cIO, "nread", io_nread, 0);
140  rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
141  rb_define_method(rb_cIO, "wait", io_wait, -1);
142 }
143