Add __mingw_access() that works the same for all msvcr*/ucrt libs
Old versions of MSVCRT _access() just ignored X_OK, while the
version shipped with Vista, returns an error code.
_access() from msvcr110/120 returns an error code for nul file.
Signed-off-by: Mateusz Brzostek <mateuszb@poczta.onet.pl>
Signed-off-by: Liu Hao <lh_mouse@126.com>
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index f8b0623..10f3b04 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -330,7 +330,7 @@
misc/wcstoimax.c misc/wcstold.c misc/wcstoumax.c misc/wctob.c misc/wctrans.c \
misc/wctype.c misc/wdirent.c misc/winbs_uint64.c misc/winbs_ulong.c misc/winbs_ushort.c \
misc/wmemchr.c misc/wmemcmp.c misc/wmemcpy.c misc/wmemmove.c misc/wmempcpy.c \
- misc/wmemset.c misc/ftw.c misc/ftw64.c \
+ misc/wmemset.c misc/ftw.c misc/ftw64.c misc/mingw-access.c \
\
stdio/mingw_pformat.h \
stdio/vfscanf2.S stdio/vfwscanf2.S stdio/vscanf2.S stdio/vsscanf2.S stdio/vswscanf2.S \
diff --git a/mingw-w64-crt/misc/mingw-access.c b/mingw-w64-crt/misc/mingw-access.c
new file mode 100644
index 0000000..6f405ab
--- /dev/null
+++ b/mingw-w64-crt/misc/mingw-access.c
@@ -0,0 +1,54 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#include <windows.h>
+#include <errno.h>
+#include <io.h>
+
+int __cdecl __mingw_access(const char *fname, int mode);
+
+int __cdecl __mingw_access(const char *fname, int mode)
+{
+ DWORD attr;
+
+ if (fname == NULL || (mode & ~(F_OK | X_OK | W_OK | R_OK)))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ attr = GetFileAttributesA(fname);
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ {
+ switch (GetLastError())
+ {
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ errno = ENOENT;
+ break;
+ case ERROR_ACCESS_DENIED:
+ errno = EACCES;
+ break;
+ default:
+ errno = EINVAL;
+ }
+ return -1;
+ }
+
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ /* All directories have read & write access */
+ return 0;
+ }
+
+ if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & W_OK))
+ {
+ /* no write permission on file */
+ errno = EACCES;
+ return -1;
+ }
+ else
+ return 0;
+}
diff --git a/mingw-w64-headers/crt/io.h b/mingw-w64-headers/crt/io.h
index a7cc5fc..4a5b08b 100644
--- a/mingw-w64-headers/crt/io.h
+++ b/mingw-w64-headers/crt/io.h
@@ -365,9 +365,7 @@
/* Old versions of MSVCRT access() just ignored X_OK, while the version
shipped with Vista, returns an error code. This will restore the
old behaviour */
-static inline int __mingw_access (const char *__fname, int __mode) {
- return _access (__fname, __mode & ~X_OK);
-}
+int __cdecl __mingw_access (const char *__fname, int __mode);
#define access(__f,__m) __mingw_access (__f, __m)
#endif