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_SYS_IOCTL_H)
00018 #include <sys/ioctl.h>
00019 #endif
00020 #if defined(FIONREAD_HEADER)
00021 #include FIONREAD_HEADER
00022 #endif
00023
00024 #ifdef HAVE_RB_W32_IOCTLSOCKET
00025 #define ioctl ioctlsocket
00026 #define ioctl_arg u_long
00027 #define ioctl_arg2num(i) ULONG2NUM(i)
00028 #else
00029 #define ioctl_arg int
00030 #define ioctl_arg2num(i) INT2NUM(i)
00031 #endif
00032
00033 #ifdef HAVE_RB_W32_IS_SOCKET
00034 #define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd)
00035 #else
00036 #define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
00037 #endif
00038
00039 static VALUE io_ready_p _((VALUE io));
00040 static VALUE io_wait _((int argc, VALUE *argv, VALUE io));
00041 void Init_wait _((void));
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 static VALUE
00052 io_nread(VALUE io)
00053 {
00054 rb_io_t *fptr;
00055 int len;
00056 ioctl_arg n;
00057
00058 GetOpenFile(io, fptr);
00059 rb_io_check_readable(fptr);
00060 len = rb_io_read_pending(fptr);
00061 if (len > 0) return len;
00062 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
00063 if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
00064 if (n > 0) return ioctl_arg2num(n);
00065 return INT2FIX(0);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static VALUE
00077 io_ready_p(VALUE io)
00078 {
00079 rb_io_t *fptr;
00080 ioctl_arg n;
00081
00082 GetOpenFile(io, fptr);
00083 rb_io_check_readable(fptr);
00084 if (rb_io_read_pending(fptr)) return Qtrue;
00085 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qnil;
00086 if (ioctl(fptr->fd, FIONREAD, &n)) return Qnil;
00087 if (n > 0) return Qtrue;
00088 return Qfalse;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 static VALUE
00101 io_wait(int argc, VALUE *argv, VALUE io)
00102 {
00103 rb_io_t *fptr;
00104 int i;
00105 ioctl_arg n;
00106 VALUE timeout;
00107 struct timeval timerec;
00108 struct timeval *tv;
00109
00110 GetOpenFile(io, fptr);
00111 rb_io_check_readable(fptr);
00112 rb_scan_args(argc, argv, "01", &timeout);
00113 if (NIL_P(timeout)) {
00114 tv = NULL;
00115 }
00116 else {
00117 timerec = rb_time_interval(timeout);
00118 tv = &timerec;
00119 }
00120
00121 if (rb_io_read_pending(fptr)) return Qtrue;
00122 if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
00123 i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
00124 if (i < 0)
00125 rb_sys_fail(0);
00126 rb_io_check_closed(fptr);
00127 if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
00128 if (n > 0) return io;
00129 return Qnil;
00130 }
00131
00132
00133
00134
00135
00136 void
00137 Init_wait()
00138 {
00139 rb_define_method(rb_cIO, "nread", io_nread, 0);
00140 rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
00141 rb_define_method(rb_cIO, "wait", io_wait, -1);
00142 }
00143