windows: Implement socketpair() using TCP sockets
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
@@ -33,3 +35,65 @@ void windows_deinit()
|
|||||||
{
|
{
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
int socketpair(int domain, int type, int protocol, int sv[2])
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
||||||
|
};
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
int s, c, sc;
|
||||||
|
BOOL on;
|
||||||
|
|
||||||
|
/* We don't check domain for AF_INET, as we use it as replacement for
|
||||||
|
* AF_UNIX. */
|
||||||
|
if (type != SOCK_STREAM)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (protocol != 0 && protocol != IPPROTO_TCP)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (s == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (c == -1)
|
||||||
|
{
|
||||||
|
closesocket(c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 &&
|
||||||
|
getsockname(s,(struct sockaddr*)&addr, &len) == 0 &&
|
||||||
|
listen(s, 0) == 0 &&
|
||||||
|
connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0)
|
||||||
|
{
|
||||||
|
sc = accept(s, NULL, NULL);
|
||||||
|
if (sc > 0)
|
||||||
|
{
|
||||||
|
closesocket(s);
|
||||||
|
s = sc;
|
||||||
|
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
|
||||||
|
(void*)&on, sizeof(on)) == 0 &&
|
||||||
|
setsockopt(c, IPPROTO_TCP, TCP_NODELAY,
|
||||||
|
(void*)&on, sizeof(on)) == 0)
|
||||||
|
{
|
||||||
|
sv[0] = s;
|
||||||
|
sv[1] = c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closesocket(s);
|
||||||
|
closesocket(c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -246,6 +246,11 @@ static inline int dlclose(void *handle)
|
|||||||
return FreeLibrary((HMODULE)handle);
|
return FreeLibrary((HMODULE)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* socketpair(2) for SOCK_STREAM, uses TCP on loopback
|
||||||
|
*/
|
||||||
|
int socketpair(int domain, int type, int protocol, int sv[2]);
|
||||||
|
|
||||||
/* Windows does not support "ll" format printf length modifiers. Mingw
|
/* Windows does not support "ll" format printf length modifiers. Mingw
|
||||||
* therefore maps these to the Windows specific I64 length modifier. That
|
* therefore maps these to the Windows specific I64 length modifier. That
|
||||||
* won't work for us, as we use our own printf backend on Windows, which works
|
* won't work for us, as we use our own printf backend on Windows, which works
|
||||||
|
|||||||
Reference in New Issue
Block a user