v3-4-ctdb: Add recfrom_send/recv
authorVolker Lendecke <vl@samba.org>
Tue, 1 Feb 2011 10:39:45 +0000 (03:39 -0700)
committerVolker Lendecke <vl@samba.org>
Tue, 1 Feb 2011 12:23:58 +0000 (05:23 -0700)
lib/async_req/async_sock.c
lib/async_req/async_sock.h

index 09ab7d01b51492b82ec0a7b86ce33944f89e97df..f4777ca69c36b0e71040f1a9af2b68576402ff1c 100644 (file)
@@ -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;
+}
index c5d9400eb60e3ea6d3bcabfe894615b4747b1e0a..2139f1943ed2a2c3abb7b8a8919a61d633ede7ea 100644 (file)
@@ -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