about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2010-09-25 17:47:13 +0000
committerEric Wong <e@yhbt.net>2010-09-25 17:47:13 +0000
commitaf03e4471de3d3b91eec16e26e93a84d4a717116 (patch)
tree66d952790d43ea016f8676d188baf7077d5d5c48
parentdb53263856d864ba6273e6cac73011f699509d71 (diff)
downloadkgio-af03e4471de3d3b91eec16e26e93a84d4a717116.tar.gz
No point in cluttering up the meat of our code.
-rw-r--r--ext/kgio/kgio_ext.c139
-rw-r--r--ext/kgio/missing/accept4.h48
-rw-r--r--ext/kgio/my_fileno.h36
-rw-r--r--ext/kgio/nonblock.h15
-rw-r--r--ext/kgio/sock_for_fd.h66
5 files changed, 170 insertions, 134 deletions
diff --git a/ext/kgio/kgio_ext.c b/ext/kgio/kgio_ext.c
index 6dbccbc..d0632e3 100644
--- a/ext/kgio/kgio_ext.c
+++ b/ext/kgio/kgio_ext.c
@@ -14,61 +14,19 @@
 #include <arpa/inet.h>
 #include <assert.h>
 
-#ifndef SOCK_CLOEXEC
-#  if (FD_CLOEXEC == O_NONBLOCK)
-#    define SOCK_CLOEXEC 1
-#    define SOCK_NONBLOCK 2
-#  else
-#    define SOCK_CLOEXEC FD_CLOEXEC
-#    define SOCK_NONBLOCK O_NONBLOCK
-#  endif
-#endif
+#include "missing/accept4.h"
+#include "nonblock.h"
+#include "my_fileno.h"
+#include "sock_for_fd.h"
 
