From 9de2efaa5b197c46508c36f50bbe6c5026f2953a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 May 2009 13:14:12 +0200 Subject: Change async_connect to use connect instead of getsockopt to get the error On my Linux box, this is definitely the more reliable strategy with unix domain sockets, and according to my tests it also works correctly with TCP sockets. --- lib/async_req/async_sock.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'lib/async_req') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index d7f31768ef..fe71b29117 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -167,6 +167,8 @@ struct async_connect_state { int result; int sys_errno; long old_sockflags; + socklen_t address_len; + struct sockaddr_storage address; }; static void async_connect_connected(struct tevent_context *ev, @@ -209,6 +211,13 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, state->fd = fd; state->sys_errno = 0; + state->address_len = address_len; + if (address_len > sizeof(state->address)) { + errno = EINVAL; + goto post_errno; + } + memcpy(&state->address, address, address_len); + state->old_sockflags = fcntl(fd, F_GETFL, 0); if (state->old_sockflags == -1) { goto post_errno; @@ -270,8 +279,6 @@ static void async_connect_connected(struct tevent_context *ev, struct async_connect_state *state = tevent_req_data(req, struct async_connect_state); - TALLOC_FREE(fde); - /* * Stevens, Network Programming says that if there's a * successful connect, the socket is only writable. Upon an @@ -279,20 +286,23 @@ static void async_connect_connected(struct tevent_context *ev, */ if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) == (TEVENT_FD_READ|TEVENT_FD_WRITE)) { - int sockerr; - socklen_t err_len = sizeof(sockerr); - - if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR, - (void *)&sockerr, &err_len) == 0) { - errno = sockerr; + int ret; + + ret = connect(state->fd, + (struct sockaddr *)(void *)&state->address, + state->address_len); + if (ret == 0) { + TALLOC_FREE(fde); + tevent_req_done(req); + return; } - state->sys_errno = errno; - - DEBUG(10, ("connect returned %s\n", strerror(errno))); - - fcntl(state->fd, F_SETFL, state->old_sockflags); - tevent_req_error(req, state->sys_errno); + if (errno == EINPROGRESS) { + /* Try again later, leave the fde around */ + return; + } + TALLOC_FREE(fde); + tevent_req_error(req, errno); return; } -- cgit