This commit is contained in:
Samuel Williams 2025-08-15 05:07:26 +02:00 committed by GitHub
commit 01c278684f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 59 additions and 0 deletions

View file

@ -735,6 +735,39 @@ bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
return val;
}
static VALUE
bsock_readable_p(VALUE self)
{
VALUE result = rb_call_super(0, NULL);
if (RTEST(result)) {
rb_io_t *fptr;
RB_IO_POINTER(self, fptr);
char buffer[1];
#ifdef MSG_DONTWAIT
int result = recv(fptr->fd, buffer, 1, MSG_PEEK | MSG_DONTWAIT);
#else
rb_io_set_nonblock(fptr);
int result = recv(fptr->fd, buffer, 1, MSG_PEEK);
#endif
if (result > 0) {
return Qtrue;
}
if (result == 0) {
return Qfalse;
}
if (result == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
return Qtrue;
}
} else {
return Qfalse;
}
}
void
rsock_init_basicsocket(void)
{
@ -768,6 +801,8 @@ rsock_init_basicsocket(void)
rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0);
rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1);
rb_define_method(rb_cBasicSocket, "readable?", bsock_readable_p, 0);
/* for ext/socket/lib/socket.rb use only: */
rb_define_private_method(rb_cBasicSocket,
"__recv_nonblock", bsock_recv_nonblock, 4);

View file

@ -660,6 +660,14 @@ strio_eof(VALUE self)
return Qtrue;
}
static VALUE
strio_readable_p(VALUE self)
{
if (strio_to_read(self)) return Qtrue;
return Qfalse;
}
/* :nodoc: */
static VALUE
strio_copy(VALUE copy, VALUE orig)
@ -1971,6 +1979,7 @@ Init_stringio(void)
rb_define_method(StringIO, "closed_write?", strio_closed_write, 0);
rb_define_method(StringIO, "eof", strio_eof, 0);
rb_define_method(StringIO, "eof?", strio_eof, 0);
rb_define_method(StringIO, "readable?", strio_readable_p, 0);
/* call-seq: strio.fcntl */
rb_define_method(StringIO, "fcntl", strio_fcntl, -1);
/* call-seq: strio.flush -> strio */

15
io.c
View file

@ -2657,6 +2657,20 @@ io_fillbuf(rb_io_t *fptr)
return 0;
}
VALUE
rb_io_readable_p(VALUE io)
{
rb_io_t *fptr;
RB_IO_POINTER(io, fptr);
rb_io_check_char_readable(fptr);
if (READ_CHAR_PENDING(fptr)) return Qtrue;
if (READ_DATA_PENDING(fptr)) return Qtrue;
return RBOOL(fptr->fd >= 0);
}
/*
* call-seq:
* eof -> true or false
@ -15842,6 +15856,7 @@ Init_IO(void)
rb_define_method(rb_cIO, "rewind", rb_io_rewind, 0);
rb_define_method(rb_cIO, "pos", rb_io_tell, 0);
rb_define_method(rb_cIO, "pos=", rb_io_set_pos, 1);
rb_define_method(rb_cIO, "readable?", rb_io_readable_p, 0);
rb_define_method(rb_cIO, "eof", rb_io_eof, 0);
rb_define_method(rb_cIO, "eof?", rb_io_eof, 0);