[add/change] - win32 wrappers
parent
87bfff2643
commit
20a96d422c
|
@ -29,6 +29,8 @@ static int dummy ATTRIBUTE((unused));
|
|||
#include "win32_compat.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include < time.h >
|
||||
|
||||
#undef poll
|
||||
#undef socket
|
||||
#undef connect
|
||||
|
@ -47,239 +49,154 @@ static int dummy ATTRIBUTE((unused));
|
|||
|
||||
int win32_inet_pton(int af, const char * src, void * dst)
|
||||
{
|
||||
int temp = sizeof(struct sockaddr_in);
|
||||
int ret = -1;
|
||||
int len = strlen(src) + 1;
|
||||
wchar_t *srcNonConst = (wchar_t *)malloc(len);
|
||||
memset(srcNonConst, 0, len);
|
||||
MultiByteToWideChar(CP_ACP, NULL, src, -1, srcNonConst, len);
|
||||
struct sockaddr_in sa;
|
||||
int len = sizeof(SOCKADDR);
|
||||
int ret = -1;
|
||||
int strLen = strlen(src) + 1;
|
||||
#ifdef UNICODE
|
||||
wchar_t *srcNonConst = (wchar_t *)malloc(strLen*sizeof(wchar_t));
|
||||
memset(srcNonConst, 0, strLen);
|
||||
MultiByteToWideChar(CP_ACP, 0, src, -1, srcNonConst, strLen);
|
||||
#else
|
||||
char *srcNonConst = (char *)malloc(strLen);
|
||||
memset(srcNonConst, 0, strLen);
|
||||
strncpy(srcNonConst, src, strLen);
|
||||
#endif
|
||||
|
||||
if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)dst,&temp) == 0 )
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( WSAGetLastError() == WSAEINVAL )
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
//free(srcNonConst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether "cp" is a valid ascii representation of an Internet address
|
||||
* and convert to a binary address. Returns 1 if the address is valid, 0 if
|
||||
* not. This replaces inet_addr, the return value from which cannot
|
||||
* distinguish between failure and a local broadcast address.
|
||||
*
|
||||
* This implementation of the standard inet_aton() function was copied
|
||||
* (with trivial modifications) from the OpenBSD project.
|
||||
*/
|
||||
int
|
||||
win32_inet_aton(const char *cp, struct in_addr *addr)
|
||||
{
|
||||
register unsigned int val;
|
||||
register int base, n;
|
||||
register char c;
|
||||
unsigned int parts[4];
|
||||
register unsigned int *pp = parts;
|
||||
|
||||
assert(sizeof(val) == 4);
|
||||
|
||||
c = *cp;
|
||||
while(1) {
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if(!isdigit(c))
|
||||
return (0);
|
||||
val = 0; base = 10;
|
||||
if(c == '0') {
|
||||
c = *++cp;
|
||||
if(c == 'x' || c == 'X')
|
||||
base = 16, c = *++cp;
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
while(1) {
|
||||
if(isascii(c) && isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
c = *++cp;
|
||||
} else if(base == 16 && isascii(c) && isxdigit(c)) {
|
||||
val = (val << 4) |
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if(c == '.') {
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16 bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if(pp >= parts + 3)
|
||||
return (0);
|
||||
*pp++ = val;
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0 )
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( WSAGetLastError() == WSAEINVAL )
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if(c != '\0' && (!isascii(c) || !isspace(c)))
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch(n) {
|
||||
|
||||
case 0:
|
||||
return (0); /* initial nondigit */
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if((val > 0xffffff) || (parts[0] > 0xff))
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if((val > 0xff) || (parts[0] > 0xff) ||
|
||||
(parts[1] > 0xff) || (parts[2] > 0xff))
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if(addr)
|
||||
addr->s_addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
win32_sleep(unsigned int seconds)
|
||||
{
|
||||
Sleep(seconds * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int win32_poll(struct pollfd *fds, int nfsd, int timeout)
|
||||
{
|
||||
fd_set rfds, wfds, efds;
|
||||
int ret;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&efds);
|
||||
if (fds->events & POLLIN)
|
||||
{
|
||||
FD_SET(fds->fd, &rfds);
|
||||
}
|
||||
if (fds->events & POLLOUT)
|
||||
{
|
||||
FD_SET(fds->fd, &wfds);
|
||||
}
|
||||
FD_SET(fds->fd, &efds);
|
||||
ret = select(fds->fd + 1, &rfds, &wfds, &efds, NULL);
|
||||
fds->revents = 0;
|
||||
|
||||
if (FD_ISSET(fds->fd, &rfds))
|
||||
{
|
||||
fds->revents |= POLLIN;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fds->fd, &wfds))
|
||||
{
|
||||
fds->revents |= POLLOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fds->fd, &efds))
|
||||
{
|
||||
fds->revents |= POLLHUP;
|
||||
}
|
||||
free(srcNonConst);
|
||||
memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
||||
int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
||||
{
|
||||
struct timeval timeout, *toptr;
|
||||
fd_set ifds, ofds, efds, *ip, *op;
|
||||
int i, rc;
|
||||
struct timeval timeout, *toptr;
|
||||
fd_set ifds, ofds, efds, *ip, *op;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
// Set up the file-descriptor sets in ifds, ofds and efds.
|
||||
FD_ZERO(&ifds);
|
||||
FD_ZERO(&ofds);
|
||||
FD_ZERO(&efds);
|
||||
for (i = 0, op = ip = 0; i < nfds; ++i) {
|
||||
fds[i].revents = 0;
|
||||
if(fds[i].events & (POLLIN|POLLPRI)) {
|
||||
ip = &ifds;
|
||||
FD_SET(fds[i].fd, ip);
|
||||
}
|
||||
if(fds[i].events & POLLOUT) {
|
||||
op = &ofds;
|
||||
FD_SET(fds[i].fd, op);
|
||||
}
|
||||
FD_SET(fds[i].fd, &efds);
|
||||
}
|
||||
|
||||
// Set up the timeval structure for the timeout parameter
|
||||
if(timo < 0) {
|
||||
toptr = 0;
|
||||
} else {
|
||||
toptr = &timeout;
|
||||
timeout.tv_sec = timo / 1000;
|
||||
timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
|
||||
// Set up the file-descriptor sets in ifds, ofds and efds.
|
||||
FD_ZERO(&ifds);
|
||||
FD_ZERO(&ofds);
|
||||
FD_ZERO(&efds);
|
||||
for (i = 0, op = ip = 0; i < nfds; ++i)
|
||||
{
|
||||
fds[i].revents = 0;
|
||||
if(fds[i].events & (POLLIN|POLLPRI))
|
||||
{
|
||||
ip = &ifds;
|
||||
FD_SET(fds[i].fd, ip);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_POLL
|
||||
printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
|
||||
(long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
|
||||
#endif
|
||||
rc = select(0, ip, op, &efds, toptr);
|
||||
#ifdef DEBUG_POLL
|
||||
printf("Exiting select rc=%d\n", rc);
|
||||
#endif
|
||||
|
||||
if(rc <= 0)
|
||||
return rc;
|
||||
|
||||
if(rc > 0) {
|
||||
for (i = 0; i < nfds; ++i) {
|
||||
int fd = fds[i].fd;
|
||||
if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
|
||||
fds[i].revents |= POLLIN;
|
||||
if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
if(FD_ISSET(fd, &efds))
|
||||
// Some error was detected ... should be some way to know.
|
||||
fds[i].revents |= POLLHUP;
|
||||
#ifdef DEBUG_POLL
|
||||
printf("%d %d %d revent = %x\n",
|
||||
FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
|
||||
fds[i].revents
|
||||
);
|
||||
#endif
|
||||
}
|
||||
if(fds[i].events & POLLOUT)
|
||||
{
|
||||
op = &ofds;
|
||||
FD_SET(fds[i].fd, op);
|
||||
}
|
||||
FD_SET(fds[i].fd, &efds);
|
||||
}
|
||||
|
||||
// Set up the timeval structure for the timeout parameter
|
||||
if(timo < 0)
|
||||
{
|
||||
toptr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
toptr = &timeout;
|
||||
timeout.tv_sec = timo / 1000;
|
||||
timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_POLL
|
||||
printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
|
||||
(long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
|
||||
#endif
|
||||
rc = select(0, ip, op, &efds, toptr);
|
||||
#ifdef DEBUG_POLL
|
||||
printf("Exiting select rc=%d\n", rc);
|
||||
#endif
|
||||
|
||||
if(rc <= 0)
|
||||
return rc;
|
||||
}
|
||||
*/
|
||||
|
||||
if(rc > 0)
|
||||
{
|
||||
for (i = 0; i < nfds; ++i)
|
||||
{
|
||||
int fd = fds[i].fd;
|
||||
if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
|
||||
fds[i].revents |= POLLIN;
|
||||
if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know.
|
||||
fds[i].revents |= POLLHUP;
|
||||
#ifdef DEBUG_POLL
|
||||
printf("%d %d %d revent = %x\n",
|
||||
FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
|
||||
fds[i].revents
|
||||
);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif
|
||||
|
||||
struct timezone
|
||||
{
|
||||
int tz_minuteswest; /* minutes W of Greenwich */
|
||||
int tz_dsttime; /* type of dst correction */
|
||||
};
|
||||
|
||||
int win32_gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
FILETIME ft;
|
||||
unsigned __int64 tmpres = 0;
|
||||
static int tzflag;
|
||||
|
||||
if (NULL != tv)
|
||||
{
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
|
||||
/*converting file time to unix epoch*/
|
||||
tmpres -= DELTA_EPOCH_IN_MICROSECS;
|
||||
tmpres /= 10; /*convert into microseconds*/
|
||||
tv->tv_sec = (long)(tmpres / 1000000UL);
|
||||
tv->tv_usec = (long)(tmpres % 1000000UL);
|
||||
}
|
||||
|
||||
if (NULL != tz)
|
||||
{
|
||||
if (!tzflag)
|
||||
{
|
||||
_tzset();
|
||||
tzflag++;
|
||||
}
|
||||
tz->tz_minuteswest = _timezone / 60;
|
||||
tz->tz_dsttime = _daylight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <Ws2ipdef.h>
|
||||
#include <basetsd.h>
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -37,7 +38,6 @@ typedef int uid_t;
|
|||
typedef int gid_t;
|
||||
typedef int socklen_t;
|
||||
|
||||
|
||||
#define S_IRUSR 0000400
|
||||
#define S_IWUSR 0000200
|
||||
#define S_IXUSR 0000100
|
||||
|
@ -74,11 +74,10 @@ struct pollfd {
|
|||
|
||||
/* Wrapper macros to call misc. functions win32 is missing */
|
||||
#define poll(x, y, z) win32_poll(x, y, z)
|
||||
#define inet_aton(x, y) win32_inet_aton(x, y)
|
||||
#define inet_pton(x,y,z) win32_inet_pton(x,y,z)
|
||||
int win32_inet_aton(const char *, struct in_addr *);
|
||||
int win32_inet_pton(int af, const char * src, void * dst);
|
||||
int win32_poll(struct pollfd *fds, int nfsd, int timeout);
|
||||
int win32_poll(struct pollfd *fds, unsigned int nfsd, int timeout);
|
||||
int win32_gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
|
||||
#endif//win32_COMPAT_H_
|
||||
#endif//WIN32
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef WIN32_ERRNOWRAPPER_H_
|
||||
#define WIN32_ERRNOWRAPPER_H_
|
||||
|
||||
#undef errno
|
||||
#define errno WSAGetLastError()
|
||||
#undef EAGAIN
|
||||
#undef EWOULDBLOCK
|
||||
#undef EINTR
|
||||
#undef EINPROGRESS
|
||||
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EAGAIN WSAEWOULDBLOCK //same on windows
|
||||
#define EINTR WSAEINTR
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#endif //WIN32_ERRNOWRAPPER_H_
|
Loading…
Reference in New Issue