]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
async_sock: add wait_for_error_send/recv
authorStefan Metzmacher <metze@samba.org>
Tue, 20 May 2025 18:20:30 +0000 (20:20 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 18 Jun 2025 17:52:37 +0000 (17:52 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
lib/async_req/async_sock.c
lib/async_req/async_sock.h

index fadcb4f3daa310635d03c2d6815642cc78f22971..e90619056ed9e7010ba49483bc3d6081ed7d8014 100644 (file)
@@ -861,6 +861,86 @@ bool wait_for_read_recv(struct tevent_req *req, int *perr)
        return true;
 }
 
+struct wait_for_error_state {
+       struct tevent_fd *fde;
+       int fd;
+};
+
+static void wait_for_error_cleanup(struct tevent_req *req,
+                                  enum tevent_req_state req_state);
+static void wait_for_error_done(struct tevent_context *ev,
+                               struct tevent_fd *fde,
+                               uint16_t flags,
+                               void *private_data);
+
+struct tevent_req *wait_for_error_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      int fd)
+{
+       struct tevent_req *req = NULL;
+       struct wait_for_error_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state, struct wait_for_error_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->fd = fd;
+
+       tevent_req_set_cleanup_fn(req, wait_for_error_cleanup);
+
+       state->fde = tevent_add_fd(ev,
+                                  state,
+                                  state->fd,
+                                  TEVENT_FD_ERROR,
+                                  wait_for_error_done,
+                                  req);
+       if (tevent_req_nomem(state->fde, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       return req;
+}
+
+static void wait_for_error_cleanup(struct tevent_req *req,
+                                 enum tevent_req_state req_state)
+{
+       struct wait_for_error_state *state =
+               tevent_req_data(req, struct wait_for_error_state);
+
+       TALLOC_FREE(state->fde);
+       state->fd = -1;
+}
+
+static void wait_for_error_done(struct tevent_context *ev,
+                              struct tevent_fd *fde,
+                              uint16_t flags,
+                              void *private_data)
+{
+       struct tevent_req *req =
+               talloc_get_type_abort(private_data,
+               struct tevent_req);
+       struct wait_for_error_state *state =
+               tevent_req_data(req,
+               struct wait_for_error_state);
+       int ret;
+
+       errno = 0;
+       ret = samba_socket_poll_or_sock_error(state->fd);
+       if (ret == 0) {
+               errno = EPIPE;
+       }
+       if (errno == 0) {
+               errno = EPIPE;
+       }
+
+       tevent_req_error(req, errno);
+}
+
+int wait_for_error_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_unix(req);
+}
+
 struct accept_state {
        struct tevent_fd *fde;
        int listen_sock;
index 2f84b7b8ec0e5ff0536b133885fe06102ef4bf20..743f72607877c6886b066b0bde83510b0d03e36a 100644 (file)
@@ -71,6 +71,11 @@ struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
                                      bool check_errors);
 bool wait_for_read_recv(struct tevent_req *req, int *perr);
 
+struct tevent_req *wait_for_error_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      int fd);
+int wait_for_error_recv(struct tevent_req *req);
+
 struct samba_sockaddr;
 struct tevent_req *accept_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
                               int listen_sock);