summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2021-11-10 23:01:20 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-11-10 23:01:20 (GMT)
commitaace36fd3c553b29d96997a8b80fb3364961fe9e (patch)
tree3be3bdcf860ddc24fde12b68882c26c23e746251
parentc1d16cedd4024884064b9d0834cae4f5506d6221 (diff)
parent974ef7ced24a782ff32b2248103e25a397276f36 (diff)
downloadgit-aace36fd3c553b29d96997a8b80fb3364961fe9e.zip
git-aace36fd3c553b29d96997a8b80fb3364961fe9e.tar.gz
git-aace36fd3c553b29d96997a8b80fb3364961fe9e.tar.bz2
Merge branch 'js/simple-ipc-cygwin-socket-fix'
The way Cygwin emulates a unix-domain socket, on top of which the simple-ipc mechanism is implemented, can race with the program on the other side that wants to use the socket, and briefly make it appear as a regular file before lstat(2) starts reporting it as a socket. We now have a workaround on the side that connects to a unix domain socket. * js/simple-ipc-cygwin-socket-fix: simple-ipc: work around issues with Cygwin's Unix socket emulation
-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;