http.lua updated. still needs proxy support.
code.lua updated. looks neat.
This commit is contained in:
parent
3febb302ad
commit
89f3ecf782
10 changed files with 445 additions and 358 deletions
110
src/usocket.c
110
src/usocket.c
|
@ -72,6 +72,14 @@ void sock_listen(p_sock ps, int backlog)
|
|||
listen(*ps, backlog);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
*
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void sock_shutdown(p_sock ps, int how)
|
||||
{
|
||||
shutdown(*ps, how);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Accept with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
|
@ -100,39 +108,47 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Send with timeout
|
||||
* Here we exchanged the order of the calls to write and select
|
||||
* The idea is that the outer loop (whoever is calling sock_send)
|
||||
* will call the function again if we didn't time out, so we can
|
||||
* call write and then select only if it fails.
|
||||
* Should speed things up!
|
||||
* We are also treating EINTR and EPIPE errors.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
||||
int timeout)
|
||||
{
|
||||
t_sock sock = *ps;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
ssize_t put = 0;
|
||||
int err;
|
||||
ssize_t put;
|
||||
int ret;
|
||||
/* avoid making system calls on closed sockets */
|
||||
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL);
|
||||
if (ret > 0) {
|
||||
put = write(sock, data, count);
|
||||
if (put <= 0) {
|
||||
err = IO_CLOSED;
|
||||
#ifdef __CYGWIN__
|
||||
/* this is for CYGWIN, which is like Unix but has Win32 bugs */
|
||||
if (errno == EWOULDBLOCK) err = IO_DONE;
|
||||
#endif
|
||||
*sent = 0;
|
||||
} else {
|
||||
*sent = put;
|
||||
err = IO_DONE;
|
||||
}
|
||||
return err;
|
||||
} else {
|
||||
/* make sure we repeat in case the call was interrupted */
|
||||
do put = write(sock, data, count);
|
||||
while (put <= 0 && errno == EINTR);
|
||||
/* deal with failure */
|
||||
if (put <= 0) {
|
||||
/* in any case, nothing has been sent */
|
||||
*sent = 0;
|
||||
return IO_TIMEOUT;
|
||||
/* run select to avoid busy wait */
|
||||
if (errno != EPIPE) {
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL);
|
||||
/* tell the caller to call us again because there is more data */
|
||||
if (ret > 0) return IO_DONE;
|
||||
/* tell the caller there was no data before timeout */
|
||||
else return IO_TIMEOUT;
|
||||
/* here we know the connection has been closed */
|
||||
} else return IO_CLOSED;
|
||||
/* here we sent successfully sent something */
|
||||
} else {
|
||||
*sent = put;
|
||||
return IO_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,32 +192,36 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Receive with timeout
|
||||
* Here we exchanged the order of the calls to write and select
|
||||
* The idea is that the outer loop (whoever is calling sock_send)
|
||||
* will call the function again if we didn't time out, so we can
|
||||
* call write and then select only if it fails.
|
||||
* Should speed things up!
|
||||
* We are also treating EINTR errors.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
||||
{
|
||||
t_sock sock = *ps;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
int ret;
|
||||
ssize_t taken = 0;
|
||||
ssize_t taken;
|
||||
if (sock == SOCK_INVALID) return IO_CLOSED;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL);
|
||||
if (ret > 0) {
|
||||
taken = read(sock, data, count);
|
||||
if (taken <= 0) {
|
||||
*got = 0;
|
||||
return IO_CLOSED;
|
||||
} else {
|
||||
*got = taken;
|
||||
return IO_DONE;
|
||||
}
|
||||
} else {
|
||||
do taken = read(sock, data, count);
|
||||
while (taken <= 0 && errno == EINTR);
|
||||
if (taken <= 0) {
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
int ret;
|
||||
*got = 0;
|
||||
return IO_TIMEOUT;
|
||||
if (taken == 0) return IO_CLOSED;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL);
|
||||
if (ret > 0) return IO_DONE;
|
||||
else return IO_TIMEOUT;
|
||||
} else {
|
||||
*got = taken;
|
||||
return IO_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue