diff options
author | Volker Lendecke <vl@samba.org> | 2009-05-24 13:14:12 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-05-24 13:50:54 +0200 |
commit | 9de2efaa5b197c46508c36f50bbe6c5026f2953a (patch) | |
tree | 75fe11baf9f8b8ef802a118ba07948d01817c28e | |
parent | 4906d7fc679210555871bcb080e504fcc11734c6 (diff) | |
download | samba-9de2efaa5b197c46508c36f50bbe6c5026f2953a.tar.gz samba-9de2efaa5b197c46508c36f50bbe6c5026f2953a.tar.bz2 samba-9de2efaa5b197c46508c36f50bbe6c5026f2953a.zip |
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.
-rw-r--r-- | lib/async_req/async_sock.c | 38 |
1 files changed, 24 insertions, 14 deletions
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; } |