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:
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user