Skip to content

Commit c530792

Browse files
committed
fsmonitor: handle differences between Windows named pipe functions
CreateNamedPipeW is perfectly happy accepting pipe names with seemingly embedded escape charcters (e.g. \b), WaitNamedPipeW is not and incorrectly returns ERROR_FILE_NOT_FOUND when clearly a named pipe, succesfully created with CreateNamedPipeW, exists. For example, this network 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. Signed-off-by: Eric DeCosta <[email protected]>
1 parent 27d43aa commit c530792

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

compat/simple-ipc/ipc-win32.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include "hex.h"
23
#include "simple-ipc.h"
34
#include "strbuf.h"
45
#include "pkt-line.h"
@@ -17,27 +18,27 @@
1718
static int initialize_pipe_name(const char *path, wchar_t *wpath, size_t alloc)
1819
{
1920
int off = 0;
20-
struct strbuf realpath = STRBUF_INIT;
21-
22-
if (!strbuf_realpath(&realpath, path, 0))
23-
return -1;
21+
int ret = 0;
22+
git_SHA_CTX sha1ctx;
23+
struct strbuf real_path = STRBUF_INIT;
24+
struct strbuf pipe_name = STRBUF_INIT;
25+
unsigned char hash[GIT_MAX_RAWSZ];
2426

25-
off = swprintf(wpath, alloc, L"\\\\.\\pipe\\");
26-
if (xutftowcs(wpath + off, realpath.buf, alloc - off) < 0)
27+
if (!strbuf_realpath(&real_path, path, 0))
2728
return -1;
2829

29-
/* Handle drive prefix */
30-
if (wpath[off] && wpath[off + 1] == L':') {
31-
wpath[off + 1] = L'_';
32-
off += 2;
33-
}
30+
git_SHA1_Init(&sha1ctx);
31+
git_SHA1_Update(&sha1ctx, real_path.buf, real_path.len);
32+
git_SHA1_Final(hash, &sha1ctx);
33+
strbuf_release(&real_path);
3434

35-
for (; wpath[off]; off++)
36-
if (wpath[off] == L'/')
37-
wpath[off] = L'\\';
35+
strbuf_addf(&pipe_name, "git-fsmonitor-%s", hash_to_hex(hash));
36+
off = swprintf(wpath, alloc, L"\\\\.\\pipe\\");
37+
if (xutftowcs(wpath + off, pipe_name.buf, alloc - off) < 0)
38+
ret = -1;
3839

39-
strbuf_release(&realpath);
40-
return 0;
40+
strbuf_release(&pipe_name);
41+
return ret;
4142
}
4243

4344
static enum ipc_active_state get_active_state(wchar_t *pipe_path)

0 commit comments

Comments
 (0)