diff options
author | Junio C Hamano <gitster@pobox.com> | 2021-11-10 23:01:20 (GMT) |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2021-11-10 23:01:20 (GMT) |
commit | aace36fd3c553b29d96997a8b80fb3364961fe9e (patch) | |
tree | 3be3bdcf860ddc24fde12b68882c26c23e746251 | |
parent | c1d16cedd4024884064b9d0834cae4f5506d6221 (diff) | |
parent | 974ef7ced24a782ff32b2248103e25a397276f36 (diff) | |
download | git-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.c | 22 |
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; |