forked from lix-project/lix
* Resolve all symlink components in the location of the temporary
build directory (TMPDIR, i.e., /tmp). Fixes NIX-26.
This commit is contained in:
parent
0f8d3c871b
commit
04be39734f
|
@ -53,7 +53,7 @@ Path absPath(Path path, Path dir)
|
|||
}
|
||||
|
||||
|
||||
Path canonPath(const Path & path)
|
||||
Path canonPath(const Path & path, bool resolveSymlinks)
|
||||
{
|
||||
string s;
|
||||
|
||||
|
@ -61,6 +61,11 @@ Path canonPath(const Path & path)
|
|||
throw Error(format("not an absolute path: `%1%'") % path);
|
||||
|
||||
string::const_iterator i = path.begin(), end = path.end();
|
||||
string temp;
|
||||
|
||||
/* Count the number of times we follow a symlink and stop at some
|
||||
arbitrary (but high) limit to prevent infinite loops. */
|
||||
unsigned int followCount = 0, maxFollow = 1024;
|
||||
|
||||
while (1) {
|
||||
|
||||
|
@ -84,6 +89,20 @@ Path canonPath(const Path & path)
|
|||
else {
|
||||
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 (resolveSymlinks && isLink(s)) {
|
||||
followCount++;
|
||||
if (followCount >= maxFollow)
|
||||
throw Error(format("infinite symlink recursion in path `%1%'") % path);
|
||||
temp = absPath(readLink(s), dirOf(s))
|
||||
+ string(i, end);
|
||||
i = temp.begin(); /* restart */
|
||||
end = temp.end();
|
||||
s = "";
|
||||
/* !!! potential for infinite loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,7 +283,7 @@ void makePathReadOnly(const Path & path)
|
|||
static Path tempName()
|
||||
{
|
||||
static int counter = 0;
|
||||
Path tmpRoot = canonPath(getEnv("TMPDIR", "/tmp"));
|
||||
Path tmpRoot = canonPath(getEnv("TMPDIR", "/tmp"), true);
|
||||
return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,10 @@ string getEnv(const string & key, const string & def = "");
|
|||
Path absPath(Path path, Path dir = "");
|
||||
|
||||
/* Canonicalise a path by removing all `.' or `..' components and
|
||||
double or trailing slashes. */
|
||||
Path canonPath(const Path & path);
|
||||
double or trailing slashes. Optionally resolves all symlink
|
||||
components such that each component of the resulting path is *not*
|
||||
a symbolic link. */
|
||||
Path canonPath(const Path & path, bool resolveSymlinks = false);
|
||||
|
||||
/* Return the directory part of the given canonical path, i.e.,
|
||||
everything before the final `/'. If the path is the root or an
|
||||
|
|
Loading…
Reference in a new issue