1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-30 19:42:05 +03:00

Add "err_on_readability" to writev_send

A socket where the other side has closed only becomes readable. To catch
errors early when sitting in a pure writev, we need to also test for
readability.
This commit is contained in:
Volker Lendecke
2009-05-23 16:10:54 +02:00
parent 1a69ba8945
commit a8e02b591b
5 changed files with 19 additions and 7 deletions

View File

@ -327,6 +327,7 @@ struct writev_state {
struct iovec *iov;
int count;
size_t total_size;
uint16_t flags;
};
static void writev_trigger(struct tevent_req *req, void *private_data);
@ -335,6 +336,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct tevent_queue *queue, int fd,
bool err_on_readability,
struct iovec *iov, int count)
{
struct tevent_req *req;
@ -353,11 +355,15 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
if (state->iov == NULL) {
goto fail;
}
state->flags = TEVENT_FD_WRITE;
if (err_on_readability) {
state->flags |= TEVENT_FD_READ;
}
if (queue == NULL) {
struct tevent_fd *fde;
fde = tevent_add_fd(state->ev, state, state->fd,
TEVENT_FD_WRITE, writev_handler, req);
state->flags, writev_handler, req);
if (tevent_req_nomem(fde, req)) {
return tevent_req_post(req, ev);
}
@ -378,7 +384,7 @@ static void writev_trigger(struct tevent_req *req, void *private_data)
struct writev_state *state = tevent_req_data(req, struct writev_state);
struct tevent_fd *fde;
fde = tevent_add_fd(state->ev, state, state->fd, TEVENT_FD_WRITE,
fde = tevent_add_fd(state->ev, state, state->fd, state->flags,
writev_handler, req);
if (fde == NULL) {
tevent_req_error(req, ENOMEM);
@ -397,6 +403,11 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
to_write = 0;
if (flags & TEVENT_FD_READ) {
tevent_req_error(req, EPIPE);
return;
}
for (i=0; i<state->count; i++) {
to_write += state->iov[i].iov_len;
}

View File

@ -41,6 +41,7 @@ int async_connect_recv(struct tevent_req *req, int *perrno);
struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct tevent_queue *queue, int fd,
bool err_on_readability,
struct iovec *iov, int count);
ssize_t writev_recv(struct tevent_req *req, int *perrno);

View File

@ -152,7 +152,7 @@ struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
count = 2;
}
subreq = writev_send(state, ev, queue, fd, state->iov, count);
subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@ -309,7 +309,7 @@ struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
count = 2;
}
subreq = writev_send(state, ev, queue, fd, state->iov, count);
subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}

View File

@ -680,10 +680,10 @@ static NTSTATUS cli_smb_req_iov_send(struct tevent_req *req,
iov[0].iov_base = (void *)buf;
iov[0].iov_len = talloc_get_size(buf);
subreq = writev_send(state, state->ev, state->cli->outgoing,
state->cli->fd, iov, 1);
state->cli->fd, false, iov, 1);
} else {
subreq = writev_send(state, state->ev, state->cli->outgoing,
state->cli->fd, iov, iov_count);
state->cli->fd, false, iov, iov_count);
}
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;

View File

@ -1221,7 +1221,7 @@ struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
state->iov.iov_len = len;
subreq = writev_send(state, ev, p->write_queue, p->fd,
&state->iov, 1);
false, &state->iov, 1);
if (subreq == NULL) {
goto fail;
}