From d67e614a07cbf143293436d380aba9a022c0e31b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 16 May 2013 16:11:54 +0200 Subject: lib: Add before/after hooks to async_connect This will facilitiate [un]become_root for smbd to connect safely to ctdbd. Signed-off-by: Volker Lendecke Reviewed-by: Christian Ambach --- lib/async_req/async_sock.c | 35 +++++++++++++++++++++++++++++++---- lib/async_req/async_sock.h | 10 ++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'lib/async_req') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 9909bc6eb3..59dde88592 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -217,6 +217,10 @@ struct async_connect_state { long old_sockflags; socklen_t address_len; struct sockaddr_storage address; + + void (*before_connect)(void *private_data); + void (*after_connect)(void *private_data); + void *private_data; }; static void async_connect_connected(struct tevent_context *ev, @@ -236,10 +240,12 @@ static void async_connect_connected(struct tevent_context *ev, * connect in an async state. This will be reset when the request is finished. */ -struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len) +struct tevent_req *async_connect_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, + const struct sockaddr *address, socklen_t address_len, + void (*before_connect)(void *private_data), + void (*after_connect)(void *private_data), + void *private_data) { struct tevent_req *result; struct async_connect_state *state; @@ -258,6 +264,9 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, state->fd = fd; state->sys_errno = 0; + state->before_connect = before_connect; + state->after_connect = after_connect; + state->private_data = private_data; state->old_sockflags = fcntl(fd, F_GETFL, 0); if (state->old_sockflags == -1) { @@ -273,7 +282,16 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, set_blocking(fd, false); + if (state->before_connect != NULL) { + state->before_connect(state->private_data); + } + state->result = connect(fd, address, address_len); + + if (state->after_connect != NULL) { + state->after_connect(state->private_data); + } + if (state->result == 0) { tevent_req_done(result); goto done; @@ -328,8 +346,17 @@ static void async_connect_connected(struct tevent_context *ev, tevent_req_data(req, struct async_connect_state); int ret; + if (state->before_connect != NULL) { + state->before_connect(state->private_data); + } + ret = connect(state->fd, (struct sockaddr *)(void *)&state->address, state->address_len); + + if (state->after_connect != NULL) { + state->after_connect(state->private_data); + } + if (ret == 0) { state->sys_errno = 0; TALLOC_FREE(fde); diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index af917bcb83..494b92eb29 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -40,10 +40,12 @@ struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx, socklen_t *addr_len); ssize_t recvfrom_recv(struct tevent_req *req, int *perrno); -struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len); +struct tevent_req *async_connect_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, + const struct sockaddr *address, socklen_t address_len, + void (*before_connect)(void *private_data), + void (*after_connect)(void *private_data), + void *private_data); int async_connect_recv(struct tevent_req *req, int *perrno); struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, -- cgit