[PATCH samba v3 1/1] smbclient: cancel pending notify on SIGINT
ChenXiaoSong
chenxiaosong at chenxiaosong.com
Thu Aug 6 06:05:12 UTC 2026
Hi Ralph,
Do you have any suggestions for this patch?
I also created a merge request on GitLab:
https://gitlab.com/samba-team/samba/-/merge_requests/4530
On 6/8/26 22:28, chenxiaosong at chenxiaosong.com wrote:
> From: ChenXiaoSong <chenxiaosong at kylinos.cn>
>
> When client stops querying a directory for change notifications,
> it should send a cancel request to the server.
>
> After cancel notify succeeds, `status` returned by both
> `tevent_req_poll_ntstatus()` and `cli_notify_recv()` is
> `NT_STATUS_OK` rather than `NT_STATUS_CANCELLED`, so we
> can only check `sig_state.cancelled`.
>
> Suggested-by: Stefan Metzmacher <metze at samba.org>
> Signed-off-by: ChenXiaoSong <chenxiaosong at kylinos.cn>
> ---
> source3/client/client.c | 64 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 57 insertions(+), 7 deletions(-)
>
> diff --git a/source3/client/client.c b/source3/client/client.c
> index 1d3656aab34..37693b8f401 100644
> --- a/source3/client/client.c
> +++ b/source3/client/client.c
> @@ -45,6 +45,7 @@
> #include "lib/cmdline/cmdline.h"
> #include "libcli/smb/reparse.h"
> #include "lib/param/param.h"
> +#include "lib/util/tevent_ntstatus.h"
>
> #ifndef REGISTER
> #define REGISTER 0
> @@ -4653,19 +4654,46 @@ static int cmd_newer(TALLOC_CTX *mem_ctx)
> Watch directory changes
> ****************************************************************************/
>
> +struct notify_state {
> + struct tevent_req *notify_req;
> + bool cancelled;
> +};
> +
> +static void
> +notify_sig_int_handler(
> + struct tevent_context *ev,
> + struct tevent_signal *se,
> + int signum,
> + int count,
> + void *siginfo,
> + void *private_data)
> +{
> + struct notify_state *state = (struct notify_state *)private_data;
> +
> + if (state->notify_req)
> + state->cancelled = tevent_req_cancel(state->notify_req);
> +}
> +
> static int cmd_notify(TALLOC_CTX *mem_ctx)
> {
> TALLOC_CTX *frame = talloc_stackframe();
> char *name, *buf;
> NTSTATUS status;
> uint16_t fnum;
> + struct tevent_req *req;
> + struct tevent_context *ev;
> + struct tevent_signal *se;
> + struct notify_state sig_state = {
> + .notify_req = NULL,
> + .cancelled = false,
> + };
>
> name = talloc_strdup(talloc_tos(), client_get_cur_dir());
> if (name == NULL) {
> goto fail;
> }
> if (!next_token_talloc(talloc_tos(), &cmd_ptr, &buf, NULL)) {
> - goto usage;
> + goto fail;
> }
> name = talloc_asprintf_append(name, "%s", buf);
> if (name == NULL) {
> @@ -4684,14 +4712,33 @@ static int cmd_notify(TALLOC_CTX *mem_ctx)
> goto fail;
> }
>
> + ev = samba_tevent_context_init(frame);
> + if (!ev)
> + goto close;
> +
> + se = tevent_add_signal(ev, frame, SIGINT, 0, notify_sig_int_handler, &sig_state);
> + if (!se)
> + goto close;
> +
> while (1) {
> uint32_t i;
> uint32_t num_changes = 0;
> struct notify_change *changes = NULL;
>
> - status = cli_notify(cli, fnum, 1000, FILE_NOTIFY_CHANGE_ALL,
> - true,
> - talloc_tos(), &num_changes, &changes);
> + if (sig_state.cancelled) {
> + printf("notify cancelled\n");
> + goto close;
> + }
> +
> + req = cli_notify_send(frame, ev, cli, fnum, 1000, FILE_NOTIFY_CHANGE_ALL, true);
> + if (!req)
> + goto close;
> + sig_state.notify_req = req;
> +
> + if (!tevent_req_poll_ntstatus(req, ev, &status))
> + goto close;
> +
> + status = cli_notify_recv(req, talloc_tos(), &num_changes, &changes);
> if (NT_STATUS_EQUAL(status, NT_STATUS_NOTIFY_ENUM_DIR)) {
> printf("NOTIFY_ENUM_DIR\n");
> status = NT_STATUS_OK;
> @@ -4699,7 +4746,7 @@ static int cmd_notify(TALLOC_CTX *mem_ctx)
> if (!NT_STATUS_IS_OK(status)) {
> d_printf("notify returned %s\n",
> nt_errstr(status));
> - goto fail;
> + goto close;
> }
> for (i=0; i<num_changes; i++) {
> printf("%4.4x %s\n", changes[i].action,
> @@ -4707,8 +4754,11 @@ static int cmd_notify(TALLOC_CTX *mem_ctx)
> }
> TALLOC_FREE(changes);
> }
> -usage:
> - d_printf("notify <dir name>\n");
> +close:
> + status = cli_close(cli, fnum);
> + if (!NT_STATUS_IS_OK(status)) {
> + d_printf("close returned %s\n", nt_errstr(status));
> + }
> fail:
> TALLOC_FREE(frame);
> return 1;
--
ChenXiaoSong <chenxiaosong at chenxiaosong.com>
Chinese Homepage: https://chenxiaosong.com
English Homepage: https://chenxiaosong.com/en
More information about the samba-technical
mailing list