struct wait_for_read_state {
struct tevent_fd *fde;
+ int fd;
+ bool check_errors;
};
static void wait_for_read_cleanup(struct tevent_req *req,
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;
if (tevent_req_nomem(state->fde, req)) {
return tevent_req_post(req, ev);
}
+
+ state->fd = fd;
+ state->check_errors = check_errors;
return req;
}
{
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)
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
state->ev = ev;
state->xconn = xconn;
- subreq = wait_for_read_send(state, ev, xconn->transport.sock);
+ subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
}
subreq = wait_for_read_send(state, state->ev,
- xconn->transport.sock);
+ xconn->transport.sock, false);
if (tevent_req_nomem(subreq, req)) {
return;
}
return;
}
- req = wait_for_read_send(state, winbind_event_context(), state->sock);
+ req = wait_for_read_send(state, winbind_event_context(), state->sock,
+ false);
if (req == NULL) {
DEBUG(0, ("winbind_client_request_read[%d:%s]:"
" wait_for_read_send failed - removing client\n",