--- old/src/jdk.incubator.jpackage/macosx/native/common/MacSysInfo.cpp 2020-08-06 23:08:25.000000000 -0700 +++ new/src/jdk.incubator.jpackage/macosx/native/common/MacSysInfo.cpp 2020-08-06 23:08:25.000000000 -0700 @@ -23,12 +23,39 @@ * questions. */ +#include +#include #include #include "FileUtils.h" #include "ErrorHandling.h" namespace SysInfo { +tstring getRealPath(std::vector in) { + std::vector out(PATH_MAX); + + struct stat sb; + if (lstat(in.data(), &sb) == -1) { + JP_THROW(tstrings::any() << "lstat(" << in.data() + << ") failed. Error: " << lastCRTError()); + } + + // readlink() will fail if called on real path, so if we have real path, then just + // use it + if (!S_ISLNK(sb.st_mode)) { + return tstring(in.data(), in.size() - 1 /* don't count trailing '0' */); + } + + // Get real path, since _NSGetExecutablePath can return symbolic link + ssize_t len = readlink(in.data(), out.data(), PATH_MAX); + if (len < 0) { + JP_THROW(tstrings::any() << "readlink(" << in.data() + << ") failed. Error: " << lastCRTError()); + } + + return tstring(out.data(), len); +} + tstring getProcessModulePath() { std::vector buffer; uint32_t bufferSize = 0; @@ -44,8 +71,9 @@ buffer.resize(bufferSize); } while (true); - tstring reply = tstring(buffer.data(), - buffer.size() - 1 /* don't count trailing '0' */); + + tstring reply = getRealPath(buffer); + return FileUtils::toAbsolutePath(reply); }