mirror of
https://github.com/wassname/ray.git
synced 2026-09-12 12:51:15 +08:00
Windows compatibility (#57)
* Add Python and Redis submodules, and remove old third-party modules
* Update VS projects (WARNING: references files that do not exist yet)
* Update code & add shims for APIs except AF_UNIX/{send,recv}msg()
* Minor style changes.
This commit is contained in:
committed by
Robert Nishihara
parent
a93c6b7596
commit
7237ec4124
@@ -0,0 +1,69 @@
|
||||
/* http://stackoverflow.com/a/17195644/541686 */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int) '?'
|
||||
#define BADARG (int) ':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int getopt(int nargc, char *const nargv[], const char *ostr) {
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
const char *oli; /* option letter list index */
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int) *place++) == (int) ':' || !(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int) '-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void) printf("illegal option -- %c\n", optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
} else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void) printf("option requires an argument -- %c\n", optopt);
|
||||
return (BADCH);
|
||||
} else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef GETOPT_H
|
||||
#define GETOPT_H
|
||||
|
||||
#endif /* GETOPT_H */
|
||||
@@ -0,0 +1,208 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
int socketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
if ((domain != AF_UNIX && domain != AF_INET) || type != SOCK_STREAM) {
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
SOCKET sockets[2];
|
||||
int r = dumb_socketpair(sockets);
|
||||
sv[0] = (int) sockets[0];
|
||||
sv[1] = (int) sockets[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
#pragma comment(lib, "IPHlpAPI.lib")
|
||||
|
||||
struct _MIB_TCPROW2 {
|
||||
DWORD dwState, dwLocalAddr, dwLocalPort, dwRemoteAddr, dwRemotePort,
|
||||
dwOwningPid;
|
||||
enum _TCP_CONNECTION_OFFLOAD_STATE dwOffloadState;
|
||||
};
|
||||
|
||||
struct _MIB_TCPTABLE2 {
|
||||
DWORD dwNumEntries;
|
||||
struct _MIB_TCPROW2 table[1];
|
||||
};
|
||||
|
||||
DECLSPEC_IMPORT ULONG WINAPI GetTcpTable2(struct _MIB_TCPTABLE2 *TcpTable,
|
||||
PULONG SizePointer,
|
||||
BOOL Order);
|
||||
|
||||
static DWORD getsockpid(SOCKET client) {
|
||||
/* http://stackoverflow.com/a/25431340 */
|
||||
DWORD pid = 0;
|
||||
|
||||
struct sockaddr_in Server = {0};
|
||||
int ServerSize = sizeof(Server);
|
||||
|
||||
struct sockaddr_in Client = {0};
|
||||
int ClientSize = sizeof(Client);
|
||||
|
||||
if ((getsockname(client, (struct sockaddr *) &Server, &ServerSize) == 0) &&
|
||||
(getpeername(client, (struct sockaddr *) &Client, &ClientSize) == 0)) {
|
||||
struct _MIB_TCPTABLE2 *TcpTable = NULL;
|
||||
ULONG TcpTableSize = 0;
|
||||
ULONG result;
|
||||
do {
|
||||
result = GetTcpTable2(TcpTable, &TcpTableSize, TRUE);
|
||||
if (result != ERROR_INSUFFICIENT_BUFFER) {
|
||||
break;
|
||||
}
|
||||
free(TcpTable);
|
||||
TcpTable = (struct _MIB_TCPTABLE2 *) malloc(TcpTableSize);
|
||||
} while (TcpTable != NULL);
|
||||
|
||||
if (result == NO_ERROR) {
|
||||
for (DWORD dw = 0; dw < TcpTable->dwNumEntries; ++dw) {
|
||||
struct _MIB_TCPROW2 *row = &(TcpTable->table[dw]);
|
||||
if ((row->dwState == 5 /* MIB_TCP_STATE_ESTAB */) &&
|
||||
(row->dwLocalAddr == Client.sin_addr.s_addr) &&
|
||||
((row->dwLocalPort & 0xFFFF) == Client.sin_port) &&
|
||||
(row->dwRemoteAddr == Server.sin_addr.s_addr) &&
|
||||
((row->dwRemotePort & 0xFFFF) == Server.sin_port)) {
|
||||
pid = row->dwOwningPid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(TcpTable);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||
ssize_t result = -1;
|
||||
struct cmsghdr *header = CMSG_FIRSTHDR(msg);
|
||||
if (header->cmsg_level == SOL_SOCKET && header->cmsg_type == SCM_RIGHTS) {
|
||||
/* We're trying to send over a handle of some kind.
|
||||
* We have to look up which process we're communicating with,
|
||||
* open a handle to it, and then duplicate our handle into it.
|
||||
* However, the first two steps cannot be done atomically.
|
||||
* Therefore, this code HAS A RACE CONDITIONS and is therefore NOT SECURE.
|
||||
* In the absense of a malicious actor, though, it is exceedingly unlikely
|
||||
* that the child process closes AND that its process ID is reassigned
|
||||
* to another existing process.
|
||||
*/
|
||||
struct msghdr const old_msg = *msg;
|
||||
int *const pfd = (int *) CMSG_DATA(header);
|
||||
msg->msg_control = NULL;
|
||||
msg->msg_controllen = 0;
|
||||
WSAPROTOCOL_INFO protocol_info = {0};
|
||||
BOOL const is_socket = !!FDAPI_GetSocketStatePtr(*pfd);
|
||||
DWORD const target_pid = getsockpid(sockfd);
|
||||
HANDLE target_process = NULL;
|
||||
if (target_pid) {
|
||||
if (!is_socket) {
|
||||
/* This is a regular handle... fit it into the same struct */
|
||||
target_process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, target_pid);
|
||||
if (target_process) {
|
||||
if (DuplicateHandle(GetCurrentProcess(), (HANDLE)(intptr_t) *pfd,
|
||||
target_process, (HANDLE *) &protocol_info, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS)) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* This is a socket... */
|
||||
result = FDAPI_WSADuplicateSocket(*pfd, target_pid, &protocol_info);
|
||||
}
|
||||
}
|
||||
if (result == 0) {
|
||||
int const nbufs = msg->dwBufferCount + 1;
|
||||
WSABUF *const bufs =
|
||||
(struct _WSABUF *) _alloca(sizeof(*msg->lpBuffers) * nbufs);
|
||||
bufs[0].buf = (char *) &protocol_info;
|
||||
bufs[0].len = sizeof(protocol_info);
|
||||
memcpy(&bufs[1], msg->lpBuffers,
|
||||
msg->dwBufferCount * sizeof(*msg->lpBuffers));
|
||||
DWORD nb;
|
||||
msg->lpBuffers = bufs;
|
||||
msg->dwBufferCount = nbufs;
|
||||
GUID const wsaid_WSASendMsg = {
|
||||
0xa441e712,
|
||||
0x754f,
|
||||
0x43ca,
|
||||
{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}};
|
||||
typedef INT PASCAL WSASendMsg_t(
|
||||
SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags, LPDWORD lpNumberOfBytesSent,
|
||||
LPWSAOVERLAPPED lpOverlapped,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
|
||||
WSASendMsg_t *WSASendMsg = NULL;
|
||||
result = FDAPI_WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||
&wsaid_WSASendMsg, sizeof(wsaid_WSASendMsg),
|
||||
&WSASendMsg, sizeof(WSASendMsg), &nb, NULL, 0);
|
||||
if (result == 0) {
|
||||
result = (*WSASendMsg)(sockfd, msg, flags, &nb, NULL, NULL) == 0
|
||||
? (ssize_t)(nb - sizeof(protocol_info))
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
if (result != 0 && target_process && !is_socket) {
|
||||
/* we failed to send the handle, and it needs cleaning up! */
|
||||
HANDLE duplicated_back = NULL;
|
||||
if (DuplicateHandle(target_process, *(HANDLE *) &protocol_info,
|
||||
GetCurrentProcess(), &duplicated_back, 0, FALSE,
|
||||
DUPLICATE_CLOSE_SOURCE)) {
|
||||
CloseHandle(duplicated_back);
|
||||
}
|
||||
}
|
||||
if (target_process) {
|
||||
CloseHandle(target_process);
|
||||
}
|
||||
*msg = old_msg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||
int result = -1;
|
||||
struct cmsghdr *header = CMSG_FIRSTHDR(msg);
|
||||
if (msg->msg_controllen &&
|
||||
flags == 0 /* We can't send flags on Windows... */) {
|
||||
struct msghdr const old_msg = *msg;
|
||||
msg->msg_control = NULL;
|
||||
msg->msg_controllen = 0;
|
||||
WSAPROTOCOL_INFO protocol_info = {0};
|
||||
int const nbufs = msg->dwBufferCount + 1;
|
||||
WSABUF *const bufs =
|
||||
(struct _WSABUF *) _alloca(sizeof(*msg->lpBuffers) * nbufs);
|
||||
bufs[0].buf = (char *) &protocol_info;
|
||||
bufs[0].len = sizeof(protocol_info);
|
||||
memcpy(&bufs[1], msg->lpBuffers,
|
||||
msg->dwBufferCount * sizeof(*msg->lpBuffers));
|
||||
typedef INT PASCAL WSARecvMsg_t(
|
||||
SOCKET s, LPWSAMSG lpMsg, LPDWORD lpNumberOfBytesRecvd,
|
||||
LPWSAOVERLAPPED lpOverlapped,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
|
||||
WSARecvMsg_t *WSARecvMsg = NULL;
|
||||
DWORD nb;
|
||||
GUID const wsaid_WSARecvMsg = {
|
||||
0xf689d7c8,
|
||||
0x6f1f,
|
||||
0x436b,
|
||||
{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}};
|
||||
result = FDAPI_WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||
&wsaid_WSARecvMsg, sizeof(wsaid_WSARecvMsg),
|
||||
&WSARecvMsg, sizeof(WSARecvMsg), &nb, NULL, 0);
|
||||
if (result == 0) {
|
||||
result = (*WSARecvMsg)(sockfd, msg, &nb, NULL, NULL) == 0
|
||||
? (ssize_t)(nb - sizeof(protocol_info))
|
||||
: 0;
|
||||
}
|
||||
if (result == 0) {
|
||||
int *const pfd = (int *) CMSG_DATA(header);
|
||||
if (protocol_info.iSocketType == 0 && protocol_info.iProtocol == 0) {
|
||||
*pfd = *(int *) &protocol_info;
|
||||
} else {
|
||||
*pfd = FDAPI_WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
|
||||
FROM_PROTOCOL_INFO, &protocol_info, 0, 0);
|
||||
}
|
||||
header->cmsg_level = SOL_SOCKET;
|
||||
header->cmsg_type = SCM_RIGHTS;
|
||||
}
|
||||
*msg = old_msg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef NETDB_H
|
||||
#define NETDB_H
|
||||
|
||||
#endif /* NETDB_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef IN_H
|
||||
#define IN_H
|
||||
|
||||
#endif /* IN_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef POLL_H
|
||||
#define POLL_H
|
||||
|
||||
#endif /* POLL_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
/* socketpair.c
|
||||
Copyright 2007, 2010 by Nathan C. Myers <ncm@cantrip.org>
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
The name of the author must not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Changes:
|
||||
* 2014-02-12: merge David Woodhouse, Ger Hobbelt improvements
|
||||
* git.infradead.org/users/dwmw2/openconnect.git/commitdiff/bdeefa54
|
||||
* github.com/GerHobbelt/selectable-socketpair
|
||||
* always init the socks[] to -1/INVALID_SOCKET on error, both on Win32/64
|
||||
* and UNIX/other platforms
|
||||
* 2013-07-18: Change to BSD 3-clause license
|
||||
* 2010-03-31:
|
||||
* 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
|
||||
* attempts." Bleah.
|
||||
* 2007-04-25:
|
||||
* preserve value of WSAGetLastError() on all error returns.
|
||||
* 2007-04-22: (Thanks to Matthew Gregan <kinetik@flim.org>)
|
||||
* s/EINVAL/WSAEINVAL/ fix trivial compile failure
|
||||
* s/socket/WSASocket/ enable creation of sockets suitable as stdin/stdout
|
||||
* of a child process.
|
||||
* add argument make_overlapped
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <ws2tcpip.h> /* socklen_t, et al (MSVC20xx) */
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#include <Win32_Interop/win32_types.h>
|
||||
#include <Win32_Interop/Win32_FDAPI.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
/* 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
|
||||
* suitable for use as stdin or stdout of a child process. Note that the
|
||||
* sockets must be closed with closesocket() regardless.
|
||||
*/
|
||||
|
||||
int dumb_socketpair(SOCKET socks[2]) {
|
||||
union {
|
||||
struct sockaddr_in inaddr;
|
||||
struct sockaddr addr;
|
||||
} a;
|
||||
SOCKET listener;
|
||||
int e;
|
||||
socklen_t addrlen = sizeof(a.inaddr);
|
||||
int reuse = 1;
|
||||
|
||||
if (socks == 0) {
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
socks[0] = socks[1] = -1;
|
||||
|
||||
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (listener == -1)
|
||||
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;
|
||||
|
||||
for (;;) {
|
||||
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] = FDAPI_WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
|
||||
if (socks[0] == -1)
|
||||
break;
|
||||
if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
|
||||
break;
|
||||
|
||||
socks[1] = accept(listener, NULL, NULL);
|
||||
if (socks[1] == -1)
|
||||
break;
|
||||
|
||||
FDAPI_close(listener);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FDAPI_close(listener);
|
||||
FDAPI_close(socks[0]);
|
||||
FDAPI_close(socks[1]);
|
||||
socks[0] = socks[1] = -1;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
#else
|
||||
int dumb_socketpair(int socks[2], int dummy) {
|
||||
if (socks == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
dummy = socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
|
||||
if (dummy)
|
||||
socks[0] = socks[1] = -1;
|
||||
return dummy;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef STRINGS_H
|
||||
#define STRINGS_H
|
||||
|
||||
#endif /* STRINGS_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef IOCTL_H
|
||||
#define IOCTL_H
|
||||
|
||||
#endif /* IOCTL_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef MMAN_H
|
||||
#define MMAN_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAP_SHARED 0x0010 /* share changes */
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#define PROT_READ 0x04 /* pages can be read */
|
||||
#define PROT_WRITE 0x02 /* pages can be written */
|
||||
#define PROT_EXEC 0x01 /* pages can be executed */
|
||||
|
||||
static void *mmap(void *addr,
|
||||
size_t len,
|
||||
int prot,
|
||||
int flags,
|
||||
int fd,
|
||||
off_t off) {
|
||||
void *result = (void *) (-1);
|
||||
if (!addr && prot == MAP_SHARED) {
|
||||
/* HACK: we're assuming handle sizes can't exceed 32 bits, which is wrong...
|
||||
* but works for now. */
|
||||
void *ptr = MapViewOfFile((HANDLE)(intptr_t) fd, FILE_MAP_ALL_ACCESS,
|
||||
(DWORD)(off >> (CHAR_BIT * sizeof(DWORD))),
|
||||
(DWORD) off, (SIZE_T) len);
|
||||
if (ptr) {
|
||||
result = ptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int munmap(void *addr, size_t length) {
|
||||
(void) length;
|
||||
return UnmapViewOfFile(addr) ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* MMAN_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef SELECT_H
|
||||
#define SELECT_H
|
||||
|
||||
#endif /* SELECT_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef SOCKET_H
|
||||
#define SOCKET_H
|
||||
|
||||
typedef unsigned short sa_family_t;
|
||||
|
||||
#include "../../src/Win32_Interop/Win32_FDAPI.h"
|
||||
#include "../../src/Win32_Interop/Win32_APIs.h"
|
||||
|
||||
#define cmsghdr _WSACMSGHDR
|
||||
#undef CMSG_DATA
|
||||
#define CMSG_DATA WSA_CMSG_DATA
|
||||
#define CMSG_SPACE WSA_CMSG_SPACE
|
||||
#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR
|
||||
#define CMSG_LEN WSA_CMSG_LEN
|
||||
#define CMSG_NXTHDR WSA_CMSG_NXTHDR
|
||||
|
||||
#define SCM_RIGHTS 1
|
||||
|
||||
#define iovec _WSABUF
|
||||
#define iov_base buf
|
||||
#define iov_len len
|
||||
#define msghdr _WSAMSG
|
||||
#define msg_name name
|
||||
#define msg_namelen namelen
|
||||
#define msg_iov lpBuffers
|
||||
#define msg_iovlen dwBufferCount
|
||||
#define msg_control Control.buf
|
||||
#define msg_controllen Control.len
|
||||
#define msg_flags dwFlags
|
||||
|
||||
int dumb_socketpair(SOCKET socks[2]);
|
||||
ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags);
|
||||
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
|
||||
int socketpair(int domain, int type, int protocol, int sv[2]);
|
||||
|
||||
#endif /* SOCKET_H */
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef TIME_H
|
||||
#define TIME_H
|
||||
|
||||
#include <WinSock2.h> /* timeval */
|
||||
|
||||
int gettimeofday_highres(struct timeval *tv, struct timezone *tz);
|
||||
|
||||
static int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
return gettimeofday_highres(tv, tz);
|
||||
}
|
||||
|
||||
#endif /* TIME_H */
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef UN_H
|
||||
#define UN_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct sockaddr_un {
|
||||
/** AF_UNIX. */
|
||||
sa_family_t sun_family;
|
||||
/** The pathname. */
|
||||
char sun_path[108];
|
||||
};
|
||||
|
||||
#endif /* UN_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef WAIT_H
|
||||
#define WAIT_H
|
||||
|
||||
#endif /* WAIT_H */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef UNISTD_H
|
||||
#define UNISTD_H
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
int getopt(int nargc, char *const nargv[], const char *ostr);
|
||||
|
||||
#include "../../src/Win32_Interop/Win32_FDAPI.h"
|
||||
#define close(...) FDAPI_close(__VA_ARGS__)
|
||||
|
||||
#endif /* UNISTD_H */
|
||||
Reference in New Issue
Block a user