Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /********************************************************************** 00002 00003 io/wait.c - 00004 00005 $Author: kosaki $ 00006 created at: Tue Jul 14 21:53:18 2009 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 #ifdef HAVE_UNISTD_H 00016 #include <unistd.h> 00017 #endif 00018 #include <fcntl.h> 00019 00020 #ifdef F_GETFL 00021 static int 00022 io_nonblock_mode(int fd) 00023 { 00024 int f = fcntl(fd, F_GETFL); 00025 if (f == -1) rb_sys_fail(0); 00026 return f; 00027 } 00028 #else 00029 #define io_nonblock_mode(fd) ((void)(fd), 0) 00030 #endif 00031 00032 #ifdef F_GETFL 00033 static VALUE 00034 rb_io_nonblock_p(VALUE io) 00035 { 00036 rb_io_t *fptr; 00037 GetOpenFile(io, fptr); 00038 if (io_nonblock_mode(fptr->fd) & O_NONBLOCK) 00039 return Qtrue; 00040 return Qfalse; 00041 } 00042 #else 00043 #define rb_io_nonblock_p rb_f_notimplement 00044 #endif 00045 00046 #ifdef F_SETFL 00047 static void 00048 io_nonblock_set(int fd, int f, int nb) 00049 { 00050 if (nb) { 00051 if ((f & O_NONBLOCK) != 0) 00052 return; 00053 f |= O_NONBLOCK; 00054 } 00055 else { 00056 if ((f & O_NONBLOCK) == 0) 00057 return; 00058 f &= ~O_NONBLOCK; 00059 } 00060 if (fcntl(fd, F_SETFL, f) == -1) 00061 rb_sys_fail(0); 00062 } 00063 00064 static VALUE 00065 rb_io_nonblock_set(VALUE io, VALUE nb) 00066 { 00067 rb_io_t *fptr; 00068 GetOpenFile(io, fptr); 00069 io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb)); 00070 return io; 00071 } 00072 00073 static VALUE 00074 io_nonblock_restore(VALUE arg) 00075 { 00076 int *restore = (int *)arg; 00077 if (fcntl(restore[0], F_SETFL, restore[1]) == -1) 00078 rb_sys_fail(0); 00079 return Qnil; 00080 } 00081 00082 static VALUE 00083 rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) 00084 { 00085 int nb = 1; 00086 rb_io_t *fptr; 00087 int f, restore[2]; 00088 00089 GetOpenFile(io, fptr); 00090 if (argc > 0) { 00091 VALUE v; 00092 rb_scan_args(argc, argv, "01", &v); 00093 nb = RTEST(v); 00094 } 00095 f = io_nonblock_mode(fptr->fd); 00096 restore[0] = fptr->fd; 00097 restore[1] = f; 00098 io_nonblock_set(fptr->fd, f, nb); 00099 return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore); 00100 } 00101 #else 00102 #define rb_io_nonblock_set rb_f_notimplement 00103 #define rb_io_nonblock_block rb_f_notimplement 00104 #endif 00105 00106 void 00107 Init_nonblock(void) 00108 { 00109 VALUE io = rb_cIO; 00110 00111 rb_define_method(io, "nonblock?", rb_io_nonblock_p, 0); 00112 rb_define_method(io, "nonblock=", rb_io_nonblock_set, 1); 00113 rb_define_method(io, "nonblock", rb_io_nonblock_block, -1); 00114 } 00115