summaryrefslogtreecommitdiff
path: root/src/libmowgli/platform/win32/socketpair.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmowgli/platform/win32/socketpair.c')
-rw-r--r--src/libmowgli/platform/win32/socketpair.c155
1 files changed, 84 insertions, 71 deletions
diff --git a/src/libmowgli/platform/win32/socketpair.c b/src/libmowgli/platform/win32/socketpair.c
index 6ede51e..b641838 100644
--- a/src/libmowgli/platform/win32/socketpair.c
+++ b/src/libmowgli/platform/win32/socketpair.c
@@ -1,11 +1,11 @@
/* socketpair.c
* Copyright 2007, 2010 by Nathan C. Myers <ncm@cantrip.org>
- * This code is Free Software. It may be copied freely, in original or
+ * This code is Free Software. It may be copied freely, in original or
* modified form, subject only to the restrictions that (1) the author is
* relieved from all responsibilities for any use for any purpose, and (2)
* this copyright notice must be retained, unchanged, in its entirety. If
* for any reason the author might be held responsible for any consequences
- * of copying or use, license is withheld.
+ * of copying or use, license is withheld.
*/
/* Changes:
@@ -13,8 +13,8 @@
* set addr to 127.0.0.1 because win32 getsockname does not always set it.
* 2010-02-25:
* set SO_REUSEADDR option to avoid leaking some windows resource.
- * Windows System Error 10049, "Event ID 4226 TCP/IP has reached
- * the security limit imposed on the number of concurrent TCP connect
+ * Windows System Error 10049, "Event ID 4226 TCP/IP has reached
+ * the security limit imposed on the number of concurrent TCP connect
* attempts." Bleah.
* 2007-04-25:
* preserve value of WSAGetLastError() on all error returns.
@@ -32,78 +32,91 @@
/* dumb_socketpair:
* If make_overlapped is nonzero, both sockets created will be usable for
* "overlapped" operations via WSASend etc. If make_overlapped is zero,
- * socks[0] (only) will be usable with regular ReadFile etc., and thus
+ * socks[0] (only) will be usable with regular ReadFile etc., and thus
* suitable for use as stdin or stdout of a child process. Note that the
* sockets must be closed with closesocket() regardless.
*/
-int socketpair(int domain, int type, int protocol, int socks[2])
+int
+socketpair(int domain, int type, int protocol, int socks[2])
{
- union {
- struct sockaddr_in inaddr;
- struct sockaddr addr;
- } a;
- SOCKET listener;
- int e;
- socklen_t addrlen = sizeof(a.inaddr);
- int make_overlapped = 0;
- DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
- int reuse = 1;
-
- if (socks == NULL) {
- WSASetLastError(WSAEINVAL);
- return SOCKET_ERROR;
- }
-
- listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (listener == INVALID_SOCKET)
- return SOCKET_ERROR;
-
- memset(&a, 0, sizeof(a));
- a.inaddr.sin_family = AF_INET;
- a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- a.inaddr.sin_port = 0;
-
- socks[0] = socks[1] = INVALID_SOCKET;
- do {
- if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
- (char*) &reuse, (socklen_t) sizeof(reuse)) == -1)
- break;
- if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
- break;
-
- memset(&a, 0, sizeof(a));
- if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
- break;
- // win32 getsockname may only set the port number, p=0.0005.
- // ( http://msdn.microsoft.com/library/ms738543.aspx ):
- a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- a.inaddr.sin_family = AF_INET;
-
- if (listen(listener, 1) == SOCKET_ERROR)
- break;
-
- socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
- if (socks[0] == (int) INVALID_SOCKET)
- break;
- if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
- break;
-
- socks[1] = accept(listener, NULL, NULL);
- if (socks[1] == (int) INVALID_SOCKET)
- break;
-
- closesocket(listener);
- return 0;
-
- } while (0);
-
- e = WSAGetLastError();
- closesocket(listener);
- closesocket(socks[0]);
- closesocket(socks[1]);
- WSASetLastError(e);
- return SOCKET_ERROR;
+ union
+ {
+ struct sockaddr_in inaddr;
+
+ struct sockaddr addr;
+ } a;
+
+ SOCKET listener;
+ int e;
+ socklen_t addrlen = sizeof(a.inaddr);
+ int make_overlapped = 0;
+ DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
+ int reuse = 1;
+
+ if (socks == NULL)
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (listener == INVALID_SOCKET)
+ return SOCKET_ERROR;
+
+ memset(&a, 0, sizeof(a));
+ a.inaddr.sin_family = AF_INET;
+ a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ a.inaddr.sin_port = 0;
+
+ socks[0] = socks[1] = INVALID_SOCKET;
+
+ do
+ {
+ if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &reuse, (socklen_t) sizeof(reuse)) == -1)
+ break;
+
+ if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
+ break;
+
+ memset(&a, 0, sizeof(a));
+
+ if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
+ break;
+
+ // win32 getsockname may only set the port number, p=0.0005.
+ // ( http://msdn.microsoft.com/library/ms738543.aspx ):
+ a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ a.inaddr.sin_family = AF_INET;
+
+ if (listen(listener, 1) == SOCKET_ERROR)
+ break;
+
+ socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
+
+ if (socks[0] == (int) INVALID_SOCKET)
+ break;
+
+ if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
+ break;
+
+ socks[1] = accept(listener, NULL, NULL);
+
+ if (socks[1] == (int) INVALID_SOCKET)
+ break;
+
+ closesocket(listener);
+ return 0;
+ } while (0);
+
+ e = WSAGetLastError();
+ closesocket(listener);
+ closesocket(socks[0]);
+ closesocket(socks[1]);
+ WSASetLastError(e);
+ return SOCKET_ERROR;
}
#endif