return state->total_size;
}
-struct readv_state {
- int fd;
-
- int (*next_vector)(void *private_data,
- TALLOC_CTX *mem_ctx,
- struct iovec **vector,
- size_t *count);
- void *private_data;
-
- struct iovec *iov;
- size_t count;
-
- int total_read;
-};
-
-static bool readv_ask_for_vector(struct tevent_req *req,
- struct readv_state *state);
-static void readv_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *private_data);
-
-struct tevent_req *readv_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd,
- int (*next_vector)(void *private_data,
- TALLOC_CTX *mem_ctx,
- struct iovec **vector,
- size_t *count),
- void *private_data)
-{
- struct tevent_req *req;
- struct readv_state *state;
- struct tevent_fd *fde;
-
- req = tevent_req_create(mem_ctx, &state, struct readv_state);
- if (req == NULL) {
- return NULL;
- }
- state->fd = fd;
- state->next_vector = next_vector;
- state->private_data = private_data;
- state->iov = NULL;
- state->count = 0;
- state->total_read = 0;
-
- if (!readv_ask_for_vector(req, state)) {
- return tevent_req_post(req, ev);
- }
-
- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, readv_handler,
- req);
- if (fde == NULL) {
- goto fail;
- }
- return req;
- fail:
- TALLOC_FREE(req);
- return NULL;
-
-}
-
-static bool readv_ask_for_vector(struct tevent_req *req,
- struct readv_state *state)
-{
- int ret;
- size_t to_read = 0;
- size_t i;
-
- talloc_free(state->iov);
- state->iov = NULL;
- state->count = 0;
-
- ret = state->next_vector(state->private_data,
- state, &state->iov, &state->count);
- if (ret == -1) {
- if (tevent_req_error(req, errno)) {
- return false;
- }
- }
-
- for (i=0; i < state->count; i++) {
- size_t tmp = to_read;
- tmp += state->iov[i].iov_len;
-
- if (tmp < to_read) {
- tevent_req_error(req, EMSGSIZE);
- return false;
- }
-
- to_read = tmp;
- }
-
- if (to_read == 0) {
- tevent_req_done(req);
- return false;
- }
-
- if (state->total_read + to_read < state->total_read) {
- tevent_req_error(req, EMSGSIZE);
- return false;
- }
-
- return true;
-}
-
-static void readv_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 readv_state *state =
- tevent_req_data(req, struct readv_state);
- int nread;
-
- nread = readv(state->fd, state->iov, state->count);
- if (nread == -1) {
- tevent_req_error(req, errno);
- return;
- }
- if (nread == 0) {
- tevent_req_error(req, EPIPE);
- return;
- }
-
- state->total_read += nread;
-
- while (nread > 0) {
- if (nread < state->iov[0].iov_len) {
- uint8_t *base;
- base = (uint8_t *)state->iov[0].iov_base;
- base += nread;
- state->iov[0].iov_base = base;
- state->iov[0].iov_len -= nread;
- break;
- }
- nread -= state->iov[0].iov_len;
- state->iov += 1;
- state->count -= 1;
- }
-
- if (state->count) {
- /* we have more to read */
- return;
- }
-
- /* ask the callback for a new vector we should fill */
- readv_ask_for_vector(req, state);
-}
-
-int readv_recv(struct tevent_req *req, int *perrno)
-{
- struct readv_state *state =
- tevent_req_data(req, struct readv_state);
-
- if (tevent_req_is_unix_error(req, perrno)) {
- return -1;
- }
- return state->total_read;
-}
-
struct read_packet_state {
int fd;
uint8_t *buf;