summaryrefslogtreecommitdiff
path: root/network_io
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2001-07-10 15:01:43 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2001-07-10 15:01:43 +0000
commit2489186f0f850b96bf0fce72ee2e4520474e52b8 (patch)
tree859968c65e3b5e0d68f1f8da00186ecefefe79bc /network_io
parentdd2e0eb3ea532af4c69d89153bb711f0c8890ff0 (diff)
downloadlibapr-2489186f0f850b96bf0fce72ee2e4520474e52b8.tar.gz
apr_connect() on Unix:
handle EINTR handle APR timeouts on the socket git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@61910 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io')
-rw-r--r--network_io/unix/sendrecv.c20
-rw-r--r--network_io/unix/sockets.c67
2 files changed, 54 insertions, 33 deletions
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index 1e9df3d62..abd77409c 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -59,7 +59,7 @@
#include "fileio.h"
#endif /* APR_HAS_SENDFILE */
-static apr_status_t wait_for_io_or_timeout(apr_socket_t *sock, int for_read)
+apr_status_t apr_wait_for_io_or_timeout(apr_socket_t *sock, int for_read)
{
struct timeval tv, *tvptr;
fd_set fdset;
@@ -103,7 +103,7 @@ apr_status_t apr_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
&& sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -132,7 +132,7 @@ apr_status_t apr_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 1);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 1);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -167,7 +167,7 @@ apr_status_t apr_sendto(apr_socket_t *sock, apr_sockaddr_t *where,
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
&& sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -200,7 +200,7 @@ apr_status_t apr_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 1);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 1);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -235,7 +235,7 @@ apr_status_t apr_sendv(apr_socket_t * sock, const struct iovec *vec,
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -324,7 +324,7 @@ apr_status_t apr_sendfile(apr_socket_t *sock, apr_file_t *file,
if (rv == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout > 0) {
- arv = wait_for_io_or_timeout(sock, 0);
+ arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -423,7 +423,7 @@ apr_status_t apr_sendfile(apr_socket_t * sock, apr_file_t * file,
* we get -1/EAGAIN/nbytes>0; AFAICT it just means extra syscalls
* from time to time
*/
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
@@ -577,7 +577,7 @@ apr_status_t apr_sendfile(apr_socket_t *sock, apr_file_t *file,
if (rc == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout > 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
@@ -710,7 +710,7 @@ apr_status_t apr_sendfile(apr_socket_t * sock, apr_file_t * file,
if (rv == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
sock->timeout > 0) {
- arv = wait_for_io_or_timeout(sock, 0);
+ arv = apr_wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
return arv;
diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c
index d60712e9e..c14ce5475 100644
--- a/network_io/unix/sockets.c
+++ b/network_io/unix/sockets.c
@@ -257,39 +257,60 @@ apr_status_t apr_accept(apr_socket_t **new, apr_socket_t *sock, apr_pool_t *conn
apr_status_t apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
{
+ int rc;
+
if ((sock->socketdes < 0) || (!sock->remote_addr)) {
return APR_ENOTSOCK;
}
- if ((connect(sock->socketdes,
- (const struct sockaddr *)&sa->sa.sin,
- sa->salen) < 0) &&
- (errno != EINPROGRESS)) {
+ do {
+ rc = connect(sock->socketdes,
+ (const struct sockaddr *)&sa->sa.sin,
+ sa->salen);
+ } while (rc == -1 && errno == EINTR);
+
+ /* we can see EINPROGRESS the first time connect is called on a non-blocking
+ * socket; if called again, we can see EALREADY
+ */
+ if (rc == -1 && (errno == EINPROGRESS || errno == EALREADY) && sock->timeout != 0) {
+ apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
+ if (arv != APR_SUCCESS) {
+ return arv;
+ }
+ else {
+ do {
+ rc = connect(sock->socketdes,
+ (const struct sockaddr *)&sa->sa.sin,
+ sa->salen);
+ } while (rc == -1 && errno == EINTR);
+ }
+ }
+
+ if (rc == -1) {
return errno;
}
- else {
- sock->remote_addr = sa;
- /* XXX IPv6 assumes sin_port and sin6_port at same offset */
- if (sock->local_addr->sa.sin.sin_port == 0) {
- /* connect() got us an ephemeral port */
- sock->local_port_unknown = 1;
- }
- /* XXX IPv6 to be handled better later... */
- if (
+
+ sock->remote_addr = sa;
+ /* XXX IPv6 assumes sin_port and sin6_port at same offset */
+ if (sock->local_addr->sa.sin.sin_port == 0) {
+ /* connect() got us an ephemeral port */
+ sock->local_port_unknown = 1;
+ }
+ /* XXX IPv6 to be handled better later... */
+ if (
#if APR_HAVE_IPV6
- sock->local_addr->sa.sin.sin_family == APR_INET6 ||
+ sock->local_addr->sa.sin.sin_family == APR_INET6 ||
#endif
- sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
- /* not bound to specific local interface; connect() had to assign
- * one for the socket
- */
- sock->local_interface_unknown = 1;
- }
+ sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
+ /* not bound to specific local interface; connect() had to assign
+ * one for the socket
+ */
+ sock->local_interface_unknown = 1;
+ }
#ifndef HAVE_POLL
- sock->connected=1;
+ sock->connected=1;
#endif
- return APR_SUCCESS;
- }
+ return APR_SUCCESS;
}
apr_status_t apr_socket_data_get(void **data, const char *key, apr_socket_t *sock)