about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2010-09-27 16:56:13 +0000
committerEric Wong <e@yhbt.net>2010-09-27 18:26:56 +0000
commit5123d66fe0b2dad67539a20fe5b91f5b9afd814a (patch)
treecbf1daefece3786fa6c89b104392c90b34a1ba05
parent6c818b0b6f76ef733679bcea1024142b4ef3ce00 (diff)
downloadkgio-5123d66fe0b2dad67539a20fe5b91f5b9afd814a.tar.gz
Some Ruby implementations (Rubinius) may call lseek
and clobber the intended errno when looking up the
open file, causing rb_io_wait_* functions to fail.
-rw-r--r--ext/kgio/kgio_ext.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/ext/kgio/kgio_ext.c b/ext/kgio/kgio_ext.c
index faa25ff..f717db5 100644
--- a/ext/kgio/kgio_ext.c
+++ b/ext/kgio/kgio_ext.c
@@ -51,25 +51,21 @@ struct accept_args {
         socklen_t *addrlen;
 };
 
-static void wait_readable(VALUE io)
+static void wait_readable(VALUE io, int fd)
 {
         if (io_wait_rd) {
                 (void)rb_funcall(io, io_wait_rd, 0, 0);
         } else {
-                int fd = my_fileno(io);
-
                 if (!rb_io_wait_readable(fd))
                         rb_sys_fail("wait readable");
         }
 }
 
-static void wait_writable(VALUE io)
+static void wait_writable(VALUE io, int fd)
 {
         if (io_wait_wr) {
                 (void)rb_funcall(io, io_wait_wr, 0, 0);
         } else {
-                int fd = my_fileno(io);
-
                 if (!rb_io_wait_writable(fd))
                         rb_sys_fail("wait writable");
         }
@@ -100,7 +96,7 @@ static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
                 rb_str_set_len(a->buf, 0);
                 if (errno == EAGAIN) {
                         if (io_wait) {
-                                wait_readable(a->io);
+                                wait_readable(a->io, a->fd);
                                 return -1;
                         } else {
                                 a->buf = mKgio_WaitReadable;
@@ -202,7 +198,7 @@ static int write_check(struct io_args *a, long n, const char *msg, int io_wait)
                         return -1;
                 if (errno == EAGAIN) {
                         if (io_wait) {
-                                wait_writable(a->io);
+                                wait_writable(a->io, a->fd);
                                 return -1;
                         } else {
                                 a->buf = mKgio_WaitWritable;
@@ -586,7 +582,7 @@ my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
 
                         if (io_wait) {
                                 errno = EAGAIN;
-                                wait_writable(io);
+                                wait_writable(io, fd);
                         }
                         return io;
                 }