2011-09-01 23:31:56 +04:00
|
|
|
/*
|
|
|
|
Copyright (c) 2006 by Dan Kennedy.
|
|
|
|
Copyright (c) 2006 by Juliusz Chroboczek.
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
|
2016-01-09 01:39:00 +03:00
|
|
|
static int dummy _U_;
|
2011-09-01 23:31:56 +04:00
|
|
|
|
|
|
|
#else
|
2018-04-16 22:38:38 +03:00
|
|
|
#include <win32/win32_compat.h>
|
2011-09-01 23:31:56 +04:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
2011-09-12 20:58:28 +04:00
|
|
|
|
2011-09-01 23:31:56 +04:00
|
|
|
#undef poll
|
|
|
|
#undef socket
|
|
|
|
#undef connect
|
|
|
|
#undef accept
|
|
|
|
#undef shutdown
|
|
|
|
#undef getpeername
|
|
|
|
#undef sleep
|
|
|
|
#undef inet_aton
|
|
|
|
#undef gettimeofday
|
|
|
|
#undef stat
|
|
|
|
#define assert(a)
|
|
|
|
|
|
|
|
/* Windows needs this header file for the implementation of inet_aton() */
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
int win32_inet_pton(int af, const char * src, void * dst)
|
|
|
|
{
|
2011-09-12 20:58:28 +04:00
|
|
|
struct sockaddr_in sa;
|
|
|
|
int len = sizeof(SOCKADDR);
|
|
|
|
int ret = -1;
|
2019-10-10 01:08:10 +03:00
|
|
|
size_t strLen = strlen(src) + 1;
|
2011-09-12 20:58:28 +04:00
|
|
|
#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
|
2011-09-01 23:31:56 +04:00
|
|
|
|
2011-09-12 20:58:28 +04:00
|
|
|
if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0 )
|
2011-09-01 23:31:56 +04:00
|
|
|
{
|
2011-09-12 20:58:28 +04:00
|
|
|
ret = 1;
|
2011-09-01 23:31:56 +04:00
|
|
|
}
|
2011-09-12 20:58:28 +04:00
|
|
|
else
|
2011-09-01 23:31:56 +04:00
|
|
|
{
|
2011-09-12 20:58:28 +04:00
|
|
|
if( WSAGetLastError() == WSAEINVAL )
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
}
|
2011-09-01 23:31:56 +04:00
|
|
|
}
|
2011-09-12 20:58:28 +04:00
|
|
|
free(srcNonConst);
|
|
|
|
memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));
|
2011-09-01 23:31:56 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-09-12 20:58:28 +04:00
|
|
|
int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
2011-09-01 23:31:56 +04:00
|
|
|
{
|
2011-09-12 20:58:28 +04:00
|
|
|
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);
|
2011-09-01 23:31:56 +04:00
|
|
|
}
|
2011-09-12 20:58:28 +04:00
|
|
|
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;
|
|
|
|
}
|
2011-09-01 23:31:56 +04:00
|
|
|
|
|
|
|
#ifdef DEBUG_POLL
|
2011-09-12 20:58:28 +04:00
|
|
|
printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
|
|
|
|
(long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
|
2011-09-01 23:31:56 +04:00
|
|
|
#endif
|
2011-09-12 20:58:28 +04:00
|
|
|
rc = select(0, ip, op, &efds, toptr);
|
2011-09-01 23:31:56 +04:00
|
|
|
#ifdef DEBUG_POLL
|
2011-09-12 20:58:28 +04:00
|
|
|
printf("Exiting select rc=%d\n", rc);
|
2011-09-01 23:31:56 +04:00
|
|
|
#endif
|
|
|
|
|
2011-09-12 20:58:28 +04:00
|
|
|
if(rc <= 0)
|
|
|
|
return rc;
|
2011-09-01 23:31:56 +04:00
|
|
|
|
2011-09-12 20:58:28 +04:00
|
|
|
if(rc > 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < nfds; ++i)
|
|
|
|
{
|
2019-09-12 23:07:35 +03:00
|
|
|
SOCKET fd = fds[i].fd;
|
2011-09-12 20:58:28 +04:00
|
|
|
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;
|
2011-09-01 23:31:56 +04:00
|
|
|
#ifdef DEBUG_POLL
|
2011-09-12 20:58:28 +04:00
|
|
|
printf("%d %d %d revent = %x\n",
|
|
|
|
FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
|
|
|
|
fds[i].revents
|
|
|
|
);
|
2011-09-01 23:31:56 +04:00
|
|
|
#endif
|
|
|
|
}
|
2011-09-12 20:58:28 +04:00
|
|
|
}
|
|
|
|
return rc;
|
2011-09-01 23:31:56 +04:00
|
|
|
}
|
2011-09-12 20:58:28 +04:00
|
|
|
|
|
|
|
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
|
|
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
|
|
|
#else
|
|
|
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
|
|
|
#endif
|
|
|
|
|
2016-01-09 00:35:29 +03:00
|
|
|
#ifndef __MINGW32__
|
2011-09-12 20:58:28 +04:00
|
|
|
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;
|
|
|
|
}
|
2021-10-03 15:51:42 +03:00
|
|
|
#endif
|
2011-09-12 20:58:28 +04:00
|
|
|
|
2021-10-03 15:51:42 +03:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
char* strndup(const char* s, size_t n)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
for(len=0; len<n && s[len]; len++);
|
|
|
|
len += 1;
|
|
|
|
if(!len)
|
|
|
|
return 0;
|
|
|
|
char* copy = malloc(len);
|
|
|
|
if(!copy)
|
|
|
|
return 0;
|
|
|
|
memcpy(copy, s, len-1);
|
|
|
|
copy[len-1] = 0;
|
|
|
|
return copy;
|
|
|
|
}
|
2011-09-01 23:31:56 +04:00
|
|
|
#endif
|
2021-10-03 15:51:42 +03:00
|
|
|
|
2016-01-09 00:35:29 +03:00
|
|
|
#endif
|