The GitHub CI reports these test failures: FAIL: test-access =================
../../gltests/test-access.h:101: assertion 'func (BASE "f2", X_OK) == -1' failed ../../gltests/test-access.h:102: assertion 'errno == EACCES' failed FAIL test-access.exe (exit status: 1) FAIL: test-euidaccess ===================== ../../gltests/test-access.h:101: assertion 'func (BASE "f2", X_OK) == -1' failed ../../gltests/test-access.h:102: assertion 'errno == EACCES' failed FAIL test-euidaccess.exe (exit status: 1) The cause is that - GitHub apparently recently upgraded to use Cygwin 3.5.5. - The GitHub CI runs with Administrator permissions. - The behaviour of the access() function in these circumstances has changed in Cygwin 3.5.5, see <https://sourceware.org/pipermail/cygwin/2024-December/256972.html> This patch adds a workaround. 2024-12-24 Bruno Haible <br...@clisp.org> access, euidaccess tests: Avoid test failure in Cygwin 3.5.5. * tests/test-access.h [__CYGWIN__]: Include <grp.h>, <string.h>, <unistd.h>. (is_administrator): New function. (is_root): New macro. (test_access): Reenable F_OK test for non-administrators on Cygwin. Disable X_OK test for administrators on Cygwin. diff --git a/tests/test-access.h b/tests/test-access.h index ece89beb6b..a5223356a5 100644 --- a/tests/test-access.h +++ b/tests/test-access.h @@ -19,6 +19,38 @@ # define geteuid() ROOT_UID #endif +#if defined __CYGWIN__ +/* Cygwin uses the security model from Windows. */ +# include <grp.h> +# include <string.h> +# include <unistd.h> +/* Test whether the current user is in the 'Administrators' group. + We cannot use the group name "Administrators", due to internationalization. + Therefore test for the SID "S-1-5-32-544" (cf. + <https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids>). + */ +static int +is_administrator (void) +{ + gid_t list[100]; + int i; + int count = getgroups (sizeof (list) / sizeof (list[0]), list); + if (count < 0) + return 0; + for (i = 0; i < count; i++) + { + gid_t id = list[i]; + struct group *details = getgrgid (id); + if (details != NULL && strcmp (details->gr_passwd, "S-1-5-32-544") == 0) + return 1; + } + return 0; +} +# define is_root() is_administrator () +#else +# define is_root() (geteuid () == ROOT_UID) +#endif + static void test_access (int (*func) (const char * /*file*/, int /*mode*/)) { @@ -79,22 +111,22 @@ test_access (int (*func) (const char * /*file*/, int /*mode*/)) /* On Cygwin, for users that are in the 'Administrators' group, W_OK is allowed. */ -#if !defined __CYGWIN__ - if (geteuid () != ROOT_UID) + if (! is_root ()) { errno = 0; ASSERT (func (BASE "f2", W_OK) == -1); ASSERT (errno == EACCES); } -#endif #if defined _WIN32 && !defined __CYGWIN__ /* X_OK works like R_OK. */ ASSERT (func (BASE "f2", X_OK) == 0); #else - /* On Solaris, for the root user, X_OK is allowed. */ -# if defined __sun - if (geteuid () != ROOT_UID) + /* On Solaris, for the root user, X_OK is allowed. + On Cygwin 3.5.5, for users that are in the 'Administrators' group, + X_OK is allowed. */ +# if defined __sun || defined __CYGWIN__ + if (! is_root ()) # endif { errno = 0;