From acb4425461ebfa7450b0632231b8b143aa59dfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Wed, 10 Jan 2024 16:15:42 +0100 Subject: [PATCH] win32: detect unix socket support at runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows 10 build 17063 introduced support for unix sockets to Windows. bb390b1 (git-compat-util: include declaration for unix sockets in windows, 2021-09-14) introduced a way to build git with unix socket support on Windows, but you still had to decide at build time which Windows version the compiled executable was supposed to run on. We can detect at runtime wether the operating system supports unix sockets and act accordingly for all supported Windows versions. Signed-off-by: Matthias Aßhauer --- builtin/credential-cache--daemon.c | 2 ++ builtin/credential-cache.c | 3 +++ compat/mingw.c | 19 +++++++++++++++++++ compat/mingw.h | 6 ++++++ config.mak.uname | 2 -- git-compat-util.h | 13 ++++++++++++- t/t0301-credential-cache.sh | 8 ++++++++ 7 files changed, 50 insertions(+), 3 deletions(-) diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 3a6a750a8eb320..17f929dede30d1 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -294,6 +294,8 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, usage, 0); socket_path = argv[0]; + if (!have_unix_sockets()) + die(_("credential-cache--daemon unavailable; no unix socket support")); if (!socket_path) usage_with_options(usage, options); diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c index bba96d4ffd6f19..bef120b537533c 100644 --- a/builtin/credential-cache.c +++ b/builtin/credential-cache.c @@ -149,6 +149,9 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix) usage_with_options(usage, options); op = argv[0]; + if (!have_unix_sockets()) + die(_("credential-cache unavailable; no unix socket support")); + if (!socket_path) socket_path = get_socket_path(); if (!socket_path) diff --git a/compat/mingw.c b/compat/mingw.c index 51961b44c5439f..0dc226c2a7b038 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -4215,3 +4215,22 @@ int file_attr_to_st_mode (DWORD attr, DWORD tag, const char *path) fMode |= S_IWRITE; return fMode; } + +int mingw_have_unix_sockets(void) +{ + SC_HANDLE scm, srvc; + SERVICE_STATUS_PROCESS status; + DWORD bytes; + int ret = 0; + scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); + if (scm) { + srvc = OpenServiceA(scm, "afunix", SERVICE_QUERY_STATUS); + if (srvc) { + if(QueryServiceStatusEx(srvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &bytes)) + ret = status.dwCurrentState == SERVICE_RUNNING; + CloseServiceHandle(srvc); + } + CloseServiceHandle(scm); + } + return ret; +} diff --git a/compat/mingw.h b/compat/mingw.h index df85b7d1b26f9b..c0df7f3ef6b28f 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -729,3 +729,9 @@ int err_win_to_posix(DWORD winerr); * Check current process is inside Windows Container. */ int is_inside_windows_container(void); + +#ifndef NO_UNIX_SOCKETS +int mingw_have_unix_sockets(void); +#undef have_unix_sockets +#define have_unix_sockets mingw_have_unix_sockets +#endif diff --git a/config.mak.uname b/config.mak.uname index 25ecc1faea77f2..5269ea16c1e0bc 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -447,7 +447,6 @@ ifeq ($(uname_S),Windows) NO_POLL = YesPlease NO_SYMLINK_HEAD = YesPlease NO_IPV6 = YesPlease - NO_UNIX_SOCKETS = YesPlease NO_SETENV = YesPlease NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease @@ -652,7 +651,6 @@ ifeq ($(uname_S),MINGW) NO_LIBGEN_H = YesPlease NO_POLL = YesPlease NO_SYMLINK_HEAD = YesPlease - NO_UNIX_SOCKETS = YesPlease NO_SETENV = YesPlease NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease diff --git a/git-compat-util.h b/git-compat-util.h index 6a978cdb799988..896be4c816e6ae 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -220,6 +220,18 @@ struct strbuf; #define GIT_WINDOWS_NATIVE #endif +#if defined(NO_UNIX_SOCKETS) || !defined(GIT_WINDOWS_NATIVE) +static inline int _have_unix_sockets(void) +{ +#if defined(NO_UNIX_SOCKETS) + return 0; +#else + return 1; +#endif +} +#define have_unix_sockets _have_unix_sockets +#endif + #include #include #include @@ -1627,5 +1639,4 @@ static inline void *container_of_or_null_offset(void *ptr, size_t offset) #define OFFSETOF_VAR(ptr, member) \ ((uintptr_t)&(ptr)->member - (uintptr_t)(ptr)) #endif /* !__GNUC__ */ - #endif diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh index 8300faadea9a76..f2c146fa2a1dd7 100755 --- a/t/t0301-credential-cache.sh +++ b/t/t0301-credential-cache.sh @@ -8,6 +8,14 @@ test -z "$NO_UNIX_SOCKETS" || { skip_all='skipping credential-cache tests, unix sockets not available' test_done } +if test_have_prereq MINGW +then + service_running=$(sc query afunix | grep "4 RUNNING") + test -z "$service_running" || { + skip_all='skipping credential-cache tests, unix sockets not available' + test_done + } +fi uname_s=$(uname -s) case $uname_s in