From c4f92fff3af0d8763c6e5b5d4e84a782aa00dd18 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 1 Feb 2011 03:39:45 -0700 Subject: [PATCH] v3-4-ctdb: Add recfrom_send/recv --- lib/async_req/async_sock.c | 82 ++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 7 ++++ 2 files changed, 89 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 09ab7d01b5..f4777ca69c 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -611,3 +611,85 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, *pbuf = talloc_move(mem_ctx, &state->buf); return talloc_get_size(*pbuf); } + +struct recvfrom_state { + int fd; + void *buf; + size_t len; + int flags; + struct sockaddr_storage *addr; + socklen_t *addr_len; + ssize_t received; +}; + +static void recvfrom_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags, + struct sockaddr_storage *addr, + socklen_t *addr_len) +{ + struct tevent_req *result; + struct recvfrom_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct recvfrom_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + state->addr = addr; + state->addr_len = addr_len; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, recvfrom_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void recvfrom_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct recvfrom_state *state = + tevent_req_data(req, struct recvfrom_state); + + state->received = recvfrom(state->fd, state->buf, state->len, + state->flags, (struct sockaddr *)state->addr, + state->addr_len); + if ((state->received == -1) && (errno == EINTR)) { + /* retry */ + return; + } + if (state->received == 0) { + tevent_req_error(req, EPIPE); + return; + } + if (state->received == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t recvfrom_recv(struct tevent_req *req, int *perrno) +{ + struct recvfrom_state *state = + tevent_req_data(req, struct recvfrom_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->received; +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index c5d9400eb6..2139f1943e 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -57,4 +57,11 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **pbuf, int *perrno); +struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags, + struct sockaddr_storage *addr, + socklen_t *addr_len); +ssize_t recvfrom_recv(struct tevent_req *req, int *perrno); + #endif -- 2.34.1