Ruby: ext/io/nonblock/nonblock.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

nonblock.c
Go to the documentation of this file.
1/**********************************************************************
2
3 io/nonblock.c -
4
5 $Author$
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
21static 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/*
34 * call-seq:
35 * io.nonblock? -> boolean
36 *
37 * Returns +true+ if an IO object is in non-blocking mode.
38 */
39static VALUE
40 rb_io_nonblock_p(VALUE io)
41{
42 rb_io_t *fptr;
43 GetOpenFile(io, fptr);
44 if (io_nonblock_mode(fptr->fd) & O_NONBLOCK)
45 return Qtrue;
46 return Qfalse;
47}
48#else
49#define rb_io_nonblock_p rb_f_notimplement
50#endif
51
52#ifdef F_SETFL
53static int
54io_nonblock_set(int fd, int f, int nb)
55{
56 if (nb) {
57 if ((f & O_NONBLOCK) != 0)
58 return 0;
59 f |= O_NONBLOCK;
60 }
61 else {
62 if ((f & O_NONBLOCK) == 0)
63 return 0;
64 f &= ~O_NONBLOCK;
65 }
66 if (fcntl(fd, F_SETFL, f) == -1)
67 rb_sys_fail(0);
68 return 1;
69}
70
71/*
72 * call-seq:
73 * io.nonblock = boolean -> boolean
74 *
75 * Enables non-blocking mode on a stream when set to
76 * +true+, and blocking mode when set to +false+.
77 */
78static VALUE
79 rb_io_nonblock_set(VALUE io, VALUE nb)
80{
81 rb_io_t *fptr;
82 GetOpenFile(io, fptr);
83 if (RTEST(nb))
84 rb_io_set_nonblock(fptr);
85 else
86 io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
87 return io;
88}
89
90static VALUE
91io_nonblock_restore(VALUE arg)
92{
93 int *restore = (int *)arg;
94 if (fcntl(restore[0], F_SETFL, restore[1]) == -1)
95 rb_sys_fail(0);
96 return Qnil;
97}
98
99/*
100 * call-seq:
101 * io.nonblock {|io| } -> io
102 * io.nonblock(boolean) {|io| } -> io
103 *
104 * Yields +self+ in non-blocking mode.
105 *
106 * When +false+ is given as an argument, +self+ is yielded in blocking mode.
107 * The original mode is restored after the block is executed.
108 */
109static VALUE
110 rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
111{
112 int nb = 1;
113 rb_io_t *fptr;
114 int f, restore[2];
115
116 GetOpenFile(io, fptr);
117 if (argc > 0) {
118 VALUE v;
119 rb_scan_args(argc, argv, "01", &v);
120 nb = RTEST(v);
121 }
122 f = io_nonblock_mode(fptr->fd);
123 restore[0] = fptr->fd;
124 restore[1] = f;
125 if (!io_nonblock_set(fptr->fd, f, nb))
126 return rb_yield(io);
127 return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
128}
129#else
130#define rb_io_nonblock_set rb_f_notimplement
131#define rb_io_nonblock_block rb_f_notimplement
132#endif
133
134void
135Init_nonblock(void)
136{
137 rb_define_method(rb_cIO, "nonblock?", rb_io_nonblock_p, 0);
138 rb_define_method(rb_cIO, "nonblock=", rb_io_nonblock_set, 1);
139 rb_define_method(rb_cIO, "nonblock", rb_io_nonblock_block, -1);
140}
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
rb_cIO
VALUE rb_cIO
Definition: io.c:183
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1148
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:3041
io.h
GetOpenFile
#define GetOpenFile
Definition: io.h:125
rb_io_set_nonblock
void rb_io_set_nonblock(rb_io_t *fptr)
Definition: io.c:2942
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1341
io_nonblock_mode
#define io_nonblock_mode(fd)
Definition: nonblock.c:29
rb_io_nonblock_p
#define rb_io_nonblock_p
Definition: nonblock.c:49
Init_nonblock
void Init_nonblock(void)
Definition: nonblock.c:135
rb_io_nonblock_block
#define rb_io_nonblock_block
Definition: nonblock.c:131
rb_io_nonblock_set
#define rb_io_nonblock_set
Definition: nonblock.c:130
ruby.h
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
f
#define f
rb_io_t
Definition: io.h:61
rb_io_t::fd
int fd
Definition: io.h:65
VALUE
unsigned long VALUE
Definition: value.h:38
O_NONBLOCK
#define O_NONBLOCK
Definition: win32.h:584
fcntl
int fcntl(int, int,...)
Definition: win32.c:4338
F_SETFL
#define F_SETFL
Definition: win32.h:581