fsmonitor: relocate socket file if .git directory is remote

If the .git directory is on a remote filesystem, create the socket file in 'fsmonitor.socketDir' if it is defined, else create it in $HOME. Signed-off-by: Eric DeCosta <edecosta@mathworks.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric DeCosta committed Oct 4, 2022 at 17:32 UTC 6beb2688d33373508610b190f04721e748caa12c
8 files changed +78 -13
Makefile
+1
@@ -2032,6 +2032,7 @@ ifdef FSMONITOR_DAEMON_BACKEND
2032 COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND
2033 COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o
2034 COMPAT_OBJS += compat/fsmonitor/fsm-health-$(FSMONITOR_DAEMON_BACKEND).o
2035 + COMPAT_OBJS += compat/fsmonitor/fsm-ipc-$(FSMONITOR_DAEMON_BACKEND).o
2036 endif
2037
2038 ifdef FSMONITOR_OS_SETTINGS
builtin/fsmonitor--daemon.c
+2 -1
@@ -1343,7 +1343,8 @@ static int fsmonitor_run_daemon(void)
1343 * directory.)
1344 */
1345 strbuf_init(&state.path_ipc, 0);
1346 - strbuf_addstr(&state.path_ipc, absolute_path(fsmonitor_ipc__get_path()));
1346 + strbuf_addstr(&state.path_ipc,
1347 + absolute_path(fsmonitor_ipc__get_path(the_repository)));
1348
1349 /*
1350 * Confirm that we can create platform-specific resources for the
compat/fsmonitor/fsm-ipc-darwin.c new
+52
@@ -0,0 +1,52 @@
1 +#include "cache.h"
2 +#include "config.h"
3 +#include "strbuf.h"
4 +#include "fsmonitor.h"
5 +#include "fsmonitor-ipc.h"
6 +#include "fsmonitor-path-utils.h"
7 +
8 +static GIT_PATH_FUNC(fsmonitor_ipc__get_default_path, "fsmonitor--daemon.ipc")
9 +
10 +const char *fsmonitor_ipc__get_path(struct repository *r)
11 +{
12 + static const char *ipc_path = NULL;
13 + SHA_CTX sha1ctx;
14 + char *sock_dir = NULL;
15 + struct strbuf ipc_file = STRBUF_INIT;
16 + unsigned char hash[SHA_DIGEST_LENGTH];
17 +
18 + if (!r)
19 + BUG("No repository passed into fsmonitor_ipc__get_path");
20 +
21 + if (ipc_path)
22 + return ipc_path;
23 +
24 +
25 + /* By default the socket file is created in the .git directory */
26 + if (fsmonitor__is_fs_remote(r->gitdir) < 1) {
27 + ipc_path = fsmonitor_ipc__get_default_path();
28 + return ipc_path;
29 + }
30 +
31 + SHA1_Init(&sha1ctx);
32 + SHA1_Update(&sha1ctx, r->worktree, strlen(r->worktree));
33 + SHA1_Final(hash, &sha1ctx);
34 +
35 + repo_config_get_string(r, "fsmonitor.socketdir", &sock_dir);
36 +
37 + /* Create the socket file in either socketDir or $HOME */
38 + if (sock_dir && *sock_dir) {
39 + strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s",
40 + sock_dir, hash_to_hex(hash));
41 + } else {
42 + strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash));
43 + }
44 + free(sock_dir);
45 +
46 + ipc_path = interpolate_path(ipc_file.buf, 1);
47 + if (!ipc_path)
48 + die(_("Invalid path: %s"), ipc_file.buf);
49 +
50 + strbuf_release(&ipc_file);
51 + return ipc_path;
52 +}
compat/fsmonitor/fsm-ipc-win32.c new
+9
@@ -0,0 +1,9 @@
1 +#include "config.h"
2 +#include "fsmonitor-ipc.h"
3 +
4 +const char *fsmonitor_ipc__get_path(struct repository *r) {
5 + static char *ret;
6 + if (!ret)
7 + ret = git_pathdup("fsmonitor--daemon.ipc");
8 + return ret;
9 +}
compat/fsmonitor/fsm-settings-darwin.c
+1 -1
@@ -26,7 +26,7 @@
26 static enum fsmonitor_reason check_uds_volume(struct repository *r)
27 {
28 struct fs_info fs;
29 - const char *ipc_path = fsmonitor_ipc__get_path();
29 + const char *ipc_path = fsmonitor_ipc__get_path(r);
30 struct strbuf path = STRBUF_INIT;
31 strbuf_add(&path, ipc_path, strlen(ipc_path));
32
contrib/buildsystems/CMakeLists.txt
+2
@@ -308,6 +308,7 @@ if(SUPPORTS_SIMPLE_IPC)
308 add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND)
309 list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-win32.c)
310 list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-win32.c)
311 + list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-win32.c)
312 list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-win32.c)
313
314 add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS)
@@ -316,6 +317,7 @@ if(SUPPORTS_SIMPLE_IPC)
317 add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND)
318 list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-darwin.c)
319 list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-darwin.c)
320 + list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-darwin.c)
321 list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-darwin.c)
322
323 add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS)
fsmonitor-ipc.c
+8 -10
@@ -18,7 +18,7 @@ int fsmonitor_ipc__is_supported(void)
18 return 0;
19 }
20
21 -const char *fsmonitor_ipc__get_path(void)
21 +const char *fsmonitor_ipc__get_path(struct repository *r)
22 {
23 return NULL;
24 }
@@ -47,11 +47,9 @@ int fsmonitor_ipc__is_supported(void)
47 return 1;
48 }
49
50 -GIT_PATH_FUNC(fsmonitor_ipc__get_path, "fsmonitor--daemon.ipc")
51 -
50 enum ipc_active_state fsmonitor_ipc__get_state(void)
51 {
54 - return ipc_get_active_state(fsmonitor_ipc__get_path());
52 + return ipc_get_active_state(fsmonitor_ipc__get_path(the_repository));
53 }
54
55 static int spawn_daemon(void)
@@ -81,8 +79,8 @@ int fsmonitor_ipc__send_query(const char *since_token,
79 trace2_data_string("fsm_client", NULL, "query/command", tok);
80
81 try_again:
84 - state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options,
85 - &connection);
82 + state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
83 + &options, &connection);
84
85 switch (state) {
86 case IPC_STATE__LISTENING:
@@ -117,13 +115,13 @@ try_again:
115
116 case IPC_STATE__INVALID_PATH:
117 ret = error(_("fsmonitor_ipc__send_query: invalid path '%s'"),
120 - fsmonitor_ipc__get_path());
118 + fsmonitor_ipc__get_path(the_repository));
119 goto done;
120
121 case IPC_STATE__OTHER_ERROR:
122 default:
123 ret = error(_("fsmonitor_ipc__send_query: unspecified error on '%s'"),
126 - fsmonitor_ipc__get_path());
124 + fsmonitor_ipc__get_path(the_repository));
125 goto done;
126 }
127
@@ -149,8 +147,8 @@ int fsmonitor_ipc__send_command(const char *command,
147 options.wait_if_busy = 1;
148 options.wait_if_not_found = 0;
149
152 - state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options,
153 - &connection);
150 + state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
151 + &options, &connection);
152 if (state != IPC_STATE__LISTENING) {
153 die(_("fsmonitor--daemon is not running"));
154 return -1;
fsmonitor-ipc.h
+3 -1
@@ -3,6 +3,8 @@
3
4 #include "simple-ipc.h"
5
6 +struct repository;
7 +
8 /*
9 * Returns true if built-in file system monitor daemon is defined
10 * for this platform.
@@ -16,7 +18,7 @@ int fsmonitor_ipc__is_supported(void);
18 *
19 * Returns NULL if the daemon is not supported on this platform.
20 */
19 -const char *fsmonitor_ipc__get_path(void);
21 +const char *fsmonitor_ipc__get_path(struct repository *r);
22
23 /*
24 * Try to determine whether there is a `git-fsmonitor--daemon` process