00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "ruby.h"
00014 #include "ruby/io.h"
00015
00016 #include <sys/types.h>
00017 #if defined(HAVE_UNISTD_H) && (defined(__sun))
00018 #include <unistd.h>
00019 #endif
00020 #if defined(HAVE_SYS_IOCTL_H)
00021 #include <sys/ioctl.h>
00022 #endif
00023 #if defined(FIONREAD_HEADER)
00024 #include FIONREAD_HEADER
00025 #endif
00026
00027 #ifdef HAVE_RB_W32_IOCTLSOCKET
00028 #define ioctl ioctlsocket
00029 #define ioctl_arg u_long
00030 #define ioctl_arg2num(i) ULONG2NUM(i)
00031 #else
00032 #define ioctl_arg int
00033 #define ioctl_arg2num(i) INT2NUM(i)
00034 #endif
00035
00036 #ifdef HAVE_RB_W32_IS_SOCKET
00037 #define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd)
00038 #else
00039 #define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
00040 #endif
00041
00042 static VALUE io_ready_p _((VALUE io));
00043 static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io));
00044 static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io));
00045 void Init_wait _((void));
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 static VALUE
00056 io_nread(VALUE io)
00057 {
00058 rb_io_t *fptr;
00059 int len;
00060 ioctl_arg n;
00061
00062 GetOpenFile(io, fptr);
00063 rb_io_check_readable(fptr);
00064 len = rb_io_read_pending(fptr);
00065 if (len > 0) return INT2FIX(len);
00066 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
00067 if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
00068 if (n > 0) return ioctl_arg2num(n);
00069 return INT2FIX(0);
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static VALUE
00081 io_ready_p(VALUE io)
00082 {
00083 rb_io_t *fptr;
00084 ioctl_arg n;
00085
00086 GetOpenFile(io, fptr);
00087 rb_io_check_readable(fptr);
00088 if (rb_io_read_pending(fptr)) return Qtrue;
00089 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qnil;
00090 if (ioctl(fptr->fd, FIONREAD, &n)) return Qnil;
00091 if (n > 0) return Qtrue;
00092 return Qfalse;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 static VALUE
00107 io_wait_readable(int argc, VALUE *argv, VALUE io)
00108 {
00109 rb_io_t *fptr;
00110 int i;
00111 ioctl_arg n;
00112 VALUE timeout;
00113 struct timeval timerec;
00114 struct timeval *tv;
00115
00116 GetOpenFile(io, fptr);
00117 rb_io_check_readable(fptr);
00118 rb_scan_args(argc, argv, "01", &timeout);
00119 if (NIL_P(timeout)) {
00120 tv = NULL;
00121 }
00122 else {
00123 timerec = rb_time_interval(timeout);
00124 tv = &timerec;
00125 }
00126
00127 if (rb_io_read_pending(fptr)) return Qtrue;
00128 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
00129 i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
00130 if (i < 0)
00131 rb_sys_fail(0);
00132 rb_io_check_closed(fptr);
00133 if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
00134 if (n > 0) return io;
00135 return Qnil;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static VALUE
00147 io_wait_writable(int argc, VALUE *argv, VALUE io)
00148 {
00149 rb_io_t *fptr;
00150 int i;
00151 VALUE timeout;
00152 struct timeval timerec;
00153 struct timeval *tv;
00154
00155 GetOpenFile(io, fptr);
00156 rb_io_check_writable(fptr);
00157 rb_scan_args(argc, argv, "01", &timeout);
00158 if (NIL_P(timeout)) {
00159 tv = NULL;
00160 }
00161 else {
00162 timerec = rb_time_interval(timeout);
00163 tv = &timerec;
00164 }
00165
00166 i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_OUT, tv);
00167 if (i < 0)
00168 rb_sys_fail(0);
00169 rb_io_check_closed(fptr);
00170 if (i & RB_WAITFD_OUT)
00171 return io;
00172 return Qnil;
00173 }
00174
00175
00176
00177
00178
00179 void
00180 Init_wait()
00181 {
00182 rb_define_method(rb_cIO, "nread", io_nread, 0);
00183 rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
00184 rb_define_method(rb_cIO, "wait", io_wait_readable, -1);
00185 rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
00186 rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1);
00187 }
00188