diff --git a/Compat.c b/Compat.c index 096b938a..37e7c042 100644 --- a/Compat.c +++ b/Compat.c @@ -9,6 +9,7 @@ in the source distribution for its full text. #include "Compat.h" +#include #include // IWYU pragma: keep #include #include @@ -17,6 +18,41 @@ in the source distribution for its full text. #include "XUtils.h" // IWYU pragma: keep +int Compat_faccessat(int dirfd, + const char* pathname, + int mode, + int flags) { + int ret; + +#ifdef HAVE_FACCESSAT + + // Implementation note: AT_SYMLINK_NOFOLLOW unsupported on FreeBSD, fallback to lstat in that case + + errno = 0; + + ret = faccessat(dirfd, pathname, mode, flags); + if (!ret || errno != EINVAL) + return ret; + +#endif + + // Error out on unsupported configurations + if (dirfd != AT_FDCWD || mode != F_OK) { + errno = EINVAL; + return -1; + } + + // Fallback to stat(2)/lstat(2) depending on flags + struct stat statinfo; + if(flags) { + ret = lstat(pathname, &statinfo); + } else { + ret = stat(pathname, &statinfo); + } + + return ret; +} + int Compat_fstatat(int dirfd, const char* dirpath, const char* pathname, diff --git a/Compat.h b/Compat.h index c0085d5c..e513b1d3 100644 --- a/Compat.h +++ b/Compat.h @@ -11,6 +11,11 @@ in the source distribution for its full text. #include +int Compat_faccessat(int dirfd, + const char* pathname, + int mode, + int flags); + int Compat_fstatat(int dirfd, const char* dirpath, const char* pathname, diff --git a/configure.ac b/configure.ac index aed4947e..de47b516 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,7 @@ AC_TYPE_UID_T # ---------------------------------------------------------------------- AC_FUNC_CLOSEDIR_VOID AC_FUNC_STAT -AC_CHECK_FUNCS([fstatat memmove readlinkat strdup strncasecmp strstr]) +AC_CHECK_FUNCS([faccessat fstatat memmove readlinkat strdup strncasecmp strstr]) AC_SEARCH_LIBS([dlopen], [dl dld]) diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 498ee0ef..522b96f5 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -37,6 +37,7 @@ in the source distribution for its full text. #endif #include "CRT.h" +#include "Compat.h" #include "LinuxProcess.h" #include "Macros.h" #include "Object.h"