Merge branch 'unstable' of git://github.com/diegonehab/luasocket into moteus-lua52
This commit is contained in:
commit
5167ddaf49
13 changed files with 435 additions and 166 deletions
78
src/inet.c
78
src/inet.c
|
@ -79,24 +79,22 @@ static int inet_global_tohostname(lua_State *L) {
|
|||
}
|
||||
|
||||
static int inet_global_getnameinfo(lua_State *L) {
|
||||
char hbuf[NI_MAXHOST];
|
||||
char sbuf[NI_MAXSERV];
|
||||
int i, ret;
|
||||
char host[1024];
|
||||
char serv[32];
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *resolved, *iter;
|
||||
const char *node = luaL_optstring(L, 1, NULL);
|
||||
const char *service = luaL_optstring(L, 2, NULL);
|
||||
const char *host = luaL_optstring(L, 1, NULL);
|
||||
const char *serv = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (!(node || service))
|
||||
luaL_error(L, "You have to specify a hostname, a service, or both");
|
||||
if (!(host || serv))
|
||||
luaL_error(L, "host and serv cannot be both nil");
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
|
||||
/* getaddrinfo must get a node and a service argument */
|
||||
ret = getaddrinfo(node ? node : "127.0.0.1", service ? service : "7",
|
||||
&hints, &resolved);
|
||||
ret = getaddrinfo(host, serv, &hints, &resolved);
|
||||
if (ret != 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, socket_gaistrerror(ret));
|
||||
|
@ -105,19 +103,19 @@ static int inet_global_getnameinfo(lua_State *L) {
|
|||
|
||||
lua_newtable(L);
|
||||
for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) {
|
||||
getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, host,
|
||||
node ? (socklen_t) sizeof(host) : 0, serv, service ? (socklen_t) sizeof(serv) : 0, 0);
|
||||
|
||||
if (node) {
|
||||
getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen,
|
||||
hbuf, host? (socklen_t) sizeof(hbuf): 0,
|
||||
sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0);
|
||||
if (host) {
|
||||
lua_pushnumber(L, i);
|
||||
lua_pushstring(L, host);
|
||||
lua_pushstring(L, hbuf);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
}
|
||||
freeaddrinfo(resolved);
|
||||
|
||||
if (service) {
|
||||
lua_pushstring(L, serv);
|
||||
if (serv) {
|
||||
lua_pushstring(L, sbuf);
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
|
@ -176,20 +174,10 @@ static int inet_global_getaddrinfo(lua_State *L)
|
|||
}
|
||||
lua_newtable(L);
|
||||
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
|
||||
char hbuf[NI_MAXHOST]
|
||||
#ifndef _WINDOWS
|
||||
,sbuf[NI_MAXSERV]
|
||||
#endif
|
||||
;
|
||||
ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, hbuf,
|
||||
(socklen_t) sizeof(hbuf),
|
||||
#ifdef _WINDOWS
|
||||
NULL, 0,
|
||||
#else
|
||||
sbuf, 0,
|
||||
#endif
|
||||
NI_NUMERICHOST);
|
||||
if(ret){
|
||||
char hbuf[NI_MAXHOST];
|
||||
ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
|
||||
hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
|
||||
if (ret){
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, socket_gaistrerror(ret));
|
||||
return 2;
|
||||
|
@ -218,7 +206,6 @@ static int inet_global_getaddrinfo(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Gets the host name
|
||||
\*-------------------------------------------------------------------------*/
|
||||
|
@ -237,7 +224,6 @@ static int inet_global_gethostname(lua_State *L)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*=========================================================================*\
|
||||
* Lua methods
|
||||
\*=========================================================================*/
|
||||
|
@ -520,7 +506,7 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv,
|
|||
* Some systems do not provide this so that we provide our own. It's not
|
||||
* marvelously fast, but it works just fine.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
#ifdef INET_ATON
|
||||
#ifdef LUASOCKET_INET_ATON
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
unsigned int a = 0, b = 0, c = 0, d = 0;
|
||||
|
@ -547,7 +533,7 @@ int inet_aton(const char *cp, struct in_addr *inp)
|
|||
* http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
|
||||
\*-------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef INET_PTON
|
||||
#ifdef LUASOCKET_INET_PTON
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
|
||||
{
|
||||
if (af == AF_INET) {
|
||||
|
@ -572,19 +558,23 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
|
|||
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
struct addrinfo hints, *res;
|
||||
int ret = 1;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = af;
|
||||
if (getaddrinfo(src, NULL, &hints, &res) != 0) {
|
||||
return -1;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
|
||||
if (af == AF_INET) {
|
||||
struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
|
||||
memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
|
||||
} else if (af == AF_INET6) {
|
||||
struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
|
||||
memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
ressave = res;
|
||||
while (res) {
|
||||
memcpy(dst, res->ai_addr, res->ai_addrlen);
|
||||
res = res->ai_next;
|
||||
}
|
||||
freeaddrinfo(ressave);
|
||||
return 0;
|
||||
freeaddrinfo(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
#include "timeout.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define INET_ATON
|
||||
#define INET_PTON
|
||||
#define LUASOCKET_INET_ATON
|
||||
#endif
|
||||
|
||||
int inet_open(lua_State *L);
|
||||
|
@ -39,11 +38,11 @@ int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
|
|||
int inet_optfamily(lua_State* L, int narg, const char* def);
|
||||
int inet_optsocktype(lua_State* L, int narg, const char* def);
|
||||
|
||||
#ifdef INET_ATON
|
||||
#ifdef LUASOCKET_INET_ATON
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
#endif
|
||||
|
||||
#ifdef INET_PTON
|
||||
#ifdef LUASOCKET_INET_PTON
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
|
2
src/io.h
2
src/io.h
|
@ -22,7 +22,7 @@ enum {
|
|||
IO_DONE = 0, /* operation completed successfully */
|
||||
IO_TIMEOUT = -1, /* operation timed out */
|
||||
IO_CLOSED = -2, /* the connection has been closed */
|
||||
IO_UNKNOWN = -3
|
||||
IO_UNKNOWN = -3
|
||||
};
|
||||
|
||||
/* interface to error message function */
|
||||
|
|
41
src/makefile
41
src/makefile
|
@ -63,12 +63,13 @@ LDIR_mingw?=lua/$(LUAV)/lua
|
|||
# LUAINC_win32:
|
||||
# LUALIB_win32:
|
||||
# where lua headers and libraries are found for win32 builds
|
||||
LUAINC_win32?="../../lua-5.1.3/src"
|
||||
LUALIB_win32?=/LIBPATH:"../../lua-5.1.3" lua$(LUAV).lib
|
||||
|
||||
LUAINC_win32_base?=
|
||||
LUAINC_win32?=$(LUAINC_win32_base)/lua/$(LUAV)
|
||||
PLATFORM_win32?=Release
|
||||
LUAPREFIX_win32?=
|
||||
CDIR_win32?=lua/$(LUAV)
|
||||
LDIR_win32?=lua/$(LUAV)/lua
|
||||
CDIR_win32?=lua/$(LUAV)/$(PLATFORM_win32)
|
||||
LDIR_win32?=lua/$(LUAV)/$(PLATFORM_win32)/lua
|
||||
LUALIB_win32?=$(LUAPREFIX_win32)/lua/$(LUAV)/$(PLATFORM_win32)
|
||||
|
||||
# prefix: /usr/local /usr /opt/local /sw
|
||||
# the top of the default install tree
|
||||
|
@ -154,12 +155,12 @@ SOCKET_linux=usocket.o
|
|||
SO_mingw=dll
|
||||
O_mingw=o
|
||||
CC_mingw=gcc
|
||||
DEF_mingw= -DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE -DWINVER=0x0501 \
|
||||
-DLUASOCKET_API='__declspec(dllexport)' \
|
||||
DEF_mingw= -DLUASOCKET_INET_PTON -DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE \
|
||||
-DWINVER=0x0501 -DLUASOCKET_API='__declspec(dllexport)' \
|
||||
-DMIME_API='__declspec(dllexport)'
|
||||
CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \
|
||||
-fvisibility=hidden
|
||||
LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lwsock32 -lws2_32 -o
|
||||
LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
|
||||
LD_mingw=gcc
|
||||
SOCKET_mingw=wsocket.o
|
||||
|
||||
|
@ -170,23 +171,25 @@ SOCKET_mingw=wsocket.o
|
|||
SO_win32=dll
|
||||
O_win32=obj
|
||||
CC_win32=cl
|
||||
DEF_win32= /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" \
|
||||
/D "LUASOCKET_API=__declspec(dllexport)" /D "_CRT_SECURE_NO_WARNINGS" \
|
||||
/D "_WINDLL" /D "LUA_COMPAT_MODULE" /D "MIME_API=__declspec(dllexport)" \
|
||||
/D "LUASOCKET_$(DEBUG)"
|
||||
CFLAGS_win32=/I "$(LUAINC)" $(DEF) /O2 /Ot /MD /W3 /nologo
|
||||
LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \
|
||||
/MANIFEST /MANIFESTFILE:"intermediate.manifest" \
|
||||
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
|
||||
/SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /DYNAMICBASE:NO \
|
||||
/MACHINE:X86 $(LUALIB) ws2_32.lib /OUT:
|
||||
DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \
|
||||
//D "LUASOCKET_API=__declspec(dllexport)" //D "_CRT_SECURE_NO_WARNINGS" \
|
||||
//D "_WINDLL" //D "LUA_COMPAT_MODULE" \
|
||||
//D "MIME_API=__declspec(dllexport)" \
|
||||
//D "LUASOCKET_$(DEBUG)"
|
||||
CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo
|
||||
LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
|
||||
//MANIFEST //MANIFESTFILE:"intermediate.manifest" \
|
||||
//MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
|
||||
//SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \
|
||||
//MACHINE:X86 /LIBPATH:"$(shell cmd //c echo $(LUALIB))" \
|
||||
lua$(subst .,,$(LUAV)).lib ws2_32.lib //OUT:
|
||||
LD_win32=cl
|
||||
SOCKET_win32=wsocket.obj
|
||||
|
||||
.SUFFIXES: .obj
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" /c $<
|
||||
$(CC) $(CFLAGS) //Fo"$@" //c $<
|
||||
|
||||
#------
|
||||
# Output file names
|
||||
|
|
122
src/udp.c
122
src/udp.c
|
@ -155,31 +155,31 @@ static int meth_sendto(lua_State *L) {
|
|||
p_timeout tm = &udp->tm;
|
||||
int err;
|
||||
switch (udp->family) {
|
||||
case PF_INET: {
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
if (!inet_pton(AF_INET, ip, &addr.sin_addr))
|
||||
case PF_INET: {
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1)
|
||||
luaL_argerror(L, 3, "invalid ip address");
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
timeout_markstart(tm);
|
||||
err = socket_sendto(&udp->sock, data, count, &sent,
|
||||
(SA *) &addr, sizeof(addr), tm);
|
||||
break;
|
||||
}
|
||||
case PF_INET6: {
|
||||
struct sockaddr_in6 addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
if (!inet_pton(AF_INET6, ip, &addr.sin6_addr))
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
timeout_markstart(tm);
|
||||
err = socket_sendto(&udp->sock, data, count, &sent,
|
||||
(SA *) &addr, sizeof(addr), tm);
|
||||
break;
|
||||
}
|
||||
case PF_INET6: {
|
||||
struct sockaddr_in6 addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
if (inet_pton(AF_INET6, ip, &addr.sin6_addr) != 1)
|
||||
luaL_argerror(L, 3, "invalid ip address");
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = htons(port);
|
||||
timeout_markstart(tm);
|
||||
err = socket_sendto(&udp->sock, data, count, &sent,
|
||||
(SA *) &addr, sizeof(addr), tm);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = htons(port);
|
||||
timeout_markstart(tm);
|
||||
err = socket_sendto(&udp->sock, data, count, &sent,
|
||||
(SA *) &addr, sizeof(addr), tm);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unknown family %d", udp->family);
|
||||
return 2;
|
||||
|
@ -229,38 +229,40 @@ static int meth_receivefrom(lua_State *L) {
|
|||
timeout_markstart(tm);
|
||||
count = MIN(count, sizeof(buffer));
|
||||
switch (udp->family) {
|
||||
case PF_INET: {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
err = socket_recvfrom(&udp->sock, buffer, count, &got,
|
||||
(SA *) &addr, &addr_len, tm);
|
||||
/* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
|
||||
if (err == IO_CLOSED)
|
||||
err = IO_DONE;
|
||||
if (err == IO_DONE) {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
lua_pushlstring(L, buffer, got);
|
||||
if (!inet_ntop(AF_INET, &addr.sin_addr,
|
||||
addrstr, sizeof(addrstr))) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "invalid source address");
|
||||
return 2;
|
||||
}
|
||||
lua_pushstring(L, addrstr);
|
||||
lua_pushnumber(L, ntohs(addr.sin_port));
|
||||
return 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PF_INET6: {
|
||||
struct sockaddr_in6 addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
err = socket_recvfrom(&udp->sock, buffer, count, &got,
|
||||
(SA *) &addr, &addr_len, tm);
|
||||
/* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
|
||||
if (err == IO_CLOSED)
|
||||
case PF_INET: {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
err = socket_recvfrom(&udp->sock, buffer, count, &got,
|
||||
(SA *) &addr, &addr_len, tm);
|
||||
/* Unlike TCP, recv() of zero is not closed,
|
||||
* but a zero-length packet. */
|
||||
if (err == IO_CLOSED)
|
||||
err = IO_DONE;
|
||||
if (err == IO_DONE) {
|
||||
if (err == IO_DONE) {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
lua_pushlstring(L, buffer, got);
|
||||
if (!inet_ntop(AF_INET, &addr.sin_addr,
|
||||
addrstr, sizeof(addrstr))) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "invalid source address");
|
||||
return 2;
|
||||
}
|
||||
lua_pushstring(L, addrstr);
|
||||
lua_pushnumber(L, ntohs(addr.sin_port));
|
||||
return 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PF_INET6: {
|
||||
struct sockaddr_in6 addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
err = socket_recvfrom(&udp->sock, buffer, count, &got,
|
||||
(SA *) &addr, &addr_len, tm);
|
||||
/* Unlike TCP, recv() of zero is not closed,
|
||||
* but a zero-length packet. */
|
||||
if (err == IO_CLOSED)
|
||||
err = IO_DONE;
|
||||
if (err == IO_DONE) {
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
lua_pushlstring(L, buffer, got);
|
||||
if (!inet_ntop(AF_INET6, &addr.sin6_addr,
|
||||
|
@ -272,9 +274,9 @@ static int meth_receivefrom(lua_State *L) {
|
|||
lua_pushstring(L, addrstr);
|
||||
lua_pushnumber(L, ntohs(addr.sin6_port));
|
||||
return 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unknown family %d", udp->family);
|
||||
|
@ -413,7 +415,7 @@ static int meth_setsockname(lua_State *L) {
|
|||
const char *address = luaL_checkstring(L, 2);
|
||||
const char *port = luaL_checkstring(L, 3);
|
||||
const char *err;
|
||||
struct addrinfo bindhints;
|
||||
struct addrinfo bindhints;
|
||||
memset(&bindhints, 0, sizeof(bindhints));
|
||||
bindhints.ai_socktype = SOCK_DGRAM;
|
||||
bindhints.ai_family = udp->family;
|
||||
|
@ -461,9 +463,9 @@ static int udp_create(lua_State *L, int family) {
|
|||
}
|
||||
|
||||
static int global_create(lua_State *L) {
|
||||
return udp_create(L, AF_INET);
|
||||
return udp_create(L, AF_INET);
|
||||
}
|
||||
|
||||
static int global_create6(lua_State *L) {
|
||||
return udp_create(L, AF_INET6);
|
||||
return udp_create(L, AF_INET6);
|
||||
}
|
||||
|
|
|
@ -238,8 +238,10 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
|
|||
/*-------------------------------------------------------------------------*\
|
||||
* Receive with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
|
||||
int err;
|
||||
int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||
p_timeout tm)
|
||||
{
|
||||
int err, prev = IO_DONE;
|
||||
*got = 0;
|
||||
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
||||
for ( ;; ) {
|
||||
|
@ -250,7 +252,14 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
|
|||
}
|
||||
if (taken == 0) return IO_CLOSED;
|
||||
err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) return err;
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
* On TCP, it means our socket is now useless, so the error passes.
|
||||
* (We will loop again, exiting because the same error will happen) */
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
|
||||
prev = err;
|
||||
}
|
||||
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
||||
}
|
||||
}
|
||||
|
@ -259,8 +268,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
|
|||
* Recvfrom with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
||||
SA *addr, socklen_t *len, p_timeout tm) {
|
||||
int err;
|
||||
SA *addr, socklen_t *len, p_timeout tm)
|
||||
{
|
||||
int err, prev = IO_DONE;
|
||||
*got = 0;
|
||||
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
||||
for ( ;; ) {
|
||||
|
@ -271,7 +281,14 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
|||
}
|
||||
if (taken == 0) return IO_CLOSED;
|
||||
err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) return err;
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
* On TCP, it means our socket is now useless, so the error passes.
|
||||
* (We will loop again, exiting because the same error will happen) */
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
|
||||
prev = err;
|
||||
}
|
||||
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue