aboutsummaryrefslogtreecommitdiffstats
path: root/spec/rubyspec/optional/capi/ext/io_spec.c
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-07 12:04:49 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-07 12:04:49 +0000
commita3736e97a6ca517c2cd7d3d93a8f2ef86e39e5b5 (patch)
tree9eef7f720314ebaff56845a74e203770e62284e4 /spec/rubyspec/optional/capi/ext/io_spec.c
parent52df1d0d3370919711c0577aaa42d1a864709885 (diff)
downloadruby-a3736e97a6ca517c2cd7d3d93a8f2ef86e39e5b5.tar.gz
Add in-tree mspec and ruby/spec
* For easier modifications of ruby/spec by MRI developers. * .gitignore: track changes under spec. * spec/mspec, spec/rubyspec: add in-tree mspec and ruby/spec. These files can therefore be updated like any other file in MRI. Instructions are provided in spec/README. [Feature #13156] [ruby-core:79246] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/rubyspec/optional/capi/ext/io_spec.c')
-rw-r--r--spec/rubyspec/optional/capi/ext/io_spec.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/spec/rubyspec/optional/capi/ext/io_spec.c b/spec/rubyspec/optional/capi/ext/io_spec.c
new file mode 100644
index 0000000000..982284deab
--- /dev/null
+++ b/spec/rubyspec/optional/capi/ext/io_spec.c
@@ -0,0 +1,296 @@
+#include "ruby.h"
+#include "rubyspec.h"
+#include "ruby/io.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static int set_non_blocking(int fd) {
+ int flags;
+#if defined(O_NONBLOCK)
+ if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
+ flags = 0;
+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+#else
+ flags = 1;
+ return ioctl(fd, FIOBIO, &flags);
+#endif
+}
+
+#ifdef HAVE_GET_OPEN_FILE
+static int io_spec_get_fd(VALUE io) {
+ rb_io_t* fp;
+ GetOpenFile(io, fp);
+ return fp->fd;
+}
+
+VALUE io_spec_GetOpenFile_fd(VALUE self, VALUE io) {
+ return INT2NUM(io_spec_get_fd(io));
+}
+#endif
+
+#ifdef HAVE_RB_IO_ADDSTR
+VALUE io_spec_rb_io_addstr(VALUE self, VALUE io, VALUE str) {
+ return rb_io_addstr(io, str);
+}
+#endif
+
+#ifdef HAVE_RB_IO_PRINTF
+VALUE io_spec_rb_io_printf(VALUE self, VALUE io, VALUE ary) {
+ long argc = RARRAY_LEN(ary);
+ VALUE *argv = alloca(sizeof(VALUE) * argc);
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ argv[i] = rb_ary_entry(ary, i);
+ }
+
+ return rb_io_printf((int)argc, argv, io);
+}
+#endif
+
+#ifdef HAVE_RB_IO_PRINT
+VALUE io_spec_rb_io_print(VALUE self, VALUE io, VALUE ary) {
+ long argc = RARRAY_LEN(ary);
+ VALUE *argv = alloca(sizeof(VALUE) * argc);
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ argv[i] = rb_ary_entry(ary, i);
+ }
+
+ return rb_io_print((int)argc, argv, io);
+}
+#endif
+
+#ifdef HAVE_RB_IO_PUTS
+VALUE io_spec_rb_io_puts(VALUE self, VALUE io, VALUE ary) {
+ long argc = RARRAY_LEN(ary);
+ VALUE *argv = alloca(sizeof(VALUE) * argc);
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ argv[i] = rb_ary_entry(ary, i);
+ }
+
+ return rb_io_puts((int)argc, argv, io);
+}
+#endif
+
+#ifdef HAVE_RB_IO_WRITE
+VALUE io_spec_rb_io_write(VALUE self, VALUE io, VALUE str) {
+ return rb_io_write(io, str);
+}
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_IO
+VALUE io_spec_rb_io_check_io(VALUE self, VALUE io) {
+ return rb_io_check_io(io);
+}
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_READABLE
+VALUE io_spec_rb_io_check_readable(VALUE self, VALUE io) {
+ rb_io_t* fp;
+ GetOpenFile(io, fp);
+ rb_io_check_readable(fp);
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_WRITABLE
+VALUE io_spec_rb_io_check_writable(VALUE self, VALUE io) {
+ rb_io_t* fp;
+ GetOpenFile(io, fp);
+ rb_io_check_writable(fp);
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_CLOSED
+VALUE io_spec_rb_io_check_closed(VALUE self, VALUE io) {
+ rb_io_t* fp;
+ GetOpenFile(io, fp);
+ rb_io_check_closed(fp);
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_IO_TAINT_CHECK
+VALUE io_spec_rb_io_taint_check(VALUE self, VALUE io) {
+ /*rb_io_t* fp;
+ GetOpenFile(io, fp);*/
+ rb_io_taint_check(io);
+ return io;
+}
+#endif
+
+typedef int wait_bool;
+#define wait_bool_to_ruby_bool(x) (x ? Qtrue : Qfalse)
+
+#ifdef HAVE_RB_IO_WAIT_READABLE
+#define RB_IO_WAIT_READABLE_BUF 13
+
+VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
+ int fd = io_spec_get_fd(io);
+ char buf[RB_IO_WAIT_READABLE_BUF];
+ wait_bool ret;
+
+ set_non_blocking(fd);
+
+ if(RTEST(read_p)) {
+ rb_ivar_set(self, rb_intern("@write_data"), Qtrue);
+ if(read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
+ return Qnil;
+ }
+ }
+
+ ret = rb_io_wait_readable(fd);
+
+ if(RTEST(read_p)) {
+ if(read(fd, buf, RB_IO_WAIT_READABLE_BUF) != 13) {
+ return Qnil;
+ }
+ rb_ivar_set(self, rb_intern("@read_data"),
+ rb_str_new(buf, RB_IO_WAIT_READABLE_BUF));
+ }
+
+ return wait_bool_to_ruby_bool(ret);
+}
+#endif
+
+#ifdef HAVE_RB_IO_WAIT_WRITABLE
+VALUE io_spec_rb_io_wait_writable(VALUE self, VALUE io) {
+ wait_bool ret;
+ ret = rb_io_wait_writable(io_spec_get_fd(io));
+ return wait_bool_to_ruby_bool(ret);
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_WAIT_FD
+VALUE io_spec_rb_thread_wait_fd(VALUE self, VALUE io) {
+ rb_thread_wait_fd(io_spec_get_fd(io));
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_FD_WRITABLE
+VALUE io_spec_rb_thread_fd_writable(VALUE self, VALUE io) {
+ rb_thread_fd_writable(io_spec_get_fd(io));
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_IO_BINMODE
+VALUE io_spec_rb_io_binmode(VALUE self, VALUE io) {
+ return rb_io_binmode(io);
+}
+#endif
+
+#ifdef HAVE_RB_FD_FIX_CLOEXEC
+VALUE io_spec_rb_fd_fix_cloexec(VALUE self, VALUE io) {
+ rb_fd_fix_cloexec(io_spec_get_fd(io));
+ return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_CLOEXEC_OPEN
+VALUE io_spec_rb_cloexec_open(VALUE self, VALUE path, VALUE flags, VALUE mode) {
+ const char *pathname = StringValuePtr(path);
+ int fd = rb_cloexec_open(pathname, FIX2INT(flags), FIX2INT(mode));
+ return rb_funcall(rb_cIO, rb_intern("for_fd"), 1, INT2FIX(fd));
+}
+#endif
+
+#ifdef HAVE_RB_IO_CLOSE
+VALUE io_spec_rb_io_close(VALUE self, VALUE io) {
+ return rb_io_close(io);
+}
+#endif
+
+void Init_io_spec(void) {
+ VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject);
+
+#ifdef HAVE_GET_OPEN_FILE
+ rb_define_method(cls, "GetOpenFile_fd", io_spec_GetOpenFile_fd, 1);
+#endif
+
+#ifdef HAVE_RB_IO_ADDSTR
+ rb_define_method(cls, "rb_io_addstr", io_spec_rb_io_addstr, 2);
+#endif
+
+#ifdef HAVE_RB_IO_PRINTF
+ rb_define_method(cls, "rb_io_printf", io_spec_rb_io_printf, 2);
+#endif
+
+#ifdef HAVE_RB_IO_PRINT
+ rb_define_method(cls, "rb_io_print", io_spec_rb_io_print, 2);
+#endif
+
+#ifdef HAVE_RB_IO_PUTS
+ rb_define_method(cls, "rb_io_puts", io_spec_rb_io_puts, 2);
+#endif
+
+#ifdef HAVE_RB_IO_WRITE
+ rb_define_method(cls, "rb_io_write", io_spec_rb_io_write, 2);
+#endif
+
+#ifdef HAVE_RB_IO_CLOSE
+ rb_define_method(cls, "rb_io_close", io_spec_rb_io_close, 1);
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_IO
+ rb_define_method(cls, "rb_io_check_io", io_spec_rb_io_check_io, 1);
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_READABLE
+ rb_define_method(cls, "rb_io_check_readable", io_spec_rb_io_check_readable, 1);
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_WRITABLE
+ rb_define_method(cls, "rb_io_check_writable", io_spec_rb_io_check_writable, 1);
+#endif
+
+#ifdef HAVE_RB_IO_CHECK_CLOSED
+ rb_define_method(cls, "rb_io_check_closed", io_spec_rb_io_check_closed, 1);
+#endif
+
+#ifdef HAVE_RB_IO_TAINT_CHECK
+ rb_define_method(cls, "rb_io_taint_check", io_spec_rb_io_taint_check, 1);
+#endif
+
+#ifdef HAVE_RB_IO_WAIT_READABLE
+ rb_define_method(cls, "rb_io_wait_readable", io_spec_rb_io_wait_readable, 2);
+#endif
+
+#ifdef HAVE_RB_IO_WAIT_WRITABLE
+ rb_define_method(cls, "rb_io_wait_writable", io_spec_rb_io_wait_writable, 1);
+#endif
+
+#ifdef HAVE_RB_THREAD_WAIT_FD
+ rb_define_method(cls, "rb_thread_wait_fd", io_spec_rb_thread_wait_fd, 1);
+#endif
+
+#ifdef HAVE_RB_THREAD_FD_WRITABLE
+ rb_define_method(cls, "rb_thread_fd_writable", io_spec_rb_thread_fd_writable, 1);
+#endif
+
+#ifdef HAVE_RB_IO_BINMODE
+ rb_define_method(cls, "rb_io_binmode", io_spec_rb_io_binmode, 1);
+#endif
+
+#ifdef HAVE_RB_FD_FIX_CLOEXEC
+ rb_define_method(cls, "rb_fd_fix_cloexec", io_spec_rb_fd_fix_cloexec, 1);
+#endif
+
+#ifdef HAVE_RB_CLOEXEC_OPEN
+ rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif