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 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 f |= O_NONBLOCK;
00052 else
00053 f &= ~O_NONBLOCK;
00054 if (fcntl(fd, F_SETFL, f) == -1)
00055 rb_sys_fail(0);
00056 }
00057
00058 static VALUE
00059 rb_io_nonblock_set(VALUE io, VALUE nb)
00060 {
00061 rb_io_t *fptr;
00062 GetOpenFile(io, fptr);
00063 io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
00064 return io;
00065 }
00066
00067 static VALUE
00068 io_nonblock_restore(VALUE arg)
00069 {
00070 int *restore = (int *)arg;
00071 if (fcntl(restore[0], F_SETFL, restore[1]) == -1)
00072 rb_sys_fail(0);
00073 return Qnil;
00074 }
00075
00076 static VALUE
00077 rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
00078 {
00079 int nb = 1;
00080 rb_io_t *fptr;
00081 int f, restore[2];
00082
00083 GetOpenFile(io, fptr);
00084 if (argc > 0) {
00085 VALUE v;
00086 rb_scan_args(argc, argv, "01", &v);
00087 nb = RTEST(v);
00088 }
00089 f = io_nonblock_mode(fptr->fd);
00090 restore[0] = fptr->fd;
00091 restore[1] = f;
00092 io_nonblock_set(fptr->fd, f, nb);
00093 return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
00094 }
00095 #else
00096 #define rb_io_nonblock_set rb_f_notimplement
00097 #define rb_io_nonblock_block rb_f_notimplement
00098 #endif
00099
00100 void
00101 Init_nonblock(void)
00102 {
00103 VALUE io = rb_cIO;
00104
00105 rb_define_method(io, "nonblock?", rb_io_nonblock_p, 0);
00106 rb_define_method(io, "nonblock=", rb_io_nonblock_set, 1);
00107 rb_define_method(io, "nonblock", rb_io_nonblock_block, -1);
00108 }
00109