3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-10 04:12:25 +00:00

Rewrote Linux edition of proc_self_dirname() to handle any symlink length.

This make sure the method work also when the program is located in
deep or long file paths, longer than both PATH_MAX and "getconf
PATH_MAX .".  Use the same code on GNU Hurd, where it now work.

I am not sure how to test this in a platform independent way.
This commit is contained in:
Petter Reinholdtsen 2026-04-19 06:21:50 +02:00
parent 413169663d
commit 89d360aa4a

View file

@ -471,17 +471,30 @@ struct TclPass : public Pass {
#endif
#if defined(__linux__) || defined(__CYGWIN__)
#if defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__)
std::string proc_self_dirname()
{
char path[PATH_MAX];
ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path));
std::string path(4096, '\0');
ssize_t buflen = -1;
// Double until sucess, while avoiding endless loop. Give up
// when symlink is longer than 4096*(2^30) = 4398046511104
// bytes.
for (int tries = 30; 0 < tries; tries--) {
buflen = readlink("/proc/self/exe", path.data(), path.size());
if (buflen < (ssize_t)path.size())
break;
else
path.resize(path.size() * 2);
}
if (buflen < 0) {
log_error("readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno));
path.resize(0);
} else {
while (buflen > 0 && path[buflen-1] != '/')
buflen--;
path.resize(buflen);
}
while (buflen > 0 && path[buflen-1] != '/')
buflen--;
return std::string(path, buflen);
return path;
}
#elif defined(__FreeBSD__) || defined(__NetBSD__)
std::string proc_self_dirname()