summaryrefslogtreecommitdiff
path: root/ext/io/nonblock
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-14 12:53:23 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-14 12:53:23 +0000
commitc749e4fca225cd00f5be15f6fe6e4538a6c29413 (patch)
treee2e0a04f2ae9a00e205c4d08a44b0823bd6937a2 /ext/io/nonblock
parent6a3931e0f630f56d4acd2b232f58c0225f03f52b (diff)
* ext/io/nonblock: moved from ext/io/wait/lib.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/io/nonblock')
-rw-r--r--ext/io/nonblock/extconf.rb8
-rw-r--r--ext/io/nonblock/nonblock.c108
2 files changed, 116 insertions, 0 deletions
diff --git a/ext/io/nonblock/extconf.rb b/ext/io/nonblock/extconf.rb
new file mode 100644
index 00000000000..aecdc16cea7
--- /dev/null
+++ b/ext/io/nonblock/extconf.rb
@@ -0,0 +1,8 @@
+require 'mkmf'
+target = "io/nonblock"
+
+hdr = %w"fcntl.h"
+if have_macro("O_NONBLOCK", hdr) and
+ (have_macro("F_GETFL", hdr) or have_macro("F_SETFL", hdr))
+ create_makefile(target)
+end
diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c
new file mode 100644
index 00000000000..d7e1ac8e016
--- /dev/null
+++ b/ext/io/nonblock/nonblock.c
@@ -0,0 +1,108 @@
+/**********************************************************************
+
+ io/wait.c -
+
+ $Author$
+ created at: Tue Jul 14 21:53:18 2009
+
+ All the files in this distribution are covered under the Ruby's
+ license (see the file COPYING).
+
+**********************************************************************/
+
+#include "ruby.h"
+#include "ruby/io.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+
+#ifdef F_GETFL
+static int
+io_nonblock_mode(int fd)
+{
+ int f = fcntl(fd, F_GETFL);
+ if (f == -1) rb_sys_fail(0);
+ return f;
+}
+#else
+#define io_nonblock_mode(fd) ((void)(fd), 0)
+#endif
+
+#ifdef F_GETFL
+static VALUE
+rb_io_nonblock_p(VALUE io)
+{
+ rb_io_t *fptr;
+ GetOpenFile(io, fptr);
+ if (io_nonblock_mode(fptr->fd) & O_NONBLOCK)
+ return Qtrue;
+ return Qfalse;
+}
+#else
+#define rb_io_nonblock_p rb_f_notimplement
+#endif
+
+#ifdef F_SETFL
+static void
+io_nonblock_set(int fd, int f, int nb)
+{
+ if (nb)
+ f |= O_NONBLOCK;
+ else
+ f &= ~O_NONBLOCK;
+ if (fcntl(fd, F_SETFL, f) == -1)
+ rb_sys_fail(0);
+}
+
+static VALUE
+rb_io_nonblock_set(VALUE io, VALUE nb)
+{
+ rb_io_t *fptr;
+ GetOpenFile(io, fptr);
+ io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb));
+ return io;
+}
+
+static VALUE
+io_nonblock_restore(VALUE arg)
+{
+ int *restore = (int *)arg;
+ if (fcntl(restore[0], F_SETFL, restore[1]) == -1)
+ rb_sys_fail(0);
+ return Qnil;
+}
+
+static VALUE
+rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
+{
+ int nb = 1;
+ rb_io_t *fptr;
+ int f, restore[2];
+
+ GetOpenFile(io, fptr);
+ if (argc > 0) {
+ VALUE v;
+ rb_scan_args(argc, argv, "01", &v);
+ nb = RTEST(v);
+ }
+ f = io_nonblock_mode(fptr->fd);
+ restore[0] = fptr->fd;
+ restore[1] = f;
+ io_nonblock_set(fptr->fd, f, nb);
+ return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
+}
+#else
+#define rb_io_nonblock_set rb_f_notimplement
+#define rb_io_nonblock_block rb_f_notimplement
+#endif
+
+void
+Init_nonblock(void)
+{
+ VALUE io = rb_cIO;
+
+ rb_define_method(io, "nonblock?", rb_io_nonblock_p, 0);
+ rb_define_method(io, "nonblock=", rb_io_nonblock_set, 1);
+ rb_define_method(io, "nonblock", rb_io_nonblock_block, -1);
+}