diff --git a/TODO b/TODO index 6612b45..7cde792 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,11 @@ -make sure all modules that can use socket.newtry + +ajeitar o connect com a dica do mike + if ((err > 1 || !FD_ISSET(sock, &wfds)) && + recv(sock, &dummy, 0, 0) < 0 && errno != EWOULDBLOCK) ... + +sort out the wrap around of gettime... +optmize aux_getgroupudata +make sure all modules that can use it actually use socket.newtry make select interrupt safe adicionar exemplos de expansão: pipe, local, named pipe Add service name translation. @@ -9,5 +16,7 @@ testar os options! - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) - inet_ntoa também é uma merda. - SSL -- unix 92 bytes maximo no endereço, incluindo o zero -- unix 9216 maximo de datagram size + +these are done +* unix 92 bytes maximo no endereço, incluindo o zero +* unix 9216 maximo de datagram size diff --git a/src/socket.h b/src/socket.h index 3dac875..5da1ccc 100644 --- a/src/socket.h +++ b/src/socket.h @@ -60,6 +60,6 @@ const char *sock_listen(p_sock ps, int backlog); const char *sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, p_tm tm); -const char *sock_hoststrerror(); +const char *sock_hoststrerror(void); #endif /* SOCK_H */ diff --git a/src/usocket.c b/src/usocket.c index 617b1ea..cf0458d 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -113,7 +113,7 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) if (err > 0) { char dummy; /* recv will set errno to the value a blocking connect would set */ - if (recv(sock, &dummy, 0, 0) < 0 && errno != EWOULDBLOCK) + if (recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN) return sock_connectstrerror(errno); else return NULL; @@ -179,7 +179,7 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, /* if result is valid, we are done */ if (*pa != SOCK_INVALID) return NULL; /* find out if we failed for a fatal reason */ - if (errno != EWOULDBLOCK && errno != ECONNABORTED) + if (errno != EAGAIN && errno != ECONNABORTED) return sock_acceptstrerror(errno); /* call select to avoid busy-wait. */ FD_ZERO(&fds); @@ -206,21 +206,23 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, while (put < 0 && errno == EINTR); /* deal with failure */ if (put <= 0) { + int ret; fd_set fds; /* in any case, nothing has been sent */ *sent = 0; + /* only proceed to select if no error happened */ + if (errno != EAGAIN) return IO_ERROR; + /* optimize for the timeout = 0 case */ + if (timeout == 0) return IO_TIMEOUT; /* here we know the connection has been closed */ if (errno == EPIPE) return IO_CLOSED; /* run select to avoid busy wait */ FD_ZERO(&fds); FD_SET(sock, &fds); - if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { - /* here the call was interrupted. calling again might work */ - if (errno == EINTR) return IO_RETRY; - /* here there was no data before timeout */ - else return IO_TIMEOUT; - /* here we didn't send anything, but now we can */ - } else return IO_RETRY; + ret = sock_select(sock+1, NULL, &fds, NULL, timeout); + if (ret == 0) return IO_TIMEOUT; + else if (ret > 0 || errno == EINTR) return IO_RETRY; + else return IO_ERROR; /* here we successfully sent something */ } else { *sent = put; @@ -240,15 +242,18 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, do put = sendto(sock, data, count, 0, addr, addr_len); while (put < 0 && errno == EINTR); if (put <= 0) { + int ret; fd_set fds; *sent = 0; + if (errno != EAGAIN) return IO_ERROR; + if (timeout == 0) return IO_TIMEOUT; if (errno == EPIPE) return IO_CLOSED; FD_ZERO(&fds); FD_SET(sock, &fds); - if (sock_select(sock+1, NULL, &fds, NULL, timeout) <= 0) { - if (errno == EINTR) return IO_RETRY; - else return IO_TIMEOUT; - } else return IO_RETRY; + ret = sock_select(sock+1, NULL, &fds, NULL, timeout); + if (ret == 0) return IO_TIMEOUT; + else if (ret > 0 || errno == EINTR) return IO_RETRY; + else return IO_ERROR; } else { *sent = put; return IO_DONE; @@ -270,12 +275,14 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) int ret; *got = 0; if (taken == 0) return IO_CLOSED; + if (errno != EAGAIN) return IO_ERROR; + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(sock+1, &fds, NULL, NULL, timeout); - if (ret < 0 && errno == EINTR) return IO_RETRY; if (ret == 0) return IO_TIMEOUT; - return IO_RETRY; + else if (ret > 0 || errno == EINTR) return IO_RETRY; + else return IO_ERROR; } else { *got = taken; return IO_DONE; @@ -298,12 +305,14 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, int ret; *got = 0; if (taken == 0) return IO_CLOSED; + if (errno != EAGAIN) return IO_ERROR; + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(sock+1, &fds, NULL, NULL, timeout); - if (ret < 0 && errno == EINTR) return IO_RETRY; if (ret == 0) return IO_TIMEOUT; - return IO_RETRY; + else if (ret > 0 || errno == EINTR) return IO_RETRY; + else return IO_ERROR; } else { *got = taken; return IO_DONE; @@ -363,7 +372,7 @@ static const char *sock_createstrerror(int err) static const char *sock_acceptstrerror(int err) { switch (err) { - case EWOULDBLOCK: return io_strerror(IO_RETRY); + case EAGAIN: return io_strerror(IO_RETRY); case EBADF: return "invalid descriptor"; case ENOBUFS: case ENOMEM: return "insuffucient buffer space"; case ENOTSOCK: return "descriptor not a socket"; diff --git a/src/wsocket.c b/src/wsocket.c index e276fe0..7f3e066 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -200,7 +200,6 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, { t_sock sock = *ps; int put; - int ret; /* avoid making system calls on closed sockets */ if (sock == SOCK_INVALID) return IO_CLOSED; /* try to send something */ @@ -212,6 +211,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, /* run select to avoid busy wait */ if (WSAGetLastError() == WSAEWOULDBLOCK) { fd_set fds; + int ret; + /* optimize for the timeout = 0 case */ + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(0, NULL, &fds, NULL, timeout); @@ -236,13 +238,14 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, { t_sock sock = *ps; int put; - int ret; if (sock == SOCK_INVALID) return IO_CLOSED; put = sendto(sock, data, (int) count, 0, addr, addr_len); if (put <= 0) { *sent = 0; if (WSAGetLastError() == WSAEWOULDBLOCK) { fd_set fds; + int ret; + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(0, NULL, &fds, NULL, timeout); @@ -269,6 +272,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) int ret; *got = 0; if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(0, &fds, NULL, NULL, timeout); @@ -295,6 +299,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, int ret; *got = 0; if (taken == 0 || WSAGetLastError() != WSAEWOULDBLOCK) return IO_CLOSED; + if (timeout == 0) return IO_TIMEOUT; FD_ZERO(&fds); FD_SET(sock, &fds); ret = sock_select(0, &fds, NULL, NULL, timeout); diff --git a/test/testsrvr.lua b/test/testsrvr.lua index 71281cf..5b842f1 100644 --- a/test/testsrvr.lua +++ b/test/testsrvr.lua @@ -1,4 +1,4 @@ -local socket = require"socket" +socket = require"socket" host = host or "localhost" port = port or "8080"