Skip to content

Commit 3c88fcc

Browse files
committed
fsmonitor: Handle differences between Windows named pipe functions
CreateNamedPipeW is perfectly happy accepting pipe names with embedded escape charcters (e.g. \b), WaitNamedPipeW is not and incorrectly returns ERROR_FILE_NOT_FOUND when clearly a named pipe with the given name exists. For example, this path is problemmatic: \\batfs-sb29-cifs\vmgr\sbs29\my_git_repo In order to work around this issue, rather than using the path to the worktree directly as the name of the pipe, instead use the hash of the worktree path.
1 parent 27d43aa commit 3c88fcc

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

compat/fsmonitor/fsm-ipc-win32.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
#include "git-compat-util.h"
2+
#include "cache.h"
23
#include "config.h"
4+
#include "strbuf.h"
35
#include "fsmonitor-ipc.h"
46

5-
const char *fsmonitor_ipc__get_path(struct repository *r) {
6-
static char *ret;
7-
if (!ret)
8-
ret = git_pathdup("fsmonitor--daemon.ipc");
9-
return ret;
7+
const char *fsmonitor_ipc__get_path(struct repository *r)
8+
{
9+
static const char *ipc_path = NULL;
10+
git_SHA_CTX sha1ctx;
11+
struct strbuf pipe_name = STRBUF_INIT;
12+
unsigned char hash[GIT_MAX_RAWSZ];
13+
14+
if (ipc_path)
15+
return ipc_path;
16+
17+
git_SHA1_Init(&sha1ctx);
18+
git_SHA1_Update(&sha1ctx, r->worktree, strlen(r->worktree));
19+
git_SHA1_Final(hash, &sha1ctx);
20+
21+
strbuf_addf(&pipe_name, "git-fsmonitor-%s", hash_to_hex(hash));
22+
ipc_path = strbuf_detach(&pipe_name, NULL);
23+
return ipc_path;
1024
}

compat/simple-ipc/ipc-win32.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,15 @@
1717
static int initialize_pipe_name(const char *path, wchar_t *wpath, size_t alloc)
1818
{
1919
int off = 0;
20-
struct strbuf realpath = STRBUF_INIT;
21-
22-
if (!strbuf_realpath(&realpath, path, 0))
23-
return -1;
20+
int ret = 0;
21+
char *pipe_name = xstrdup(path);
2422

2523
off = swprintf(wpath, alloc, L"\\\\.\\pipe\\");
26-
if (xutftowcs(wpath + off, realpath.buf, alloc - off) < 0)
27-
return -1;
24+
if (xutftowcs(wpath + off, basename(pipe_name), alloc - off) < 0)
25+
ret = -1;
2826

29-
/* Handle drive prefix */
30-
if (wpath[off] && wpath[off + 1] == L':') {
31-
wpath[off + 1] = L'_';
32-
off += 2;
33-
}
34-
35-
for (; wpath[off]; off++)
36-
if (wpath[off] == L'/')
37-
wpath[off] = L'\\';
38-
39-
strbuf_release(&realpath);
40-
return 0;
27+
free(pipe_name);
28+
return ret;
4129
}
4230

4331
static enum ipc_active_state get_active_state(wchar_t *pipe_path)

0 commit comments

Comments
 (0)