aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-04-15 14:11:51 +0200
committerGitHub <noreply@github.com>2021-04-15 14:11:51 +0200
commit3ee0ecdda0e64f39d9702617f2547b0e3d5619b6 (patch)
tree03b2cf9fc0ff426b3ec319e98053186d3e3dea02 /src/libutil
parent4cd9bd19cd8fecf1dd4cff1f0178091da2ef1316 (diff)
parentf3f228700a52857fe6e8632df4e935551ea219ff (diff)
Merge pull request #4679 from ony/feature/one-pass-canon-path
Optimize canonPath to resolve relative symlinks in one pass
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/util.cc14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 60b318559..5f597bf06 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -144,16 +144,18 @@ Path canonPath(const Path & path, bool resolveSymlinks)
s += '/';
while (i != end && *i != '/') s += *i++;
- /* If s points to a symlink, resolve it and restart (since
- the symlink target might contain new symlinks). */
+ /* If s points to a symlink, resolve it and continue from there */
if (resolveSymlinks && isLink(s)) {
if (++followCount >= maxFollow)
throw Error("infinite symlink recursion in path '%1%'", path);
- temp = absPath(readLink(s), dirOf(s))
- + string(i, end);
- i = temp.begin(); /* restart */
+ temp = readLink(s) + string(i, end);
+ i = temp.begin();
end = temp.end();
- s = "";
+ if (!temp.empty() && temp[0] == '/') {
+ s.clear(); /* restart for symlinks pointing to absolute path */
+ } else {
+ s = dirOf(s);
+ }
}
}
}