support utils::guesspath() also on Windows

This commit is contained in:
Axel Kohlmeyer
2021-09-08 18:17:14 -04:00
parent b87a48e40b
commit 9cdb83a24d
3 changed files with 21 additions and 2 deletions

View File

@ -37,6 +37,15 @@
#include <sys/syslimits.h>
#endif
// target Windows version is Windows 7 and later
#if defined(_WIN32_WINNT)
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT _WIN32_WINNT_WIN7
#include <io.h>
#include <windows.h>
#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

View File

@ -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

View File

@ -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