Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /********************************************************************** 00002 00003 io/wait.c - 00004 00005 $Author: kosaki $ 00006 created at: Tue Aug 28 09:08:06 JST 2001 00007 00008 All the files in this distribution are covered under the Ruby's 00009 license (see the file COPYING). 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 * call-seq: 00045 * io.nread -> int 00046 * 00047 * Returns number of bytes that can be read without blocking. 00048 * Returns zero if no information available. 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 * call-seq: 00070 * io.ready? -> true, false or nil 00071 * 00072 * Returns true if input available without blocking, or false. 00073 * Returns nil if no information available. 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 * call-seq: 00093 * io.wait -> IO, true, false or nil 00094 * io.wait(timeout) -> IO, true, false or nil 00095 * 00096 * Waits until input is available or times out and returns self or nil when 00097 * EOF is reached. 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 * IO wait methods 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