34 lines
1.2 KiB
Diff
34 lines
1.2 KiB
Diff
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
|
||
index 0b11330..4c1dff2 100644
|
||
--- a/src/libutil/util.cc
|
||
+++ b/src/libutil/util.cc
|
||
@@ -198,17 +198,17 @@ bool pathExists(const Path & path)
|
||
Path readLink(const Path & path)
|
||
{
|
||
checkInterrupt();
|
||
- struct stat st = lstat(path);
|
||
- if (!S_ISLNK(st.st_mode))
|
||
- throw Error(format("‘%1%’ is not a symlink") % path);
|
||
- char buf[st.st_size];
|
||
- ssize_t rlsize = readlink(path.c_str(), buf, st.st_size);
|
||
- if (rlsize == -1)
|
||
- throw SysError(format("reading symbolic link ‘%1%’") % path);
|
||
- else if (rlsize > st.st_size)
|
||
- throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%")
|
||
- % path % rlsize % st.st_size);
|
||
- return string(buf, st.st_size);
|
||
+ for (ssize_t bufSize = PATH_MAX/4; true; bufSize += bufSize/2) {
|
||
+ char buf[bufSize];
|
||
+ ssize_t rlSize = readlink(path.c_str(), buf, bufSize);
|
||
+ if (rlSize == -1)
|
||
+ if (errno == EINVAL)
|
||
+ throw Error(format("'%1%' is not a symlink") % path);
|
||
+ else
|
||
+ throw SysError(format("reading symbolic link '%1%'") % path);
|
||
+ else if (rlSize < bufSize)
|
||
+ return string(buf, rlSize);
|
||
+ }
|
||
}
|
||
|
||
|