Hi, On Wed, 7 Apr 2021, Jeremy Drake via Mingw-w64-public wrote:
For a few months, I've been working around an issue building ncurses with clang targeting UCRT (https://github.com/msys2/CLANG-packages/issues/4), and recently the same issue had to be worked around for GCC targeting UCRT. I finally got around to debugging it, and found that the call at https://github.com/mirror/ncurses/blob/1f7a36f/ncurses/tinfo/access.c#L136 failed: result = ACCESS(head, R_OK | W_OK | X_OK); With that knowledge, I created the following test program: #include <io.h> #include <stdio.h> #include <stddef.h> int main(int argc, char ** argv) { int ret = mkdir("64"); printf("mkdir: %d (%d)\n", ret, errno); ret = access("64/", R_OK|W_OK); printf("access R_OK|W_OK: %d (%d)\n", ret, errno); ret = access("64/", R_OK|W_OK|X_OK); printf("access R_OK|W_OK|X_OK: %d (%d)\n", ret, errno); return 0; }
Nitpicky sidetrack - doesn't this fail to build for you unless you include errno.h too?
With MSVCRT all calls return 0, but with UCRT the last call returns -1 and sets errno to EINVAL. (That is, assuming a directory '64' can be created in the current directory when run). It seems that, to UCRT, X_OK is an invalid parameter. I don't know if this can or should be worked around here, or if all callers need to be taught not to check the execute bit on Windows.
This used to be an issue with msvcrt.dll too, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33281. However, when I try out your test snippet (extended to test the directory both with and without a trailing slash, and with a regular file) I can't reproduce the issue with access() on msvcrt.dll on Vista, as reported there. Maybe Microsoft reverted the change there to keep things from breaking?
I can reproduce the issue with UCRT though. (I also ran into this at some point when I crosscompiled a GCC, where I had managed to miss the GCC access() workaround - I presume I built GCC with UCRT at the time.)
As for how to fix it, see in particular https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33281#c11. Defining X_OK to zero is told to break some codepaths somewhere (that expect it to have a nonzero value).
I guess the least risky solution would be to enable the "__USE_MINGW_ACCESS" codepath unconditionally if using UCRT - what do you think?
(One could also consider to change the implementation of __mingw_access to just strip out the X_OK bit and call the CRT's real _access function, instead of reimplementing it with a call to GetFileAttributesA.)
// Martin _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public