/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* posixio.c: POSIX IO emulation layer for WIN32
- *
+ *
* Known contributors to this file:
* Ron Koenderink, 2007
+ * Markus Armbruster, 2007-2008
*/
/*
#include <share.h>
#include <stdio.h>
#include <stdarg.h>
+/*
+ * Need to include winsock2.h before ws2tcpip.h.
+ * Use sys/socket.h to ensure the #undef NS_ALL
+ * is not missed after including winsock2.h.
+ */
+#include "sys/socket.h"
#include <sys/stat.h>
+#include <ws2tcpip.h>
#include "misc.h"
-#include "sys/socket.h"
#include "sys/uio.h"
#include "unistd.h"
fdmap[fd].type = type;
/*
- * Garbage collection for posix_fileno(), currently not
+ * Garbage collection for fileno(), currently not
* replacing fclose() and fcloseall() so do not know when
* a stream is closed.
*/
posix_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
int new_fd;
- int handle, new_handle;
+ int handle;
+ SOCKET new_handle;
if (!lookup_handle(fd, FDMAP_IO_SOCKET, ENOTSOCK, NULL, &handle))
return -1;
errno = WSAGetLastError();
return -1;
}
- set_fd(new_fd, FDMAP_IO_SOCKET, new_handle);
+ set_fd(new_fd, FDMAP_IO_SOCKET, (int)new_handle);
return new_fd;
}
const void *optval, socklen_t optlen)
{
/*
- * SO_REUSEADDR requests from tcp_listen.c
- * to permit another bind even when the
+ * SO_REUSEADDR requests to permit another bind even when the
* port is still in state TIME_WAIT. Windows' SO_REUSEADDR is
* broken: it makes bind() succeed no matter what, even if
* there's another server running on the same port. Luckily,
int
posix_socket(int domain, int type, int protocol)
{
- int handle;
+ SOCKET handle;
int new_fd;
-
+
if ((new_fd = get_fd()) < 0)
return -1;
errno = WSAGetLastError();
return -1;
}
- set_fd(new_fd, FDMAP_IO_SOCKET, handle);
+ set_fd(new_fd, FDMAP_IO_SOCKET, (int)handle);
return new_fd;
}
+#ifdef HAVE_GETADDRINFO
const char *
-inet_ntop(int af, const void *source, char *dest, socklen_t len)
+inet_ntop(int af, const void *src, char *dst, socklen_t len)
{
- if (af == AF_INET)
- {
- struct sockaddr_in in;
- memset(&in, 0, sizeof(in));
- in.sin_family = AF_INET;
- memcpy(&in.sin_addr, source, sizeof(struct in_addr));
- getnameinfo((struct sockaddr *)&in,
- sizeof(struct sockaddr_in), dest, len,
- NULL, 0, NI_NUMERICHOST);
- return dest;
+ struct sockaddr *sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ size_t salen;
+
+ if (af == AF_INET) {
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = af;
+ memcpy(&sin.sin_addr, src, sizeof(sin.sin_addr));
+ sa = (struct sockaddr *)&sin;
+ salen = sizeof(sin);
+ } else if (af == AF_INET6) {
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = af;
+ memcpy(&sin6.sin6_addr, src, sizeof(sin6.sin6_addr));
+ sa = (struct sockaddr *)&sin6;
+ salen = sizeof(sin6);
+ } else {
+ errno = EAFNOSUPPORT;
+ return NULL;
}
- else if (af == AF_INET6)
- {
- struct sockaddr_in6 in;
- memset(&in, 0, sizeof(in));
- in.sin6_family = AF_INET6;
- memcpy(&in.sin6_addr, source, sizeof(struct in_addr6));
- getnameinfo((struct sockaddr *)&in,
- sizeof(struct sockaddr_in6), dest, len,
- NULL, 0, NI_NUMERICHOST);
- return dest;
+
+ if (getnameinfo(sa, salen, dst, len, NULL, 0, NI_NUMERICHOST)) {
+ errno = EAFNOSUPPORT;
+ return NULL;
}
- return NULL;
+
+ return dst;
}
+#endif
#define FILE_FUNCTION(type, expr) \
int handle; \
return result;
case FDMAP_IO_FILE:
return _close(handle);
+ default:
+ CANT_REACH();
+ return -1;
}
- CANT_REACH();
- return -1;
}
/*
FILE_FUNCTION(FDMAP_IO_FILE, _commit(handle))
}
+/*
+ * POSIX ftruncate()
+ */
+int
+ftruncate(int fd, off_t length)
+{
+ FILE_FUNCTION(FDMAP_IO_FILE, _chsize(handle, length))
+}
+
/*
* POSIX equivalent for fstat().
* fstat() is used instead of _fstat(),
return result; \
case FDMAP_IO_FILE: \
return (file_expr); \
- } \
- CANT_REACH(); \
- return -1;
+ default: \
+ CANT_REACH(); \
+ return -1; \
+ }
/*
* POSIX equivalent for read().
}
buffer = malloc(total_bytes);
- if (buffer == NULL)
+ if (buffer == NULL && total_bytes != 0) {
+ errno = ENOMEM;
return -1;
+ }
bytes_read = posix_read(fd, buffer, total_bytes);
if (bytes_read <= 0) {
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)
+ if (buffer == NULL && total_bytes != 0) {
+ errno = ENOMEM;
return -1;
+ }
buffer_location = buffer;
for (i = 0; i < iovcnt; i++) {
* handle is reused.
*/
int
-posix_fileno(FILE *stream)
+fileno(FILE *stream)
{
int fd;
int handle;
if (type == FDMAP_IO_SOCKET) {
result = WSAIoctl(handle, FIONBIO, NULL, 0,&nonblocking,
sizeof (nonblocking), &bytes_returned, NULL, NULL);
-
+
if(result < 0) {
errno = WSAGetLastError();
return -1;