diff options
author | Eric Wong <e@yhbt.net> | 2010-09-25 17:47:13 +0000 |
---|---|---|
committer | Eric Wong <e@yhbt.net> | 2010-09-25 17:47:13 +0000 |
commit | af03e4471de3d3b91eec16e26e93a84d4a717116 (patch) | |
tree | 66d952790d43ea016f8676d188baf7077d5d5c48 | |
parent | db53263856d864ba6273e6cac73011f699509d71 (diff) | |
download | kgio-af03e4471de3d3b91eec16e26e93a84d4a717116.tar.gz |
No point in cluttering up the meat of our code.
-rw-r--r-- | ext/kgio/kgio_ext.c | 139 | ||||
-rw-r--r-- | ext/kgio/missing/accept4.h | 48 | ||||
-rw-r--r-- | ext/kgio/my_fileno.h | 36 | ||||
-rw-r--r-- | ext/kgio/nonblock.h | 15 | ||||
-rw-r--r-- | ext/kgio/sock_for_fd.h | 66 |
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 |