Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

nonblock.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 io/wait.c -
4
5 $Author: kosaki $
6 created at: Tue Jul 14 21:53:18 2009
7
8 All the files in this distribution are covered under the Ruby's
9 license (see the file COPYING).
10
11 **********************************************************************/
12
13 #include "ruby.h"
14 #include "ruby/io.h"
15 #ifdef HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <fcntl.h>
19
20 #ifdef F_GETFL
21 static int
22 io_nonblock_mode(int fd)
23 {
24 int f = fcntl(fd, F_GETFL);
25 if (f == -1) rb_sys_fail(0);
26 return f;
27 }
28 #else
29 #define io_nonblock_mode(fd) ((void)(fd), 0)
30 #endif
31
32 #ifdef F_GETFL
33 static VALUE
34 rb_io_nonblock_p(VALUE io)
35 {
36 rb_io_t *fptr;
37 GetOpenFile(io, fptr);
38 if (io_nonblock_mode(fptr->fd) & O_NONBLOCK)
39 return Qtrue;
40 return Qfalse;
41 }
42 #else
43 #define rb_io_nonblock_p rb_f_notimplement
44 #endif
45
46 #ifdef F_SETFL
47 static void
48 io_nonblock_set(int fd, int f, int nb)
49 {
50 if (nb) {
51 if ((f & O_NONBLOCK) != 0)
52 return;
53 f |= O_NONBLOCK;
54 }
55 else {
56 if ((f & O_NONBLOCK) == 0)
57 return;
58 f &= ~O_NONBLOCK;
59 }
60 if (fcntl(fd, F_SETFL, f) == -1)
61 rb_sys_fail(0);
62 }
63
64 static VALUE
65 rb_io_nonblock_set(VALUE io, VALUE nb)
66 {
67 rb_io_t *fptr;
68 GetOpenFile(io, fptr);
69 io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
70 return io;
71 }
72
73 static VALUE
74 io_nonblock_restore(VALUE arg)
75 {
76 int *restore = (int *)arg;
77 if (fcntl(restore[0], F_SETFL, restore[1]) == -1)
78 rb_sys_fail(0);
79 return Qnil;
80 }
81
82 static VALUE
83 rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
84 {
85 int nb = 1;
86 rb_io_t *fptr;
87 int f, restore[2];
88
89 GetOpenFile(io, fptr);
90 if (argc > 0) {
91 VALUE v;
92 rb_scan_args(argc, argv, "01", &v);
93 nb = RTEST(v);
94 }
95 f = io_nonblock_mode(fptr->fd);
96 restore[0] = fptr->fd;
97 restore[1] = f;
98 io_nonblock_set(fptr->fd, f, nb);
99 return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
100 }
101 #else
102 #define rb_io_nonblock_set rb_f_notimplement
103 #define rb_io_nonblock_block rb_f_notimplement
104 #endif
105
106 void
107 Init_nonblock(void)
108 {
109 VALUE io = rb_cIO;
110
111 rb_define_method(io, "nonblock?", rb_io_nonblock_p, 0);
112 rb_define_method(io, "nonblock=", rb_io_nonblock_set, 1);
113 rb_define_method(io, "nonblock", rb_io_nonblock_block, -1);
114 }
115