about summary refs log tree commit homepage
path: root/ext
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-05-27 09:35:23 +0000
committerEric Wong <normalperson@yhbt.net>2010-05-27 09:37:56 +0000
commite60aebdd55da2db78780165656ba8c457ecbeb97 (patch)
tree75974a7aaf0a495a0d7b6056ef3f6ff26758c1f4 /ext
parentdfe29268314ea3fce7e7025ff9536821c6f60c9c (diff)
downloadruby_io_splice-e60aebdd55da2db78780165656ba8c457ecbeb97.tar.gz
This should be more convenient to use than having
to remember to call "fileno" every time...
Diffstat (limited to 'ext')
-rw-r--r--ext/io_splice/io_splice_ext.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c
index 3a1cf7a..6b27b59 100644
--- a/ext/io_splice/io_splice_ext.c
+++ b/ext/io_splice/io_splice_ext.c
@@ -10,6 +10,37 @@
 #include <limits.h>
 #include <alloca.h>
 
+#if ! HAVE_RB_IO_T
+#  define rb_io_t OpenFile
+#endif
+
+#ifdef GetReadFile
+#  define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
+#else
+#  if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
+#    define FPTR_TO_FD(fptr) fileno(fptr->f)
+#  else
+#    define FPTR_TO_FD(fptr) fptr->fd
+#  endif
+#endif
+
+static int my_fileno(VALUE io)
+{
+        rb_io_t *fptr;
+
+        for (;;) {
+                switch (TYPE(io)) {
+                case T_FIXNUM: return NUM2INT(io);
+                case T_FILE: {
+                        GetOpenFile(io, fptr);
+                        return FPTR_TO_FD(fptr);
+                }
+                default:
+                        io = rb_convert_type(io, T_FILE, "IO", "to_io");
+                        /* retry */
+                }
+        }
+}
 #ifndef HAVE_RB_THREAD_BLOCKING_REGION
 /* partial emulation of the 1.9 rb_thread_blocking_region under 1.8 */
 #  include <rubysig.h>
@@ -123,8 +154,8 @@ static VALUE my_splice(VALUE self,
         struct splice_args a = {
                 .off_in = NIL_P(off_in) ? NULL : (i = NUM2OFFT(off_in), &i),
                 .off_out = NIL_P(off_out) ? NULL : (o = NUM2OFFT(off_out), &o),
-                .fd_in = NUM2INT(fd_in),
-                .fd_out = NUM2INT(fd_out),
+                .fd_in = my_fileno(fd_in),
+                .fd_out = my_fileno(fd_out),
                 .len = (size_t)NUM2ULONG(len),
                 .flags = NUM2UINT(flags),
         };
@@ -177,8 +208,8 @@ static VALUE my_tee(VALUE self,
 {
         long n;
         struct tee_args a = {
-                .fd_in = NUM2INT(fd_in),
-                .fd_out = NUM2INT(fd_out),
+                .fd_in = my_fileno(fd_in),
+                .fd_out = my_fileno(fd_out),
                 .len = (size_t)NUM2ULONG(len),
                 .flags = NUM2UINT(flags),
         };
@@ -278,7 +309,7 @@ static VALUE my_vmsplice(VALUE self, VALUE fd, VALUE data, VALUE flags)
         struct vmsplice_args a;
 
         ARY2IOVEC(a.iov, a.nr_segs, left, data);
-        a.fd = NUM2INT(fd);
+        a.fd = my_fileno(fd);
         a.flags = NUM2UINT(flags);
 
         for (;;) {