ext/io/nonblock/nonblock.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   io/wait.c -
00004 
00005   $Author: akr $
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         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 

Generated on Wed Aug 10 09:17:00 2011 for Ruby by  doxygen 1.4.7