From: Johannes Schindelin <johannes.schindelin@xxxxxx> 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@xxxxxx> --- simple-ipc: work around issues with Cygwin's Unix socket emulation Adam Dinwoodie reported problems running the simple-ipc tests on Cygwin [https://lore.kernel.org/git/20211104194619.GA12886@xxxxxxxxxxxxx]. This patch works around the underlying problem, which is rooted in Cygwin's implementation details. With this patch, I could not reproduce the problem, even with sh t0052-simple-ipc.sh --stress-limit=30. As per Junio's encouragement [https://lore.kernel.org/git/xmqqee7ozyx4.fsf@gitster.g], I am submitting this still in the -rc phase, hoping that it will make it into v2.34.0 final. Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1074%2Fdscho%2Fcygwin-vs-simple-ipc-workaround-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1074/dscho/cygwin-vs-simple-ipc-workaround-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/1074 compat/simple-ipc/ipc-unix-socket.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c index 4e28857a0a1..28a79289d4f 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; base-commit: 6c220937e2b26d85920bf2d38ff2464a0d57fd6b -- gitgitgadget