diff mbox series

[v4,2/4] fsmonitor: generate unique Unix socket file name in the desired location

Message ID 2cb026a631704b004b06e4a944c79a434df08440.1661962145.git.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series fsmonitor: option to allow fsmonitor to run against network-mounted repos | expand

Commit Message

Eric DeCosta Aug. 31, 2022, 4:09 p.m. UTC
From: Eric DeCosta <edecosta@mathworks.com>

Based on the values of fsmonitor.allowRemote and fsmonitor.socketDir
locate the Unix domain socket file in the desired location (either
the .git directory, $HOME, or fsmonitor.socketDir). If the location
is other than the .git directory, generate a unique file name based
on the SHA1 has of the path to the .git directory.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
---
 fsmonitor-ipc.c | 40 +++++++++++++++++++++++++++++++++++++---
 fsmonitor-ipc.h |  6 ++++++
 2 files changed, 43 insertions(+), 3 deletions(-)

Comments

Ævar Arnfjörð Bjarmason Aug. 31, 2022, 7:49 p.m. UTC | #1
On Wed, Aug 31 2022, Eric DeCosta via GitGitGadget wrote:

> From: Eric DeCosta <edecosta@mathworks.com>
>
> Based on the values of fsmonitor.allowRemote and fsmonitor.socketDir
> locate the Unix domain socket file in the desired location (either
> the .git directory, $HOME, or fsmonitor.socketDir). If the location
> is other than the .git directory, generate a unique file name based
> on the SHA1 has of the path to the .git directory.

Per:

	fsmonitor-ipc.h- * Returns the pathname to the IPC named pipe or Unix domain socket
	fsmonitor-ipc.h- * where a `git-fsmonitor--daemon` process will listen.  This is a
	fsmonitor-ipc.h- * per-worktree value.

> +	git_dir = get_git_dir();
> +	sock_dir = fsm_settings__get_socket_dir(the_repository);
> +
> +	SHA1_Init(&sha1ctx);
> +	SHA1_Update(&sha1ctx, git_dir, strlen(git_dir));
> +	SHA1_Final(hash, &sha1ctx);
> +
> +	if (sock_dir && *sock_dir)
> +		strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s",
> +					sock_dir, hash_to_hex(hash));
> +	else

But here we (from eyeballing this, maybe I've missed something):

 1. Get the path to the git dir
 2. SHA-1 hash that path, presumably to make it fixed size & get rid of
    slashes etc.
 3. Make that the IPC filename

Per the "per worktree" can't we just check if:

 * We have a .git/worktree/? If so derive the name from that.
 * We don't? Then we just have one? Stick it in in there? I.e. isn't the
   hash_to_hex() here redundant?

...

> +		strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash));

... but not here, so is it just for this "else", but got carried over
above?

I think if we're creating a new global cookie file, and presumably
potentially a *lot* of them in the user's ~ we should at least
prominently document that somewhere.

But more generally couldn't this?:

 * Play nice with $HOME/.config/git/ etc, as is the usual convention these days on *nix
 * We would have to the equivalent of a "mkdir -p", but if we stick it
   in .config/git/fsmonitor-sockets or something we could have a nested
   path there that mirrors the path to the repo.

The latter can really help with debugging, you have this random
.git-fsmonitor-XXXXX file, where the XXXX is totally mysterious, until
you eventually find this code & discover it's a SHA-1 hash of some other
path...
Junio C Hamano Aug. 31, 2022, 8:11 p.m. UTC | #2
"Eric DeCosta via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +const char *fsmonitor_ipc__get_path(void)
> +{
> +#ifdef WIN32
> +	return fsmonitor_ipc__get_default_path();
> +#else

Hmph.

As compat/fsmonitor/ directory already sets up a good way to have
platform-specific implementation of a common API function, I think
this patch goes in a wrong direction by fighting it.

Shouldn't the rest of the function we see here be made to another 
implementation of fsmonitor_ipc__get_default_path() that is
specific to platforms, i.e. in compat/fsmonitor/$somenewfile.c,
that is used for !WIN32 case?
diff mbox series

Patch

diff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c
index 789e7397baa..1e3f0a6cf48 100644
--- a/fsmonitor-ipc.c
+++ b/fsmonitor-ipc.c
@@ -1,7 +1,6 @@ 
 #include "cache.h"
-#include "fsmonitor.h"
-#include "simple-ipc.h"
 #include "fsmonitor-ipc.h"
+#include "fsmonitor-settings.h"
 #include "run-command.h"
 #include "strbuf.h"
 #include "trace2.h"
@@ -47,7 +46,42 @@  int fsmonitor_ipc__is_supported(void)
 	return 1;
 }
 
-GIT_PATH_FUNC(fsmonitor_ipc__get_path, "fsmonitor--daemon.ipc")
+GIT_PATH_FUNC(fsmonitor_ipc__get_default_path, "fsmonitor--daemon.ipc")
+
+const char *fsmonitor_ipc__get_path(void)
+{
+#ifdef WIN32
+	return fsmonitor_ipc__get_default_path();
+#else
+	char *retval;
+	SHA_CTX sha1ctx;
+	const char *git_dir;
+	const char *sock_dir;
+	struct strbuf ipc_file = STRBUF_INIT;
+	unsigned char hash[SHA_DIGEST_LENGTH];
+
+	if (fsm_settings__get_allow_remote(the_repository) < 1)
+		return fsmonitor_ipc__get_default_path();
+
+	git_dir = get_git_dir();
+	sock_dir = fsm_settings__get_socket_dir(the_repository);
+
+	SHA1_Init(&sha1ctx);
+	SHA1_Update(&sha1ctx, git_dir, strlen(git_dir));
+	SHA1_Final(hash, &sha1ctx);
+
+	if (sock_dir && *sock_dir)
+		strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s",
+					sock_dir, hash_to_hex(hash));
+	else
+		strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash));
+	retval = interpolate_path(ipc_file.buf, 1);
+	if (!retval)
+		die(_("Invalid path: %s"), ipc_file.buf);
+	strbuf_release(&ipc_file);
+	return retval;
+#endif
+}
 
 enum ipc_active_state fsmonitor_ipc__get_state(void)
 {
diff --git a/fsmonitor-ipc.h b/fsmonitor-ipc.h
index b6a7067c3af..4d27223c2a6 100644
--- a/fsmonitor-ipc.h
+++ b/fsmonitor-ipc.h
@@ -18,6 +18,12 @@  int fsmonitor_ipc__is_supported(void);
  */
 const char *fsmonitor_ipc__get_path(void);
 
+/*
+ * Returns the pathname to the default IPC named pipe or Unix domain
+ * socket.
+ */
+const char *fsmonitor_ipc__get_default_path(void);
+
 /*
  * Try to determine whether there is a `git-fsmonitor--daemon` process
  * listening on the IPC pipe/socket.