src/server/util/io.c

branch
aio
changeset 172
5580517faafc
parent 147
d050449c3b9e
child 193
aa8393527b1e
--- a/src/server/util/io.c	Sat Feb 04 16:42:11 2017 +0100
+++ b/src/server/util/io.c	Sat Feb 18 13:27:25 2017 +0100
@@ -64,6 +64,7 @@
 #include "../daemon/vfs.h"
 #include "io.h"
 #include "pool.h"
+#include "../daemon/event.h"
 #include "ucx/utils.h"
 
 IOStream native_io_funcs = {
@@ -72,7 +73,10 @@
     (io_read_f)net_sys_read,
     (io_sendfile_f)NET_SYS_SENDFILE,
     (io_close_f)net_sys_close,
-    NULL
+    NULL,
+    (io_setmode_f)net_sys_setmode,
+    (io_poll_f)net_sys_poll,
+    0
 };
 
 IOStream http_io_funcs = {
@@ -81,7 +85,10 @@
     (io_read_f)net_http_read,
     (io_sendfile_f)net_http_sendfile,
     (io_close_f)net_http_close,
-    (io_finish_f)net_http_finish
+    (io_finish_f)net_http_finish,
+    (io_setmode_f)net_http_setmode,
+    (io_poll_f)net_http_poll,
+    0
 };
 
 IOStream ssl_io_funcs = {
@@ -90,7 +97,10 @@
     (io_read_f)net_ssl_read,
     NULL,
     (io_close_f)net_ssl_close,
-    (io_finish_f)net_ssl_finish
+    (io_finish_f)net_ssl_finish,
+    (io_setmode_f)net_ssl_setmode,
+    (io_poll_f)net_ssl_poll,
+    0
 };
 
 
@@ -170,6 +180,34 @@
     close(st->fd);
 }
 
+void net_sys_setmode(SysStream *st, int mode) {
+    int flags;
+    if (-1 == (flags = fcntl(st->fd, F_GETFL, 0))) {
+        flags = 0;
+    }
+    if(mode == IO_MODE_BLOCKING) {
+        if (fcntl(st->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) {
+            perror("fcntl");
+            // TODO: error
+        }
+    } else if(mode == IO_MODE_NONBLOCKING) {
+        if (fcntl(st->fd, F_SETFL, flags | O_NONBLOCK) != 0) {
+            perror("fcntl");
+            // TODO: error
+        }
+    }
+}
+
+int net_sys_poll(SysStream *st, EventHandler *ev, int events, Event *cb) {
+    switch(events) {
+        default: return -1;
+        case IO_POLL_NONE: return ev_remove_poll(ev, st->fd);
+        case IO_POLL_IN: return ev_pollin(ev, st->fd, cb);
+        case IO_POLL_OUT: return ev_pollout(ev, st->fd, cb);
+        case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement
+    }
+}
+
 #elif defined(XP_WIN32)
 
 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) {
@@ -287,6 +325,14 @@
     }
 }
 
+void net_http_setmode(HttpStream *st, int mode) {
+    st->fd->setmode(st->fd, mode);
+}
+
+int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb) {
+    return st->fd->poll(st->fd, ev, events, cb);
+}
+
 
 /*
  * SSLStream implementation
@@ -341,6 +387,34 @@
     
 }
 
+void net_ssl_setmode(SSLStream *st, int mode) {
+    int flags;
+    if (-1 == (flags = fcntl(SSL_get_fd(st->ssl), F_GETFL, 0))) {
+        flags = 0;
+    }
+    if(mode == IO_MODE_BLOCKING) {
+        if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags & ~O_NONBLOCK) != 0) {
+            perror("fcntl");
+            // TODO: error
+        }
+    } else if(mode == IO_MODE_NONBLOCKING) {
+        if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags | O_NONBLOCK) != 0) {
+            perror("fcntl");
+            // TODO: error
+        }
+    }
+}
+
+int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb) {
+    int fd = SSL_get_fd(st->ssl);
+    switch(events) {
+        default: return -1;
+        case IO_POLL_NONE: return ev_remove_poll(ev, fd);
+        case IO_POLL_IN: return ev_pollin(ev, fd, cb);
+        case IO_POLL_OUT: return ev_pollout(ev, fd, cb);
+        case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement
+    }
+}
 
 /* -------------------- public nsapi network functions -------------------- */
 
@@ -348,6 +422,9 @@
     ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes);
     if(r == 0) {
         return IO_EOF;
+    } else if(r < 0) {
+        ((IOStream*)fd)->io_errno = errno;
+        return IO_ERROR;
     }
     return r;
 }
@@ -355,6 +432,7 @@
 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) {
     ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes);
     if(r < 0) {
+        ((IOStream*)fd)->io_errno = errno;
         return IO_ERROR;
     }  
     return r;
@@ -363,6 +441,7 @@
 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) {
     ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt);
     if(r < 0) {
+        ((IOStream*)fd)->io_errno = errno;
         return IO_ERROR;
     }
     return r;
@@ -375,6 +454,9 @@
     ssize_t r = net_write(fd, buf.ptr, buf.length);
     free(buf.ptr);
     va_end(arg);
+    if(r < 0) {
+        ((IOStream*)fd)->io_errno = errno;
+    }
     return r;
 }
 
@@ -383,14 +465,15 @@
     if(out->sendfile && sfd->fd && sfd->fd->fd != -1) {
         ssize_t r = out->sendfile(fd, sfd);
         if(r < 0) {
+            out->io_errno = errno;
             return IO_ERROR;
         }
+        return r;
     } else {
         // stream/file does not support sendfile
         // do regular copy
         return net_fallback_sendfile(out, sfd);
     }
-    return IO_ERROR;
 }
 
 // private
@@ -418,12 +501,14 @@
         hlen -= r;
         if(r <= 0) {
             free(buf);
+            fd->io_errno = errno;
             return IO_ERROR;
         }
     }
 
     if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) {
         free(buf);
+        fd->io_errno = errno;
         return IO_ERROR;
     }
 
@@ -442,6 +527,7 @@
     }
     free(buf);
     if(length > 0) {
+        fd->io_errno = errno;
         return IO_ERROR;
     }
 
@@ -450,6 +536,7 @@
         trailer += r;
         tlen -= r;
         if(r <= 0) {
+            fd->io_errno = errno;
             return IO_ERROR;
         }
     }
@@ -466,6 +553,17 @@
     ((IOStream*)fd)->close(fd);
 }
 
+int net_setnonblock(SYS_NETFD fd, int nonblock) {
+    ((IOStream*)fd)->setmode(
+            fd,
+            nonblock ? IO_MODE_NONBLOCKING : IO_MODE_BLOCKING);
+    return 0;
+}
+
+int net_errno(SYS_NETFD fd) {
+    return ((IOStream*)fd)->io_errno;
+}
+
 // private
 void net_finish(SYS_NETFD fd) {
     ((IOStream*)fd)->finish(fd);

mercurial