Skip to content

Commit 974ef7c

Browse files
dschogitster
authored andcommitted
simple-ipc: work around issues with Cygwin's Unix socket emulation
Cygwin emulates Unix sockets by writing files with custom contents and then marking them as system files. The tricky problem is that while the file is written and its `system` bit is set, it is still identified as a file. This caused test failures when Git is too fast looking for the Unix sockets and then complains that there is a plain file in the way. Let's work around this by adding a delayed retry loop, specifically for Cygwin. Signed-off-by: Johannes Schindelin <[email protected]> Tested-by: Ramsay Jones <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6c22093 commit 974ef7c

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

compat/simple-ipc/ipc-unix-socket.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@ enum ipc_active_state ipc_get_active_state(const char *path)
3535
}
3636
}
3737

38+
#ifdef __CYGWIN__
39+
/*
40+
* Cygwin emulates Unix sockets by writing special-crafted files whose
41+
* `system` bit is set.
42+
*
43+
* If we are too fast, Cygwin might still be in the process of marking
44+
* the underlying file as a system file. Until then, we will not see a
45+
* Unix socket here, but a plain file instead. Just in case that this
46+
* is happening, wait a little and try again.
47+
*/
48+
{
49+
static const int delay[] = { 1, 10, 20, 40, -1 };
50+
int i;
51+
52+
for (i = 0; S_ISREG(st.st_mode) && delay[i] > 0; i++) {
53+
sleep_millisec(delay[i]);
54+
if (lstat(path, &st) == -1)
55+
return IPC_STATE__INVALID_PATH;
56+
}
57+
}
58+
#endif
59+
3860
/* also complain if a plain file is in the way */
3961
if ((st.st_mode & S_IFMT) != S_IFSOCK)
4062
return IPC_STATE__INVALID_PATH;

0 commit comments

Comments
 (0)