summaryrefslogtreecommitdiff
path: root/lib/async_req
diff options
context:
space:
mode:
authorUri Simchoni <urisimchoni@gmail.com>2015-06-25 09:46:24 +0300
committerJeremy Allison <jra@samba.org>2015-07-15 22:41:13 +0200
commit0c6dc1ecf9ae615b19be412b4d80113296628420 (patch)
treef24091964606707345ac7e77463d2fd41bb413e0 /lib/async_req
parent28e1cae4918213ba0cc7903a63d6200e69e5d1c7 (diff)
downloadsamba-0c6dc1ecf9ae615b19be412b4d80113296628420.tar.gz
async_req: check for errors when monitoring socket for readability
Add an option to wait_for_read_send(), so that the request, upon calling back, report whether the socket actually contains data or is in EOF/error state. EOF is signalled via the EPIPE error. This is useful for clients which do not expect data to arrive but wait for readability to detect a closed socket (i.e. they do not intend to actually read the socket when it's readable). Actual data arrival would indicate a bug in this case, so the check can be used to print an error message. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397 Signed-off-by: Uri Simchoni <urisimchoni@gmail.com> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'lib/async_req')
-rw-r--r--lib/async_req/async_sock.c45
-rw-r--r--lib/async_req/async_sock.h4
2 files changed, 44 insertions, 5 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index d2cda1572db..bc3780c9199 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -534,6 +534,8 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct wait_for_read_state {
struct tevent_fd *fde;
+ int fd;
+ bool check_errors;
};
static void wait_for_read_cleanup(struct tevent_req *req,
@@ -544,8 +546,8 @@ static void wait_for_read_done(struct tevent_context *ev,
void *private_data);
struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd)
+ struct tevent_context *ev, int fd,
+ bool check_errors)
{
struct tevent_req *req;
struct wait_for_read_state *state;
@@ -562,6 +564,9 @@ struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(state->fde, req)) {
return tevent_req_post(req, ev);
}
+
+ state->fd = fd;
+ state->check_errors = check_errors;
return req;
}
@@ -581,10 +586,44 @@ static void wait_for_read_done(struct tevent_context *ev,
{
struct tevent_req *req = talloc_get_type_abort(
private_data, struct tevent_req);
+ struct wait_for_read_state *state =
+ tevent_req_data(req, struct wait_for_read_state);
+ ssize_t nread;
+ char c;
- if (flags & TEVENT_FD_READ) {
+ if ((flags & TEVENT_FD_READ) == 0) {
+ return;
+ }
+
+ if (!state->check_errors) {
tevent_req_done(req);
+ return;
}
+
+ nread = recv(state->fd, &c, 1, MSG_PEEK);
+
+ if (nread == 0) {
+ tevent_req_error(req, EPIPE);
+ return;
+ }
+
+ if ((nread == -1) && (errno == EINTR)) {
+ /* come back later */
+ return;
+ }
+
+ if ((nread == -1) && (errno == ENOTSOCK)) {
+ /* Ignore this specific error on pipes */
+ tevent_req_done(req);
+ return;
+ }
+
+ if (nread == -1) {
+ tevent_req_error(req, errno);
+ return;
+ }
+
+ tevent_req_done(req);
}
bool wait_for_read_recv(struct tevent_req *req, int *perr)
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index 1b76fabed53..abbf822228d 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -53,8 +53,8 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
uint8_t **pbuf, int *perrno);
struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd);
+ struct tevent_context *ev, int fd,
+ bool check_errors);
bool wait_for_read_recv(struct tevent_req *req, int *perr);
#endif