diff --git a/src/utils.cpp b/src/utils.cpp index 8455c334de..ce945e7ad5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -37,6 +37,15 @@ #include #endif +// target Windows version is Windows 7 and later +#if defined(_WIN32_WINNT) +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT _WIN32_WINNT_WIN7 +#include +#include +#endif + /*! \file utils.cpp */ /* @@ -154,6 +163,9 @@ std::string utils::getsyserror() /** On Linux the folder /proc/self/fd holds symbolic links to the actual * pathnames associated with each open file descriptor of the current process. + * On macOS the same kind of information can be obtained using ``fcntl(fd,F_GETPATH,buf)``. + * On Windows we use ``GetFinalPathNameByHandleA()`` which is available with + * Windows Vista and later. * * This function is used to provide a filename with error messages in functions * where the filename is not passed as an argument, but the FILE * pointer. @@ -174,6 +186,13 @@ const char *utils::guesspath(char *buf, int len, FILE *fp) strncpy(buf, filepath, len - 1); else strncpy(buf, "(unknown)", len - 1); +#elif defined(_WIN32) + char filepath[MAX_PATH]; + HANDLE h = (HANDLE) _get_osfhandle(_fileno(fp)); + if (GetFinalPathNameByHandleA(h, filepath, PATH_MAX, FILE_NAME_NORMALIZED) > 0) + strncpy(buf, filepath, len - 1); + else + strncpy(buf, "(unknown)", len - 1); #else strncpy(buf, "(unknown)", len - 1); #endif diff --git a/src/utils.h b/src/utils.h index 3d34b72b74..f53374144e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -408,7 +408,7 @@ namespace utils { /*! Try to detect pathname from FILE pointer. * - * Currently only supported on Linux and macOS, otherwise will report "(unknown)". + * Currently supported on Linux, macOS, and Windows, otherwise will report "(unknown)". * * \param buf storage buffer for pathname. output will be truncated if not large enough * \param len size of storage buffer. output will be truncated to this length - 1 diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 60d6d608b3..5fb45cdf77 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -722,7 +722,7 @@ TEST(Utils, guesspath) { char buf[256]; FILE *fp = fopen("test_guesspath.txt", "w"); -#if defined(__linux__) || (__APPLE__) +#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32) const char *path = utils::guesspath(buf, sizeof(buf), fp); ASSERT_THAT(path, EndsWith("test_guesspath.txt")); #else