*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;
+}
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