]> git.pond.sub.org Git - empserver/blobdiff - src/lib/w32/posixio.c
Update copyright notice
[empserver] / src / lib / w32 / posixio.c
index f516ad4f7338998b12d46e3e14d39462cf23619d..0f69f76897b2380c1a5a3a8ec861f351f05b2f79 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  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 <config.h>
-#include <winsock2.h>
-#undef NS_ALL
-#include <io.h>
-#include <sys/stat.h>
+
+#include <errno.h>
 #include <fcntl.h>
+#include <io.h>
 #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 <errno.h>
-
-#include "unistd.h"
-#include "sys/uio.h"
 #include "misc.h"
+#include "sys/uio.h"
+#include "unistd.h"
 
 /*
  * FD_SETSIZE is the size for the maximum number of sockets.
@@ -130,7 +136,7 @@ set_fd(int fd, enum fdmap_io_type type, int handle)
     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.
      */
@@ -224,7 +230,8 @@ int
 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;
@@ -239,7 +246,7 @@ posix_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
        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;
 }
 
@@ -272,8 +279,7 @@ posix_setsockopt(int fd, int level, int optname,
                      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,
@@ -306,9 +312,9 @@ posix_shutdown(int fd, int how)
 int
 posix_socket(int domain, int type, int protocol)
 {
-    int handle;
+    SOCKET handle;
     int new_fd;
-    
+
     if ((new_fd = get_fd()) < 0)
        return -1;
 
@@ -318,10 +324,45 @@ posix_socket(int domain, int type, int protocol)
        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 *src, char *dst, socklen_t len)
+{
+    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;
+    }
+
+    if (getnameinfo(sa, salen, dst, len, NULL, 0, NI_NUMERICHOST)) {
+       errno = EAFNOSUPPORT;
+       return NULL;
+    }
+
+    return dst;
+}
+#endif
+
 #define FILE_FUNCTION(type, expr)                              \
     int handle;                                                        \
                                                                \
@@ -354,9 +395,10 @@ posix_close(int fd)
        return result;
     case FDMAP_IO_FILE:
        return _close(handle);
+    default:
+       CANT_REACH();
+       return -1;
     }
-    CANT_REACH();
-    return -1;
 }
 
 /*
@@ -371,6 +413,15 @@ posix_fsync(int fd)
     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(),
@@ -446,9 +497,10 @@ posix_open(const char *fname, int oflag, ...)
        return result;                                              \
     case FDMAP_IO_FILE:                                                    \
        return (file_expr);                                         \
-    }                                                              \
-    CANT_REACH();                                                  \
-    return -1;
+    default:                                                       \
+       CANT_REACH();                                               \
+       return -1;                                                  \
+    }
 
 /*
  * POSIX equivalent for read().
@@ -478,8 +530,10 @@ readv(int fd, const struct iovec *iov, int iovcnt)
     }
 
     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) {
@@ -530,12 +584,11 @@ writev(int fd, const struct iovec *iov, int iovcnt)
     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++) {
@@ -561,7 +614,7 @@ writev(int fd, const struct iovec *iov, int iovcnt)
  * handle is reused.
  */
 int
-posix_fileno(FILE *stream)
+fileno(FILE *stream)
 {
     int fd;
     int handle;
@@ -616,7 +669,7 @@ fcntl(int fd, int cmd, ...)
        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;