diff --git a/lib/libc/mingw/misc/mingw-access.c b/lib/libc/mingw/misc/mingw-access.c new file mode 100644 index 0000000000..6f405ab99c --- /dev/null +++ b/lib/libc/mingw/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 +#include +#include + +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/lib/libc/mingw/misc/ucrt-access.c b/lib/libc/mingw/misc/ucrt-access.c new file mode 100644 index 0000000000..e0c93cad05 --- /dev/null +++ b/lib/libc/mingw/misc/ucrt-access.c @@ -0,0 +1,19 @@ +/** + * 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 + +int __cdecl __mingw_access(const char *fname, int mode); + +int __cdecl access(const char *fname, int mode) +{ + /* On UCRT, unconditionally forward access to __mingw_access. UCRT's + * access() function return an error if passed the X_OK constant, + * while msvcrt.dll's access() doesn't. (It's reported that msvcrt.dll's + * access() also returned errors on X_OK in the version shipped in Vista, + * but in recent tests it's no longer the case.) */ + return __mingw_access(fname, mode); +} diff --git a/src/mingw.zig b/src/mingw.zig index 48e484cf2f..a06102a5ea 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -697,6 +697,7 @@ const mingwex_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "mbrtowc.c", "misc" ++ path.sep_str ++ "mbsinit.c", "misc" ++ path.sep_str ++ "mempcpy.c", + "misc" ++ path.sep_str ++ "mingw-access.c", "misc" ++ path.sep_str ++ "mingw-aligned-malloc.c", "misc" ++ path.sep_str ++ "mingw_getsp.S", "misc" ++ path.sep_str ++ "mingw_matherr.c", @@ -716,6 +717,7 @@ const mingwex_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "tfind.c", "misc" ++ path.sep_str ++ "tsearch.c", "misc" ++ path.sep_str ++ "twalk.c", + "misc" ++ path.sep_str ++ "ucrt-access.c", "misc" ++ path.sep_str ++ "wcrtomb.c", "misc" ++ path.sep_str ++ "wcsnlen.c", "misc" ++ path.sep_str ++ "wcstof.c",