]> git.pond.sub.org Git - empserver/commitdiff
[_WIN32] (readv, writev, iovec): New. POSIX equivalents.
authorRon Koenderink <rkoenderink@yahoo.ca>
Thu, 16 Aug 2007 21:43:20 +0000 (21:43 +0000)
committerRon Koenderink <rkoenderink@yahoo.ca>
Thu, 16 Aug 2007 21:43:20 +0000 (21:43 +0000)
(ioq_makeiov, ioqtoiov): Compile unconditionally.
(io_output): Use POSIX code unconditionally.
[_WIN32] (ioq_makebuf): Remove.

include/ioqueue.h
src/lib/gen/io.c
src/lib/gen/ioqueue.c
src/lib/w32/posixio.c
src/lib/w32/sys/uio.h [new file with mode: 0644]

index 0049be201c7aa3124d144be4746fc8ee9b977204..8aaf1561d2ec2410fa027d0f53c37047d841c2b3 100644 (file)
@@ -56,11 +56,7 @@ struct ioqueue {
 extern struct ioqueue *ioq_create(int size);
 extern void ioq_destroy(struct ioqueue *ioq);
 extern void ioq_drain(struct ioqueue *ioq);
-#if defined (_WIN32)
-extern int ioq_makebuf(struct ioqueue *ioq, char *pBuf, int nBufLen);
-#else
 extern int ioq_makeiov(struct ioqueue *ioq, struct iovec *iov, int cc);
-#endif
 extern int ioq_peek(struct ioqueue *ioq, char *buf, int cc);
 extern int ioq_dequeue(struct ioqueue *ioq, int cc);
 extern void ioq_append(struct ioqueue *ioq, char *buf, int cc);
index 61c21d91d2df36ba9a0d616171e6855e197e534e..ab2bebda4b8b9a62e526ca79c7ad2c78c858d805 100644 (file)
@@ -45,8 +45,8 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <sys/types.h>
-#if !defined(_WIN32)
 #include <sys/uio.h>
+#if !defined(_WIN32)
 #include <sys/file.h>
 #endif
 #include <sys/socket.h>
@@ -166,11 +166,7 @@ io_outputwaiting(struct iop *iop)
 int
 io_output(struct iop *iop, int waitforoutput)
 {
-#if !defined(_WIN32)
     struct iovec iov[16];
-#else
-    char buf[IO_BUFSIZE];
-#endif
     int cc;
     int n;
     int remain;
@@ -187,15 +183,10 @@ io_output(struct iop *iop, int waitforoutput)
     if (iop->flags & IO_ERROR)
        return -1;
 
-#if !defined(_WIN32)
     /* make the iov point to the data in the queue. */
     /* I.E., each of the elements in the queue. */
     /* returns the number of elements in the iov. */
     n = ioq_makeiov(iop->output, iov, IO_BUFSIZE);
-#else
-    /* Make a buffer containing the output to write. */
-    n = ioq_makebuf(iop->output, buf, sizeof(buf));
-#endif
 
     if (n <= 0) {
        return 0;
@@ -209,11 +200,7 @@ io_output(struct iop *iop, int waitforoutput)
     }
 
     /* Do the actual write. */
-#if !defined(_WIN32)
     cc = writev(iop->fd, iov, n);
-#else
-    cc = write(iop->fd, buf, n);
-#endif
 
     /* if it failed.... */
     if (cc < 0) {
index 18cf1b5b8b1b24034c4b0caa868245ca2cfbd004..926c0f55f03ee3480b81427f9eb88ca8d704ff68 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#if !defined(_WIN32)
 #include <sys/uio.h>
-#endif
 #include "ioqueue.h"
 #include "misc.h"
 #include "queue.h"
 
 static int ioqtocbuf(struct ioqueue *ioq, char *buf, int cc, int stopc);
-#if !defined(_WIN32)
 static int ioqtoiov(struct ioqueue *ioq, struct iovec *iov, int max);
-#endif
 static int ioqtobuf(struct ioqueue *ioq, char *buf, int cc);
 static int appendcc(struct ioqueue *ioq, char *buf, int cc);
 static int removecc(struct ioqueue *ioq, int cc);
@@ -101,7 +97,6 @@ ioq_drain(struct ioqueue *ioq)
  * iovec, but don't actually dequeue the data.
  * return # of iovec initialized.
  */
-#if !defined(_WIN32)
 int
 ioq_makeiov(struct ioqueue *ioq, struct iovec *iov, int cc)
 {
@@ -109,7 +104,6 @@ ioq_makeiov(struct ioqueue *ioq, struct iovec *iov, int cc)
        return 0;
     return ioqtoiov(ioq, iov, cc);
 }
-#endif
 
 /*
  * Copy the specified number of characters into the buffer
@@ -247,7 +241,6 @@ ioqtocbuf(struct ioqueue *ioq, char *buf, int cc, int stopc)
  * initialize an iovec to point at max bytes worth
  * of data from the ioqueue.
  */
-#if !defined(_WIN32)
 static int
 ioqtoiov(struct ioqueue *ioq, struct iovec *iov, int max)
 {
@@ -274,7 +267,6 @@ ioqtoiov(struct ioqueue *ioq, struct iovec *iov, int max)
     }
     return niov;
 }
-#endif
 
 /*
  * append a buffer to the end of the ioq.
@@ -356,47 +348,3 @@ removecc(struct ioqueue *ioq, int cc)
     ioq->cc -= nbytes;
     return nbytes;
 }
-
-#if defined(_WIN32)
-/*
- * Make an (output) buffer up to the
- * maximum size of the buffer.
- *
- * We don't free the bytes...
- */
-int
-ioq_makebuf(struct ioqueue *ioq, char *pBuf, int nBufLen)
-{
-    struct io *io;
-    struct emp_qelem *qp;
-    struct emp_qelem *head;
-    int nbytes;
-    int nleft;
-    int ncopied;
-    char *offset;
-
-    ncopied = 0;
-    nleft = nBufLen;
-    offset = pBuf;
-    head = &ioq->list.queue;
-
-    for (qp = head->q_forw; (qp != head) && (nleft > 0); qp = qp->q_forw) {
-       io = (struct io *)qp;
-       nbytes = io->nbytes - io->offset;
-       if (nbytes < 0) {
-           /* Paranoid check for bad buffer. */
-           continue;
-       }
-
-       /* too many bytes, wait till next time. */
-       if (nbytes > nleft)
-           break;
-
-       memcpy(offset, io->data + io->offset, nbytes);
-       offset += nbytes;
-       nleft -= nbytes;
-       ncopied += nbytes;
-    }
-    return ncopied;
-}
-#endif /* _WIN32 */
index d7e88b63ccbb24997e7036f1a5a1c0c6343025ff..b031ee288f80f11f8b3855fcc2f6a2101d74a6e6 100644 (file)
@@ -54,6 +54,7 @@
 #include <errno.h>
 
 #include "unistd.h"
+#include "sys/uio.h"
 #include "empio.h"
 #include "prototypes.h"
 
@@ -445,6 +446,51 @@ posix_read(int fd, void *buffer, unsigned int count)
        _read(handle, buffer, count))
 }
 
+/*
+ * POSIX equivalent for readv
+ * Modelled after the GNU's libc/sysdeps/posix/readv.c
+ */
+ssize_t
+readv(int fd, const struct iovec *iov, int iovcnt)
+{
+    int i;
+    unsigned char *buffer, *buffer_location;
+    size_t total_bytes = 0;
+    int bytes_read;
+    size_t bytes_left;
+
+    for (i = 0; i < iovcnt; i++) {
+       total_bytes += iov[i].iov_len;
+    }
+
+    buffer = malloc(total_bytes);
+    if (buffer == NULL)
+       return -1;
+
+    bytes_read = posix_read(fd, buffer, total_bytes);
+    if (bytes_read <= 0) {
+       free(buffer);
+       return -1;
+    }
+
+    bytes_left = bytes_read;
+    buffer_location = buffer;
+    for (i = 0; i < iovcnt; i++) {
+       size_t copy = MIN(iov[i].iov_len, bytes_left);
+
+       memcpy(iov[i].iov_base, buffer_location, copy);
+
+       buffer_location += copy;
+       bytes_left -= copy;
+       if (bytes_left == 0)
+           break;
+    }
+
+    free(buffer);
+
+    return bytes_read;
+}
+
 /*
  * POSIX equivalent for write().
  */
@@ -455,6 +501,43 @@ posix_write(int fd, const void *buffer, unsigned int count)
        _write(handle, buffer, count))
 }
 
+/*
+ * POSIX equivalent for writev
+ * Modelled after the GNU's libc/sysdeps/posix/writev.c
+ */
+ssize_t
+writev(int fd, const struct iovec *iov, int iovcnt)
+{
+    int i;
+    unsigned char *buffer, *buffer_location;
+    size_t total_bytes = 0;
+    int bytes_written;
+
+    for (i = 0; i < iovcnt; i++)
+       total_bytes += iov[i].iov_len;
+
+    if (total_bytes == 0)
+       return 0;
+
+    buffer = malloc(total_bytes);
+    if (buffer == NULL)
+       return -1;
+
+    buffer_location = buffer;
+    for (i = 0; i < iovcnt; i++) {
+       memcpy(buffer_location, iov[i].iov_base, iov[i].iov_len);
+       buffer_location += iov[i].iov_len;
+    }
+
+    bytes_written = posix_write(fd, buffer, total_bytes);
+
+    free(buffer);
+
+    if (bytes_written <= 0)
+       return -1;
+    return bytes_written;
+}
+
 /*
  * POSIX equivalent for fileno().
  * As fopen/fclose/fcloseall are not implemented as POSIX
diff --git a/src/lib/w32/sys/uio.h b/src/lib/w32/sys/uio.h
new file mode 100644 (file)
index 0000000..043e62b
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  sys/socket.h: POSIX io vector emulation for WIN32
+ * 
+ *  Known contributors to this file:
+ *     Ron Koenderink, 2007
+ */
+
+#ifndef SYS_UIO_H
+#define SYS_UIO_H
+
+#include <sys/types.h>
+#include "w32misc.h"
+
+struct iovec {
+    /*Base address of a memory region for input or output. */
+    void   *iov_base;
+
+    /* The size of the memory pointed to by iov_base. */
+    size_t  iov_len;
+};
+
+extern ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
+extern ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
+
+#endif /* SYS_UIO_H */