fsmonitor--daemon: implement 'stop' and 'status' commands

Implement `stop` and `status` client commands to control and query the status of a `fsmonitor--daemon` server process (and implicitly start a server process if necessary). Later commits will implement the actual server and monitor the file system. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Mar 25, 2022 at 18:02 UTC abc9dbc0c17fb8ad894162517296c1177a7eb7ff
1 file changed +51
builtin/fsmonitor--daemon.c
+51
@@ -7,10 +7,55 @@
7 #include "khash.h"
8
9 static const char * const builtin_fsmonitor__daemon_usage[] = {
10 + N_("git fsmonitor--daemon stop"),
11 + N_("git fsmonitor--daemon status"),
12 NULL
13 };
14
15 #ifdef HAVE_FSMONITOR_DAEMON_BACKEND
16 +/*
17 + * Acting as a CLIENT.
18 + *
19 + * Send a "quit" command to the `git-fsmonitor--daemon` (if running)
20 + * and wait for it to shutdown.
21 + */
22 +static int do_as_client__send_stop(void)
23 +{
24 + struct strbuf answer = STRBUF_INIT;
25 + int ret;
26 +
27 + ret = fsmonitor_ipc__send_command("quit", &answer);
28 +
29 + /* The quit command does not return any response data. */
30 + strbuf_release(&answer);
31 +
32 + if (ret)
33 + return ret;
34 +
35 + trace2_region_enter("fsm_client", "polling-for-daemon-exit", NULL);
36 + while (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
37 + sleep_millisec(50);
38 + trace2_region_leave("fsm_client", "polling-for-daemon-exit", NULL);
39 +
40 + return 0;
41 +}
42 +
43 +static int do_as_client__status(void)
44 +{
45 + enum ipc_active_state state = fsmonitor_ipc__get_state();
46 +
47 + switch (state) {
48 + case IPC_STATE__LISTENING:
49 + printf(_("fsmonitor-daemon is watching '%s'\n"),
50 + the_repository->worktree);
51 + return 0;
52 +
53 + default:
54 + printf(_("fsmonitor-daemon is not watching '%s'\n"),
55 + the_repository->worktree);
56 + return 1;
57 + }
58 +}
59
60 int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
61 {
@@ -28,6 +73,12 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
73 usage_with_options(builtin_fsmonitor__daemon_usage, options);
74 subcmd = argv[0];
75
76 + if (!strcmp(subcmd, "stop"))
77 + return !!do_as_client__send_stop();
78 +
79 + if (!strcmp(subcmd, "status"))
80 + return !!do_as_client__status();
81 +
82 die(_("Unhandled subcommand '%s'"), subcmd);
83 }
84