mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +01:00
Killed a few bugs found by Tomas.
This commit is contained in:
parent
9bc4e0648a
commit
3febb302ad
12
TODO
12
TODO
@ -1,3 +1,15 @@
|
|||||||
|
replace times by getrusage
|
||||||
|
|
||||||
|
make sure modules know if their dependencies are there.
|
||||||
|
|
||||||
|
one thing i noticed in usocket.c is that it doesn't check for EINTR
|
||||||
|
after write(), sendto(), read(), recvfrom() etc. ? the usual trick is
|
||||||
|
to loop while you get EINTR:
|
||||||
|
|
||||||
|
do
|
||||||
|
ret = write(...);
|
||||||
|
while(ret < 0 && errno == EINTR)
|
||||||
|
|
||||||
|
|
||||||
Read about
|
Read about
|
||||||
|
|
||||||
|
@ -138,7 +138,8 @@ int sendraw(p_buf buf, const char *data, size_t count, size_t *sent)
|
|||||||
int err = IO_DONE;
|
int err = IO_DONE;
|
||||||
while (total < count && err == IO_DONE) {
|
while (total < count && err == IO_DONE) {
|
||||||
size_t done;
|
size_t done;
|
||||||
err = io->send(io->ctx, data+total, count-total, &done, tm_get(tm));
|
err = io->send(io->ctx, data+total, count-total, &done,
|
||||||
|
tm_getsuccess(tm));
|
||||||
total += done;
|
total += done;
|
||||||
}
|
}
|
||||||
*sent = total;
|
*sent = total;
|
||||||
@ -239,7 +240,8 @@ int buf_get(p_buf buf, const char **data, size_t *count)
|
|||||||
p_tm tm = buf->tm;
|
p_tm tm = buf->tm;
|
||||||
if (buf_isempty(buf)) {
|
if (buf_isempty(buf)) {
|
||||||
size_t got;
|
size_t got;
|
||||||
err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm_get(tm));
|
err = io->recv(io->ctx, buf->data, BUF_SIZE, &got,
|
||||||
|
tm_getsuccess(tm));
|
||||||
buf->first = 0;
|
buf->first = 0;
|
||||||
buf->last = got;
|
buf->last = got;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ Public.TIMEOUT = 60
|
|||||||
-- default port for document retrieval
|
-- default port for document retrieval
|
||||||
Public.PORT = 80
|
Public.PORT = 80
|
||||||
-- user agent field sent in request
|
-- user agent field sent in request
|
||||||
Public.USERAGENT = "LuaSocket 1.5"
|
Public.USERAGENT = "LuaSocket 2.0"
|
||||||
-- block size used in transfers
|
-- block size used in transfers
|
||||||
Public.BLOCKSIZE = 8192
|
Public.BLOCKSIZE = 8192
|
||||||
|
|
||||||
@ -193,7 +193,8 @@ function Private.receivebody_bylength(sock, length, receive_cb)
|
|||||||
while length > 0 do
|
while length > 0 do
|
||||||
local size = math.min(Public.BLOCKSIZE, length)
|
local size = math.min(Public.BLOCKSIZE, length)
|
||||||
local chunk, err = sock:receive(size)
|
local chunk, err = sock:receive(size)
|
||||||
if err then
|
-- if there was an error before we got all the data
|
||||||
|
if err and string.len(chunk) ~= length then
|
||||||
go, uerr = receive_cb(nil, err)
|
go, uerr = receive_cb(nil, err)
|
||||||
return uerr or err
|
return uerr or err
|
||||||
end
|
end
|
||||||
|
16
src/tcp.c
16
src/tcp.c
@ -198,21 +198,21 @@ static int meth_accept(lua_State *L)
|
|||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
socklen_t addr_len = sizeof(addr);
|
socklen_t addr_len = sizeof(addr);
|
||||||
|
int err = IO_ERROR;
|
||||||
p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1);
|
p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1);
|
||||||
p_tm tm = &server->tm;
|
p_tm tm = &server->tm;
|
||||||
p_tcp client = lua_newuserdata(L, sizeof(t_tcp));
|
p_tcp client = lua_newuserdata(L, sizeof(t_tcp));
|
||||||
tm_markstart(tm);
|
|
||||||
aux_setclass(L, "tcp{client}", -1);
|
aux_setclass(L, "tcp{client}", -1);
|
||||||
for ( ;; ) {
|
tm_markstart(tm);
|
||||||
sock_accept(&server->sock, &client->sock,
|
/* loop until connection accepted or timeout happens */
|
||||||
(SA *) &addr, &addr_len, tm_get(tm));
|
while (err != IO_DONE) {
|
||||||
if (client->sock == SOCK_INVALID) {
|
err = sock_accept(&server->sock, &client->sock,
|
||||||
if (tm_get(tm) == 0) {
|
(SA *) &addr, &addr_len, tm_getfailure(tm));
|
||||||
|
if (err == IO_CLOSED || (err == IO_TIMEOUT && !tm_getfailure(tm))) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
io_pusherror(L, IO_TIMEOUT);
|
io_pusherror(L, err);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
} else break;
|
|
||||||
}
|
}
|
||||||
/* initialize remaining structure fields */
|
/* initialize remaining structure fields */
|
||||||
io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock);
|
io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock);
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -46,40 +46,62 @@ void tm_init(p_tm tm, int block, int total)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Set and get timeout limits
|
* Determines how much time we have left for the next system call,
|
||||||
\*-------------------------------------------------------------------------*/
|
* if the previous call was successful
|
||||||
void tm_setblock(p_tm tm, int block)
|
|
||||||
{ tm->block = block; }
|
|
||||||
void tm_settotal(p_tm tm, int total)
|
|
||||||
{ tm->total = total; }
|
|
||||||
int tm_getblock(p_tm tm)
|
|
||||||
{ return tm->block; }
|
|
||||||
int tm_gettotal(p_tm tm)
|
|
||||||
{ return tm->total; }
|
|
||||||
int tm_getstart(p_tm tm)
|
|
||||||
{ return tm->start; }
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Determines how much time we have left for the current operation
|
|
||||||
* Input
|
* Input
|
||||||
* tm: timeout control structure
|
* tm: timeout control structure
|
||||||
* Returns
|
* Returns
|
||||||
* the number of ms left or -1 if there is no time limit
|
* the number of ms left or -1 if there is no time limit
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int tm_get(p_tm tm)
|
int tm_getsuccess(p_tm tm)
|
||||||
{
|
{
|
||||||
/* no timeout */
|
if (tm->block < 0 && tm->total < 0) {
|
||||||
if (tm->block < 0 && tm->total < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
/* there is no block timeout, we use the return timeout */
|
} else if (tm->block < 0) {
|
||||||
else if (tm->block < 0)
|
int t = tm->total - tm_gettime() + tm->start;
|
||||||
return MAX(tm->total - tm_gettime() + tm->start, 0);
|
return MAX(t, 0);
|
||||||
/* there is no return timeout, we use the block timeout */
|
} else if (tm->total < 0) {
|
||||||
else if (tm->total < 0)
|
|
||||||
return tm->block;
|
return tm->block;
|
||||||
/* both timeouts are specified */
|
} else {
|
||||||
else return MIN(tm->block,
|
int t = tm->total - tm_gettime() + tm->start;
|
||||||
MAX(tm->total - tm_gettime() + tm->start, 0));
|
return MIN(tm->block, MAX(t, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Returns time since start of operation
|
||||||
|
* Input
|
||||||
|
* tm: timeout control structure
|
||||||
|
* Returns
|
||||||
|
* start field of structure
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
int tm_getstart(p_tm tm)
|
||||||
|
{
|
||||||
|
return tm->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Determines how much time we have left for the next system call,
|
||||||
|
* if the previous call was a failure
|
||||||
|
* Input
|
||||||
|
* tm: timeout control structure
|
||||||
|
* Returns
|
||||||
|
* the number of ms left or -1 if there is no time limit
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
int tm_getfailure(p_tm tm)
|
||||||
|
{
|
||||||
|
if (tm->block < 0 && tm->total < 0) {
|
||||||
|
return -1;
|
||||||
|
} else if (tm->block < 0) {
|
||||||
|
int t = tm->total - tm_gettime() + tm->start;
|
||||||
|
return MAX(t, 0);
|
||||||
|
} else if (tm->total < 0) {
|
||||||
|
int t = tm->block - tm_gettime() + tm->start;
|
||||||
|
return MAX(t, 0);
|
||||||
|
} else {
|
||||||
|
int t = tm->total - tm_gettime() + tm->start;
|
||||||
|
return MIN(tm->block, MAX(t, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
@ -131,10 +153,10 @@ int tm_meth_settimeout(lua_State *L, p_tm tm)
|
|||||||
const char *mode = luaL_optstring(L, 3, "b");
|
const char *mode = luaL_optstring(L, 3, "b");
|
||||||
switch (*mode) {
|
switch (*mode) {
|
||||||
case 'b':
|
case 'b':
|
||||||
tm_setblock(tm, ms);
|
tm->block = ms;
|
||||||
break;
|
break;
|
||||||
case 'r': case 't':
|
case 'r': case 't':
|
||||||
tm_settotal(tm, ms);
|
tm->total = ms;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
luaL_argcheck(L, 0, 3, "invalid timeout mode");
|
luaL_argcheck(L, 0, 3, "invalid timeout mode");
|
||||||
|
@ -18,13 +18,10 @@ typedef t_tm *p_tm;
|
|||||||
|
|
||||||
void tm_open(lua_State *L);
|
void tm_open(lua_State *L);
|
||||||
void tm_init(p_tm tm, int block, int total);
|
void tm_init(p_tm tm, int block, int total);
|
||||||
void tm_setblock(p_tm tm, int block);
|
int tm_getsuccess(p_tm tm);
|
||||||
void tm_settotal(p_tm tm, int total);
|
int tm_getfailure(p_tm tm);
|
||||||
int tm_getblock(p_tm tm);
|
|
||||||
int tm_gettotal(p_tm tm);
|
|
||||||
void tm_markstart(p_tm tm);
|
void tm_markstart(p_tm tm);
|
||||||
int tm_getstart(p_tm tm);
|
int tm_getstart(p_tm tm);
|
||||||
int tm_get(p_tm tm);
|
|
||||||
int tm_gettime(void);
|
int tm_gettime(void);
|
||||||
int tm_meth_settimeout(lua_State *L, p_tm tm);
|
int tm_meth_settimeout(lua_State *L, p_tm tm);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ static int meth_send(lua_State *L)
|
|||||||
int err;
|
int err;
|
||||||
const char *data = luaL_checklstring(L, 2, &count);
|
const char *data = luaL_checklstring(L, 2, &count);
|
||||||
tm_markstart(tm);
|
tm_markstart(tm);
|
||||||
err = sock_send(&udp->sock, data, count, &sent, tm_get(tm));
|
err = sock_send(&udp->sock, data, count, &sent, tm_getsuccess(tm));
|
||||||
if (err == IO_DONE) lua_pushnumber(L, sent);
|
if (err == IO_DONE) lua_pushnumber(L, sent);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
/* a 'closed' error on an unconnected means the target address was not
|
/* a 'closed' error on an unconnected means the target address was not
|
||||||
@ -129,7 +129,7 @@ static int meth_sendto(lua_State *L)
|
|||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
tm_markstart(tm);
|
tm_markstart(tm);
|
||||||
err = sock_sendto(&udp->sock, data, count, &sent,
|
err = sock_sendto(&udp->sock, data, count, &sent,
|
||||||
(SA *) &addr, sizeof(addr), tm_get(tm));
|
(SA *) &addr, sizeof(addr), tm_getsuccess(tm));
|
||||||
if (err == IO_DONE) lua_pushnumber(L, sent);
|
if (err == IO_DONE) lua_pushnumber(L, sent);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
/* a 'closed' error on an unconnected means the target address was not
|
/* a 'closed' error on an unconnected means the target address was not
|
||||||
@ -150,7 +150,7 @@ static int meth_receive(lua_State *L)
|
|||||||
p_tm tm = &udp->tm;
|
p_tm tm = &udp->tm;
|
||||||
count = MIN(count, sizeof(buffer));
|
count = MIN(count, sizeof(buffer));
|
||||||
tm_markstart(tm);
|
tm_markstart(tm);
|
||||||
err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm));
|
err = sock_recv(&udp->sock, buffer, count, &got, tm_getsuccess(tm));
|
||||||
if (err == IO_DONE) lua_pushlstring(L, buffer, got);
|
if (err == IO_DONE) lua_pushlstring(L, buffer, got);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
io_pusherror(L, err);
|
io_pusherror(L, err);
|
||||||
@ -172,7 +172,7 @@ static int meth_receivefrom(lua_State *L)
|
|||||||
tm_markstart(tm);
|
tm_markstart(tm);
|
||||||
count = MIN(count, sizeof(buffer));
|
count = MIN(count, sizeof(buffer));
|
||||||
err = sock_recvfrom(&udp->sock, buffer, count, &got,
|
err = sock_recvfrom(&udp->sock, buffer, count, &got,
|
||||||
(SA *) &addr, &addr_len, tm_get(tm));
|
(SA *) &addr, &addr_len, tm_getsuccess(tm));
|
||||||
if (err == IO_DONE) {
|
if (err == IO_DONE) {
|
||||||
lua_pushlstring(L, buffer, got);
|
lua_pushlstring(L, buffer, got);
|
||||||
lua_pushstring(L, inet_ntoa(addr.sin_addr));
|
lua_pushstring(L, inet_ntoa(addr.sin_addr));
|
||||||
|
@ -83,10 +83,12 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||||||
SA dummy_addr;
|
SA dummy_addr;
|
||||||
socklen_t dummy_len;
|
socklen_t dummy_len;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(sock, &fds);
|
FD_SET(sock, &fds);
|
||||||
|
*pa = SOCK_INVALID;
|
||||||
if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
|
if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
|
||||||
return IO_TIMEOUT;
|
return IO_TIMEOUT;
|
||||||
if (!addr) addr = &dummy_addr;
|
if (!addr) addr = &dummy_addr;
|
||||||
@ -108,6 +110,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
ssize_t put = 0;
|
ssize_t put = 0;
|
||||||
int err;
|
int err;
|
||||||
int ret;
|
int ret;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -145,6 +148,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
ssize_t put = 0;
|
ssize_t put = 0;
|
||||||
int err;
|
int err;
|
||||||
int ret;
|
int ret;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -180,6 +184,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
|||||||
fd_set fds;
|
fd_set fds;
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t taken = 0;
|
ssize_t taken = 0;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -210,6 +215,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int ret;
|
int ret;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
ssize_t taken = 0;
|
ssize_t taken = 0;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
@ -34,11 +34,6 @@
|
|||||||
/* TCP options (nagle algorithm disable) */
|
/* TCP options (nagle algorithm disable) */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
/* for some reason socklen_t is not defined in Mac Os X */
|
|
||||||
typedef int socklen_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int t_sock;
|
typedef int t_sock;
|
||||||
typedef t_sock *p_sock;
|
typedef t_sock *p_sock;
|
||||||
|
|
||||||
|
@ -86,10 +86,12 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||||||
SA dummy_addr;
|
SA dummy_addr;
|
||||||
socklen_t dummy_len;
|
socklen_t dummy_len;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(sock, &fds);
|
FD_SET(sock, &fds);
|
||||||
|
*pa = SOCK_INVALID;
|
||||||
if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
|
if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
|
||||||
return IO_TIMEOUT;
|
return IO_TIMEOUT;
|
||||||
if (!addr) addr = &dummy_addr;
|
if (!addr) addr = &dummy_addr;
|
||||||
@ -109,6 +111,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
ssize_t put = 0;
|
ssize_t put = 0;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
int err;
|
int err;
|
||||||
int ret;
|
int ret;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
@ -148,6 +151,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
ssize_t put = 0;
|
ssize_t put = 0;
|
||||||
int err;
|
int err;
|
||||||
int ret;
|
int ret;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -183,6 +187,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
|||||||
fd_set fds;
|
fd_set fds;
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t taken = 0;
|
ssize_t taken = 0;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -214,6 +219,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
|||||||
fd_set fds;
|
fd_set fds;
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t taken = 0;
|
ssize_t taken = 0;
|
||||||
|
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
|
Loading…
Reference in New Issue
Block a user