(ioq_makeiov, ioqtoiov): Compile unconditionally.
(io_output): Use POSIX code unconditionally.
[_WIN32] (ioq_makebuf): Remove.
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);
#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>
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;
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;
}
/* 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) {
#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);
* 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)
{
return 0;
return ioqtoiov(ioq, iov, cc);
}
-#endif
/*
* Copy the specified number of characters into the buffer
* 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)
{
}
return niov;
}
-#endif
/*
* append a buffer to the end of the ioq.
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 */
#include <errno.h>
#include "unistd.h"
+#include "sys/uio.h"
#include "empio.h"
#include "prototypes.h"
_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().
*/
_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
--- /dev/null
+/*
+ * 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 */