diff options
Diffstat (limited to 'spec/ruby/optional/capi/ext/io_spec.c')
-rw-r--r-- | spec/ruby/optional/capi/ext/io_spec.c | 136 |
1 files changed, 132 insertions, 4 deletions
diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index b4ffe9207a..1a73331386 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -28,9 +28,13 @@ static int set_non_blocking(int fd) { } static int io_spec_get_fd(VALUE io) { +#ifdef RUBY_VERSION_IS_3_1 + return rb_io_descriptor(io); +#else rb_io_t* fp; GetOpenFile(io, fp); return fp->fd; +#endif } VALUE io_spec_GetOpenFile_fd(VALUE self, VALUE io) { @@ -130,7 +134,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { rb_sys_fail("set_non_blocking failed"); #ifndef SET_NON_BLOCKING_FAILS_ALWAYS - if(RTEST(read_p)) { + if (RTEST(read_p)) { if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) { return Qnil; } @@ -141,7 +145,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { ret = rb_io_wait_readable(fd); - if(RTEST(read_p)) { + if (RTEST(read_p)) { ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF); if (r != RB_IO_WAIT_READABLE_BUF) { perror("read"); @@ -153,7 +157,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) { return ret ? Qtrue : Qfalse; #else - UNREACHABLE; + UNREACHABLE_RETURN(Qnil); #endif } @@ -162,6 +166,64 @@ VALUE io_spec_rb_io_wait_writable(VALUE self, VALUE io) { return ret ? Qtrue : Qfalse; } +#ifdef RUBY_VERSION_IS_3_1 +VALUE io_spec_rb_io_maybe_wait_writable(VALUE self, VALUE error, VALUE io, VALUE timeout) { + int ret = rb_io_maybe_wait_writable(NUM2INT(error), io, timeout); + return INT2NUM(ret); +} +#endif + +#ifdef RUBY_VERSION_IS_3_1 +#ifdef SET_NON_BLOCKING_FAILS_ALWAYS +NORETURN(VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p)); +#endif + +VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p) { + int fd = io_spec_get_fd(io); +#ifndef SET_NON_BLOCKING_FAILS_ALWAYS + char buf[RB_IO_WAIT_READABLE_BUF]; + int ret, saved_errno; +#endif + + if (set_non_blocking(fd) == -1) + rb_sys_fail("set_non_blocking failed"); + +#ifndef SET_NON_BLOCKING_FAILS_ALWAYS + if (RTEST(read_p)) { + if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) { + return Qnil; + } + saved_errno = errno; + rb_ivar_set(self, rb_intern("@write_data"), Qtrue); + errno = saved_errno; + } + + // main part + ret = rb_io_maybe_wait_readable(NUM2INT(error), io, timeout); + + if (RTEST(read_p)) { + ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF); + if (r != RB_IO_WAIT_READABLE_BUF) { + perror("read"); + return SSIZET2NUM(r); + } + rb_ivar_set(self, rb_intern("@read_data"), + rb_str_new(buf, RB_IO_WAIT_READABLE_BUF)); + } + + return INT2NUM(ret); +#else + UNREACHABLE_RETURN(Qnil); +#endif +} +#endif + +#ifdef RUBY_VERSION_IS_3_1 +VALUE io_spec_rb_io_maybe_wait(VALUE self, VALUE error, VALUE io, VALUE events, VALUE timeout) { + return rb_io_maybe_wait(NUM2INT(error), io, events, timeout); +} +#endif + VALUE io_spec_rb_thread_wait_fd(VALUE self, VALUE io) { rb_thread_wait_fd(io_spec_get_fd(io)); return Qnil; @@ -182,6 +244,46 @@ VALUE io_spec_rb_thread_fd_writable(VALUE self, VALUE io) { return Qnil; } +VALUE io_spec_rb_thread_fd_select_read(VALUE self, VALUE io) { + int fd = io_spec_get_fd(io); + + rb_fdset_t fds; + rb_fd_init(&fds); + rb_fd_set(fd, &fds); + + int r = rb_thread_fd_select(fd + 1, &fds, NULL, NULL, NULL); + rb_fd_term(&fds); + return INT2FIX(r); +} + +VALUE io_spec_rb_thread_fd_select_write(VALUE self, VALUE io) { + int fd = io_spec_get_fd(io); + + rb_fdset_t fds; + rb_fd_init(&fds); + rb_fd_set(fd, &fds); + + int r = rb_thread_fd_select(fd + 1, NULL, &fds, NULL, NULL); + rb_fd_term(&fds); + return INT2FIX(r); +} + +VALUE io_spec_rb_thread_fd_select_timeout(VALUE self, VALUE io) { + int fd = io_spec_get_fd(io); + + struct timeval timeout; + timeout.tv_sec = 10; + timeout.tv_usec = 20; + + rb_fdset_t fds; + rb_fd_init(&fds); + rb_fd_set(fd, &fds); + + int r = rb_thread_fd_select(fd + 1, NULL, &fds, NULL, &timeout); + rb_fd_term(&fds); + return INT2FIX(r); +} + VALUE io_spec_rb_io_binmode(VALUE self, VALUE io) { return rb_io_binmode(io); } @@ -209,7 +311,7 @@ VALUE io_spec_rb_io_set_nonblock(VALUE self, VALUE io) { GetOpenFile(io, fp); rb_io_set_nonblock(fp); #ifdef F_GETFL - flags = fcntl(fp->fd, F_GETFL, 0); + flags = fcntl(io_spec_get_fd(io), F_GETFL, 0); return flags & O_NONBLOCK ? Qtrue : Qfalse; #else return Qfalse; @@ -228,15 +330,29 @@ static VALUE io_spec_errno_set(VALUE self, VALUE val) { } VALUE io_spec_mode_sync_flag(VALUE self, VALUE io) { +#ifdef RUBY_VERSION_IS_3_3 + if (rb_io_mode(io) & FMODE_SYNC) { +#else rb_io_t *fp; GetOpenFile(io, fp); if (fp->mode & FMODE_SYNC) { +#endif return Qtrue; } else { return Qfalse; } } +#if defined(RUBY_VERSION_IS_3_3) || defined(TRUFFLERUBY) +static VALUE io_spec_rb_io_mode(VALUE self, VALUE io) { + return INT2FIX(rb_io_mode(io)); +} + +static VALUE io_spec_rb_io_path(VALUE self, VALUE io) { + return rb_io_path(io); +} +#endif + void Init_io_spec(void) { VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject); rb_define_method(cls, "GetOpenFile_fd", io_spec_GetOpenFile_fd, 1); @@ -254,14 +370,26 @@ void Init_io_spec(void) { rb_define_method(cls, "rb_io_taint_check", io_spec_rb_io_taint_check, 1); rb_define_method(cls, "rb_io_wait_readable", io_spec_rb_io_wait_readable, 2); rb_define_method(cls, "rb_io_wait_writable", io_spec_rb_io_wait_writable, 1); +#ifdef RUBY_VERSION_IS_3_1 + rb_define_method(cls, "rb_io_maybe_wait_writable", io_spec_rb_io_maybe_wait_writable, 3); + rb_define_method(cls, "rb_io_maybe_wait_readable", io_spec_rb_io_maybe_wait_readable, 4); + rb_define_method(cls, "rb_io_maybe_wait", io_spec_rb_io_maybe_wait, 4); +#endif rb_define_method(cls, "rb_thread_wait_fd", io_spec_rb_thread_wait_fd, 1); rb_define_method(cls, "rb_thread_fd_writable", io_spec_rb_thread_fd_writable, 1); + rb_define_method(cls, "rb_thread_fd_select_read", io_spec_rb_thread_fd_select_read, 1); + rb_define_method(cls, "rb_thread_fd_select_write", io_spec_rb_thread_fd_select_write, 1); + rb_define_method(cls, "rb_thread_fd_select_timeout", io_spec_rb_thread_fd_select_timeout, 1); rb_define_method(cls, "rb_wait_for_single_fd", io_spec_rb_wait_for_single_fd, 4); rb_define_method(cls, "rb_io_binmode", io_spec_rb_io_binmode, 1); rb_define_method(cls, "rb_fd_fix_cloexec", io_spec_rb_fd_fix_cloexec, 1); rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3); rb_define_method(cls, "errno=", io_spec_errno_set, 1); rb_define_method(cls, "rb_io_mode_sync_flag", io_spec_mode_sync_flag, 1); +#if defined(RUBY_VERSION_IS_3_3) || defined(TRUFFLERUBY) + rb_define_method(cls, "rb_io_mode", io_spec_rb_io_mode, 1); + rb_define_method(cls, "rb_io_path", io_spec_rb_io_path, 1); +#endif } #ifdef __cplusplus |