From a8e02b591b0c82c1f75f4f51bc683d9775f13d54 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 May 2009 16:10:54 +0200 Subject: [PATCH] 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. --- lib/async_req/async_sock.c | 15 +++++++++++++-- lib/async_req/async_sock.h | 1 + source3/lib/wb_reqtrans.c | 4 ++-- source3/libsmb/async_smb.c | 4 ++-- source3/rpc_server/srv_pipe_hnd.c | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index a3a6d75f3a0..d7f31768ef8 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -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; icount; i++) { to_write += state->iov[i].iov_len; } diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index ec859dc0aee..a50e93238aa 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -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); diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index df92ecf8b06..3fdf62a1087 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -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); } diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 12bc0a6fb31..6edfe514b80 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -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; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index f2441619ac0..a17adfb7a03 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -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; } -- 2.34.1