mirror of
https://github.com/git-for-windows/git.git
synced 2026-03-17 04:23:29 -05:00
fsmonitor--daemon: implement client command options
Implement command options `--stop`, `--is-running`, `--query`, `--query-index`, and `--flush` 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>
This commit is contained in:
committed by
Johannes Schindelin
parent
ade72692a0
commit
c8358a0be8
@@ -7,18 +7,144 @@
|
||||
#include "khash.h"
|
||||
|
||||
static const char * const builtin_fsmonitor__daemon_usage[] = {
|
||||
N_("git fsmonitor--daemon --stop"),
|
||||
N_("git fsmonitor--daemon --is-running"),
|
||||
N_("git fsmonitor--daemon --query <token>"),
|
||||
N_("git fsmonitor--daemon --query-index"),
|
||||
N_("git fsmonitor--daemon --flush"),
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef HAVE_FSMONITOR_DAEMON_BACKEND
|
||||
/*
|
||||
* Acting as a CLIENT.
|
||||
*
|
||||
* Send an IPC query to a `git-fsmonitor--daemon` SERVER process and
|
||||
* ask for the changes since the given token. This will implicitly
|
||||
* start a daemon process if necessary. The daemon process will
|
||||
* persist after we exit.
|
||||
*
|
||||
* This feature is primarily used by the test suite.
|
||||
*/
|
||||
static int do_as_client__query_token(const char *token)
|
||||
{
|
||||
struct strbuf answer = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = fsmonitor_ipc__send_query(token, &answer);
|
||||
if (ret < 0)
|
||||
die(_("could not query fsmonitor--daemon"));
|
||||
|
||||
write_in_full(1, answer.buf, answer.len);
|
||||
strbuf_release(&answer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Acting as a CLIENT.
|
||||
*
|
||||
* Read the `.git/index` to get the last token written to the FSMonitor index
|
||||
* extension and use that to make a query.
|
||||
*
|
||||
* This feature is primarily used by the test suite.
|
||||
*/
|
||||
static int do_as_client__query_from_index(void)
|
||||
{
|
||||
struct index_state *istate = the_repository->index;
|
||||
|
||||
setup_git_directory();
|
||||
if (do_read_index(istate, the_repository->index_file, 0) < 0)
|
||||
die("unable to read index file");
|
||||
if (!istate->fsmonitor_last_update)
|
||||
die("index file does not have fsmonitor extension");
|
||||
|
||||
return do_as_client__query_token(istate->fsmonitor_last_update);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acting as a CLIENT.
|
||||
*
|
||||
* Send a "quit" command to the `git-fsmonitor--daemon` (if running)
|
||||
* and wait for it to shutdown.
|
||||
*/
|
||||
static int do_as_client__send_stop(void)
|
||||
{
|
||||
struct strbuf answer = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = fsmonitor_ipc__send_command("quit", &answer);
|
||||
|
||||
/* The quit command does not return any response data. */
|
||||
strbuf_release(&answer);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
trace2_region_enter("fsm_client", "polling-for-daemon-exit", NULL);
|
||||
while (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
|
||||
sleep_millisec(50);
|
||||
trace2_region_leave("fsm_client", "polling-for-daemon-exit", NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Acting as a CLIENT.
|
||||
*
|
||||
* Send a "flush" command to the `git-fsmonitor--daemon` (if running)
|
||||
* and tell it to flush its cache.
|
||||
*
|
||||
* This feature is primarily used by the test suite to simulate a loss of
|
||||
* sync with the filesystem where we miss kernel events.
|
||||
*/
|
||||
static int do_as_client__send_flush(void)
|
||||
{
|
||||
struct strbuf answer = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
ret = fsmonitor_ipc__send_command("flush", &answer);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
write_in_full(1, answer.buf, answer.len);
|
||||
strbuf_release(&answer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_ipc_daemon_listening(void)
|
||||
{
|
||||
return fsmonitor_ipc__get_state() == IPC_STATE__LISTENING;
|
||||
}
|
||||
|
||||
int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
enum daemon_mode {
|
||||
UNDEFINED_MODE,
|
||||
STOP,
|
||||
IS_RUNNING,
|
||||
QUERY,
|
||||
QUERY_INDEX,
|
||||
FLUSH,
|
||||
} mode = UNDEFINED_MODE;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_CMDMODE(0, "stop", &mode, N_("stop the running daemon"),
|
||||
STOP),
|
||||
|
||||
OPT_CMDMODE(0, "is-running", &mode,
|
||||
N_("test whether the daemon is running"),
|
||||
IS_RUNNING),
|
||||
|
||||
OPT_CMDMODE(0, "query", &mode,
|
||||
N_("query the daemon (starting if necessary)"),
|
||||
QUERY),
|
||||
OPT_CMDMODE(0, "query-index", &mode,
|
||||
N_("query the daemon (starting if necessary) using token from index"),
|
||||
QUERY_INDEX),
|
||||
OPT_CMDMODE(0, "flush", &mode, N_("flush cached filesystem events"),
|
||||
FLUSH),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@@ -31,6 +157,24 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
|
||||
builtin_fsmonitor__daemon_usage, 0);
|
||||
|
||||
switch (mode) {
|
||||
case STOP:
|
||||
return !!do_as_client__send_stop();
|
||||
|
||||
case IS_RUNNING:
|
||||
return !is_ipc_daemon_listening();
|
||||
|
||||
case QUERY:
|
||||
if (argc != 1)
|
||||
usage_with_options(builtin_fsmonitor__daemon_usage,
|
||||
options);
|
||||
return !!do_as_client__query_token(argv[0]);
|
||||
|
||||
case QUERY_INDEX:
|
||||
return !!do_as_client__query_from_index();
|
||||
|
||||
case FLUSH:
|
||||
return !!do_as_client__send_flush();
|
||||
|
||||
case UNDEFINED_MODE:
|
||||
default:
|
||||
die(_("Unhandled command mode %d"), mode);
|
||||
|
||||
Reference in New Issue
Block a user