-static void set_nonblocking(int fd)
-{
-        int flags = fcntl(fd, F_GETFL);
-
-        if (flags == -1)
-                rb_sys_fail("fcntl(F_GETFL)");
-        if ((flags & O_NONBLOCK) == O_NONBLOCK)
-                return;
-        flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-        if (flags == -1)
-                rb_sys_fail("fcntl(F_SETFL)");
-}
-
-#ifndef HAVE_ACCEPT4
-/* accept4() is currently a Linux-only goodie */
-static int
-accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
-{
-        int fd = accept(sockfd, addr, addrlen);
-
-        if (fd >= 0) {
-                if ((flags & SOCK_CLOEXEC) == SOCK_CLOEXEC)
-                        (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
-
-                /*
-                 * Some systems inherit O_NONBLOCK across accept().
-                 * We also expect our users to use MSG_DONTWAIT
-                 * where possible, so fcntl() is completely unnecessary.
-                 */
-                if ((flags & SOCK_NONBLOCK) == SOCK_NONBLOCK)
-                        set_nonblocking(fd);
-                errno = 0;
-        }
-        return fd;
-}
-#endif /* !HAVE_ACCEPT4 */
 #if defined(__linux__)
-static int accept4_flags = SOCK_CLOEXEC;
-
 /*
  * we know MSG_DONTWAIT works properly on all stream sockets under Linux
  * we can define this macro for other platforms as people care and
  * notice.
  */
 #  define USE_MSG_DONTWAIT
+static int accept4_flags = SOCK_CLOEXEC;
 #else
 static int accept4_flags = SOCK_CLOEXEC | SOCK_NONBLOCK;
 #endif
@@ -79,78 +37,6 @@ static VALUE mKgio_WaitReadable, mKgio_WaitWritable;
 static ID io_wait_rd, io_wait_wr;
 static ID iv_kgio_addr, id_ruby;
 
-#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
-
-#if defined(MakeOpenFile) && \
-    defined(HAVE_RB_IO_T) && (HAVE_RB_IO_T == 1) && \
-    defined(HAVE_RB_IO_ASCII8BIT_BINMODE) && \
-    defined(HAVE_ST_FD) && \
-    defined(HAVE_ST_MODE)
-#  define SOCK_FOR_FD (19)
-#  define FMODE_NOREVLOOKUP 0x100
-#elif defined(MakeOpenFile) && \
-      defined(HAVE_RB_FDOPEN) && \
-      defined(HAVE_ST_F) && \
-      defined(HAVE_ST_F2) && \
-      defined(HAVE_ST_MODE)
-#  define SOCK_FOR_FD (18)
-#else
-#  define SOCK_FOR_FD (-1)
-#endif
-
-#if SOCK_FOR_FD == 19  /* modeled after ext/socket/init.c */
-static VALUE sock_for_fd(VALUE klass, int fd)
-{
-        VALUE sock = rb_obj_alloc(klass);
-        rb_io_t *fp;
-
-        MakeOpenFile(sock, fp);
-        fp->fd = fd;
-        fp->mode = FMODE_READWRITE|FMODE_DUPLEX|FMODE_NOREVLOOKUP;
-        rb_io_ascii8bit_binmode(sock);
-        rb_io_synchronized(fp);
-        return sock;
-}
-#elif SOCK_FOR_FD == 18 /* modeled after init_sock() in ext/socket/socket.c */
-static VALUE sock_for_fd(VALUE klass, int fd)
-{
-        VALUE sock = rb_obj_alloc(klass);
-        rb_io_t *fp;
-
-        MakeOpenFile(sock, fp);
-        fp->f = rb_fdopen(fd, "r");
-        fp->f2 = rb_fdopen(fd, "w");
-        fp->mode = FMODE_READWRITE;
-        rb_io_synchronized(fp);
-        return sock;
-}
-#else /* Rubinius, et al. */
-static ID id_for_fd;
-static VALUE sock_for_fd(VALUE klass, int fd)
-{
-        return rb_funcall(klass, id_for_fd, 1, INT2NUM(fd));
-}
-static void init_sock_for_fd(void)
-{
-        id_for_fd = rb_intern("for_fd");
-}
-#endif /* sock_for_fd */
-#if SOCK_FOR_FD > 0
-#  define init_sock_for_fd() if (0)
-#endif
-
 struct io_args {
         VALUE io;
         VALUE buf;
@@ -159,21 +45,6 @@ struct io_args {
         int fd;
 };
 
-static int my_fileno(VALUE io)
-{
-        rb_io_t *fptr;
-        int fd;
-
-        if (TYPE(io) != T_FILE)
-                io = rb_convert_type(io, T_FILE, "IO", "to_io");
-        GetOpenFile(io, fptr);
-        fd = FPTR_TO_FD(fptr);
-
-        if (fd < 0)
-                rb_raise(rb_eIOError, "closed stream");
-        return fd;
-}
-
 static int maybe_wait_readable(VALUE io)
 {
         if (io_wait_rd) {
diff --git a/ext/kgio/missing/accept4.h b/ext/kgio/missing/accept4.h
new file mode 100644
index 0000000..cd8be79
--- /dev/null
+++ b/ext/kgio/missing/accept4.h
@@ -0,0 +1,48 @@
+#ifndef HAVE_ACCEPT4
+#  ifndef _GNU_SOURCE
+#    define _GNU_SOURCE
+#  endif
+#  include <sys/types.h>
+#  include <sys/socket.h>
+#  ifndef SOCK_CLOEXEC
+#    if (FD_CLOEXEC == O_NONBLOCK)
+#      define SOCK_CLOEXEC 1
+#      define SOCK_NONBLOCK 2
+#    else
+#      define SOCK_CLOEXEC FD_CLOEXEC
+#      define SOCK_NONBLOCK O_NONBLOCK
+#    endif
+#  endif
+
+/* accept4() is currently a Linux-only goodie */
+static int
+accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
+{
+        int fd = accept(sockfd, addr, addrlen);
+
+        if (fd >= 0) {
+                if ((flags & SOCK_CLOEXEC) == SOCK_CLOEXEC)
+                        (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+                /*
+                 * Some systems inherit O_NONBLOCK across accept().
+                 * We also expect our users to use MSG_DONTWAIT under
+                 * Linux, so fcntl() is completely unnecessary
+                 * in most cases...
+                 */
+                if ((flags & SOCK_NONBLOCK) == SOCK_NONBLOCK) {
+                        int fl = fcntl(fd, F_GETFL);
+
+                        if ((fl & O_NONBLOCK) == 0)
+                                (void)fcntl(fd, F_SETFL, fl | O_NONBLOCK);
+                }
+
+                /*
+                 * nothing we can do about fcntl() errors in this wrapper
+                 * function, let the user (Ruby) code figure it out
+                 */
+                errno = 0;
+        }
+        return fd;
+}
+#endif /* !HAVE_ACCEPT4 */
diff --git a/ext/kgio/my_fileno.h b/ext/kgio/my_fileno.h
new file mode 100644
index 0000000..bdf1a5f
--- /dev/null
+++ b/ext/kgio/my_fileno.h
@@ -0,0 +1,36 @@
+#include <ruby.h>
+#ifdef HAVE_RUBY_IO_H
+#  include <ruby/io.h>
+#else
+#  include <stdio.h>
+#  include <rubyio.h>
+#endif
+
+#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;
+        int fd;
+
+        if (TYPE(io) != T_FILE)
+                io = rb_convert_type(io, T_FILE, "IO", "to_io");
+        GetOpenFile(io, fptr);
+        fd = FPTR_TO_FD(fptr);
+
+        if (fd < 0)
+                rb_raise(rb_eIOError, "closed stream");
+        return fd;
+}
diff --git a/ext/kgio/nonblock.h b/ext/kgio/nonblock.h
new file mode 100644
index 0000000..43de8cd
--- /dev/null
+++ b/ext/kgio/nonblock.h
@@ -0,0 +1,15 @@
+#include <ruby.h>
+#include <unistd.h>
+#include <fcntl.h>
+static void set_nonblocking(int fd)
+{
+        int flags = fcntl(fd, F_GETFL);
+
+        if (flags == -1)
+                rb_sys_fail("fcntl(F_GETFL)");
+        if ((flags & O_NONBLOCK) == O_NONBLOCK)
+                return;
+        flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+        if (flags == -1)
+                rb_sys_fail("fcntl(F_SETFL)");
+}
diff --git a/ext/kgio/sock_for_fd.h b/ext/kgio/sock_for_fd.h
new file mode 100644
index 0000000..db5cba5
--- /dev/null
+++ b/ext/kgio/sock_for_fd.h
@@ -0,0 +1,66 @@
+#include <ruby.h>
+#ifdef HAVE_RUBY_IO_H
+#  include <ruby/io.h>
+#else
+#  include <stdio.h>
+#  include <rubyio.h>
+#endif
+
+#if defined(MakeOpenFile) && \
+    defined(HAVE_RB_IO_T) && (HAVE_RB_IO_T == 1) && \
+    defined(HAVE_RB_IO_ASCII8BIT_BINMODE) && \
+    defined(HAVE_ST_FD) && \
+    defined(HAVE_ST_MODE)
+#  define SOCK_FOR_FD (19)
+#  define FMODE_NOREVLOOKUP 0x100
+#elif defined(MakeOpenFile) && \
+      (defined(OpenFile) || defined(HAVE_RB_IO_T)) && \
+      defined(HAVE_RB_FDOPEN) && \
+      defined(HAVE_ST_F) && \
+      defined(HAVE_ST_F2) && \
+      defined(HAVE_ST_MODE)
+#  define SOCK_FOR_FD (18)
+#else
+#  define SOCK_FOR_FD (-1)
+#endif
+
+#if SOCK_FOR_FD == 19  /* modeled after ext/socket/init.c */
+static VALUE sock_for_fd(VALUE klass, int fd)
+{
+        VALUE sock = rb_obj_alloc(klass);
+        rb_io_t *fp;
+
+        MakeOpenFile(sock, fp);
+        fp->fd = fd;
+        fp->mode = FMODE_READWRITE|FMODE_DUPLEX|FMODE_NOREVLOOKUP;
+        rb_io_ascii8bit_binmode(sock);
+        rb_io_synchronized(fp);
+        return sock;
+}
+#elif SOCK_FOR_FD == 18 /* modeled after init_sock() in ext/socket/socket.c */
+static VALUE sock_for_fd(VALUE klass, int fd)
+{
+        VALUE sock = rb_obj_alloc(klass);
+        OpenFile *fp;
+
+        MakeOpenFile(sock, fp);
+        fp->f = rb_fdopen(fd, "r");
+        fp->f2 = rb_fdopen(fd, "w");
+        fp->mode = FMODE_READWRITE;
+        rb_io_synchronized(fp);
+        return sock;
+}
+#else /* Rubinius, et al. */
+static ID id_for_fd;
+static VALUE sock_for_fd(VALUE klass, int fd)
+{
+        return rb_funcall(klass, id_for_fd, 1, INT2NUM(fd));
+}
+static void init_sock_for_fd(void)
+{
+        id_for_fd = rb_intern("for_fd");
+}
+#endif /* sock_for_fd */
+#if SOCK_FOR_FD > 0
+#  define init_sock_for_fd() if (0)
+#endif