Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ab538cd

Browse files
committedJun 1, 2023
Avoid direct access to IO internals.
1 parent 819d989 commit ab538cd

File tree

4 files changed

+32
-17
lines changed

4 files changed

+32
-17
lines changed
 

‎ext/nio4r/bytebuffer.c

+17-8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ static VALUE NIO_ByteBuffer_inspect(VALUE self);
3636

3737
#define MARK_UNSET -1
3838

39+
/* Compatibility for Ruby <= 3.1 */
40+
#ifndef HAVE_RB_IO_DESCRIPTOR
41+
static int
42+
io_descriptor_fallback(VALUE io)
43+
{
44+
rb_io_t *fptr;
45+
GetOpenFile(io, fptr);
46+
return fptr->fd;
47+
}
48+
#define rb_io_descriptor io_descriptor_fallback
49+
#endif
50+
3951
void Init_NIO_ByteBuffer()
4052
{
4153
mNIO = rb_define_module("NIO");
@@ -281,19 +293,18 @@ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
281293
static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
282294
{
283295
struct NIO_ByteBuffer *buffer;
284-
rb_io_t *fptr;
285296
ssize_t nbytes, bytes_read;
286297

287298
Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
288-
GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
289-
rb_io_set_nonblock(fptr);
299+
300+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
290301

291302
nbytes = buffer->limit - buffer->position;
292303
if (nbytes == 0) {
293304
rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
294305
}
295306

296-
bytes_read = read(FPTR_TO_FD(fptr), buffer->buffer + buffer->position, nbytes);
307+
bytes_read = read(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);
297308

298309
if (bytes_read < 0) {
299310
if (errno == EAGAIN) {
@@ -311,19 +322,17 @@ static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
311322
static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io)
312323
{
313324
struct NIO_ByteBuffer *buffer;
314-
rb_io_t *fptr;
315325
ssize_t nbytes, bytes_written;
316326

317327
Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
318-
GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
319-
rb_io_set_nonblock(fptr);
328+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
320329

321330
nbytes = buffer->limit - buffer->position;
322331
if (nbytes == 0) {
323332
rb_raise(cNIO_ByteBuffer_UnderflowError, "no data remaining in buffer");
324333
}
325334

326-
bytes_written = write(FPTR_TO_FD(fptr), buffer->buffer + buffer->position, nbytes);
335+
bytes_written = write(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);
327336

328337
if (bytes_written < 0) {
329338
if (errno == EAGAIN) {

‎ext/nio4r/extconf.rb

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
require "mkmf"
1717

1818
have_header("unistd.h")
19+
have_func("rb_io_descriptor")
1920

2021
$defs << "-DEV_USE_LINUXAIO" if have_header("linux/aio_abi.h")
2122
$defs << "-DEV_USE_IOURING" if have_header("linux/io_uring.h")

‎ext/nio4r/monitor.c

+14-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ static VALUE NIO_Monitor_readiness(VALUE self);
3434
static int NIO_Monitor_symbol2interest(VALUE interests);
3535
static void NIO_Monitor_update_interests(VALUE self, int interests);
3636

37+
/* Compatibility for Ruby <= 3.1 */
38+
#ifndef HAVE_RB_IO_DESCRIPTOR
39+
static int
40+
io_descriptor_fallback(VALUE io)
41+
{
42+
rb_io_t *fptr;
43+
GetOpenFile(io, fptr);
44+
return fptr->fd;
45+
}
46+
#define rb_io_descriptor io_descriptor_fallback
47+
#endif
48+
3749
/* Monitor control how a channel is being waited for by a monitor */
3850
void Init_NIO_Monitor()
3951
{
@@ -81,7 +93,6 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
8193
struct NIO_Monitor *monitor;
8294
struct NIO_Selector *selector;
8395
ID interests_id;
84-
rb_io_t *fptr;
8596

8697
interests_id = SYM2ID(interests);
8798

@@ -97,8 +108,8 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
97108
rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
98109
}
99110

100-
GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
101-
ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback, FPTR_TO_FD(fptr), monitor->interests);
111+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
112+
ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback, rb_io_descriptor(io), monitor->interests);
102113

103114
rb_ivar_set(self, rb_intern("io"), io);
104115
rb_ivar_set(self, rb_intern("interests"), interests);

‎ext/nio4r/nio4r.h

-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@ struct NIO_ByteBuffer {
4040
int position, limit, capacity, mark;
4141
};
4242

43-
#ifdef GetReadFile
44-
#define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
45-
#else
46-
#define FPTR_TO_FD(fptr) fptr->fd
47-
#endif /* GetReadFile */
48-
4943
/* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */
5044
void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
5145

0 commit comments

Comments
 (0)
Please sign in to comment.