summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-05-23 16:10:54 +0200
committerVolker Lendecke <vl@samba.org>2009-05-24 13:47:29 +0200
commita8e02b591b0c82c1f75f4f51bc683d9775f13d54 (patch)
tree25628a860b58c1dfad40028a83e2a148fcaa568f /lib
parent1a69ba894514dd4eaba9fa015bdf930a5b620fea (diff)
downloadsamba-a8e02b591b0c82c1f75f4f51bc683d9775f13d54.tar.gz
samba-a8e02b591b0c82c1f75f4f51bc683d9775f13d54.tar.bz2
samba-a8e02b591b0c82c1f75f4f51bc683d9775f13d54.zip
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/async_req/async_sock.c15
-rw-r--r--lib/async_req/async_sock.h1
2 files changed, 14 insertions, 2 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index a3a6d75f3a..d7f31768ef 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; i<state->count; 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 ec859dc0ae..a50e93238a 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);