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 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