00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00034
00035
00036
00037
00038
00039 static VALUE
00040 rb_io_nonblock_p(VALUE io)
00041 {
00042 rb_io_t *fptr;
00043 GetOpenFile(io, fptr);
00044 if (io_nonblock_mode(fptr->fd) & O_NONBLOCK)
00045 return Qtrue;
00046 return Qfalse;
00047 }
00048 #else
00049 #define rb_io_nonblock_p rb_f_notimplement
00050 #endif
00051
00052 #ifdef F_SETFL
00053 static void
00054 io_nonblock_set(int fd, int f, int nb)
00055 {
00056 if (nb) {
00057 if ((f & O_NONBLOCK) != 0)
00058 return;
00059 f |= O_NONBLOCK;
00060 }
00061 else {
00062 if ((f & O_NONBLOCK) == 0)
00063 return;
00064 f &= ~O_NONBLOCK;
00065 }
00066 if (fcntl(fd, F_SETFL, f) == -1)
00067 rb_sys_fail(0);
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 static VALUE
00078 rb_io_nonblock_set(VALUE io, VALUE nb)
00079 {
00080 rb_io_t *fptr;
00081 GetOpenFile(io, fptr);
00082 io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
00083 return io;
00084 }
00085
00086 static VALUE
00087 io_nonblock_restore(VALUE arg)
00088 {
00089 int *restore = (int *)arg;
00090 if (fcntl(restore[0], F_SETFL, restore[1]) == -1)
00091 rb_sys_fail(0);
00092 return Qnil;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 static VALUE
00106 rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
00107 {
00108 int nb = 1;
00109 rb_io_t *fptr;
00110 int f, restore[2];
00111
00112 GetOpenFile(io, fptr);
00113 if (argc > 0) {
00114 VALUE v;
00115 rb_scan_args(argc, argv, "01", &v);
00116 nb = RTEST(v);
00117 }
00118 f = io_nonblock_mode(fptr->fd);
00119 restore[0] = fptr->fd;
00120 restore[1] = f;
00121 io_nonblock_set(fptr->fd, f, nb);
00122 return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
00123 }
00124 #else
00125 #define rb_io_nonblock_set rb_f_notimplement
00126 #define rb_io_nonblock_block rb_f_notimplement
00127 #endif
00128
00129 void
00130 Init_nonblock(void)
00131 {
00132 rb_define_method(rb_cIO, "nonblock?", rb_io_nonblock_p, 0);
00133 rb_define_method(rb_cIO, "nonblock=", rb_io_nonblock_set, 1);
00134 rb_define_method(rb_cIO, "nonblock", rb_io_nonblock_block, -1);
00135 }
00136