summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2021-11-10 11:09:10 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-11-10 17:12:19 (GMT)
commit974ef7ced24a782ff32b2248103e25a397276f36 (patch)
tree2aa2da070d0b29bf28ffb3b257e24bfe477d0dbb
parent6c220937e2b26d85920bf2d38ff2464a0d57fd6b (diff)
downloadgit-974ef7ced24a782ff32b2248103e25a397276f36.zip
git-974ef7ced24a782ff32b2248103e25a397276f36.tar.gz
git-974ef7ced24a782ff32b2248103e25a397276f36.tar.bz2
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 <johannes.schindelin@gmx.de> Tested-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--compat/simple-ipc/ipc-unix-socket.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c
index 4e28857..28a7928 100644
--- a/compat/simple-ipc/ipc-unix-socket.c
+++ b/compat/simple-ipc/ipc-unix-socket.c
@@ -35,6 +35,28 @@ enum ipc_active_state ipc_get_active_state(const char *path)
}
}
+#ifdef __CYGWIN__
+ /*
+ * Cygwin emulates Unix sockets by writing special-crafted files whose
+ * `system` bit is set.
+ *
+ * If we are too fast, Cygwin might still be in the process of marking
+ * the underlying file as a system file. Until then, we will not see a
+ * Unix socket here, but a plain file instead. Just in case that this
+ * is happening, wait a little and try again.
+ */
+ {
+ static const int delay[] = { 1, 10, 20, 40, -1 };
+ int i;
+
+ for (i = 0; S_ISREG(st.st_mode) && delay[i] > 0; i++) {
+ sleep_millisec(delay[i]);
+ if (lstat(path, &st) == -1)
+ return IPC_STATE__INVALID_PATH;
+ }
+ }
+#endif
+
/* also complain if a plain file is in the way */
if ((st.st_mode & S_IFMT) != S_IFSOCK)
return IPC_STATE__INVALID_PATH;