* Resolve all symlink components in the location of the temporary

build directory (TMPDIR, i.e., /tmp).  Fixes NIX-26.
This commit is contained in:
Eelco Dolstra 2006-01-08 17:16:03 +00:00
parent 0f8d3c871b
commit 04be39734f
2 changed files with 25 additions and 4 deletions

View file

@ -53,7 +53,7 @@ Path absPath(Path path, Path dir)
} }
Path canonPath(const Path & path) Path canonPath(const Path & path, bool resolveSymlinks)
{ {
string s; string s;
@ -61,6 +61,11 @@ Path canonPath(const Path & path)
throw Error(format("not an absolute path: `%1%'") % path); throw Error(format("not an absolute path: `%1%'") % path);
string::const_iterator i = path.begin(), end = path.end(); 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) { while (1) {
@ -84,6 +89,20 @@ Path canonPath(const Path & path)
else { else {
s += '/'; s += '/';
while (i != end && *i != '/') s += *i++; 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 Path tempName()
{ {
static int counter = 0; 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(); return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str();
} }

View file

@ -64,8 +64,10 @@ string getEnv(const string & key, const string & def = "");
Path absPath(Path path, Path dir = ""); Path absPath(Path path, Path dir = "");
/* Canonicalise a path by removing all `.' or `..' components and /* Canonicalise a path by removing all `.' or `..' components and
double or trailing slashes. */ double or trailing slashes. Optionally resolves all symlink
Path canonPath(const Path & path); 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., /* Return the directory part of the given canonical path, i.e.,
everything before the final `/'. If the path is the root or an everything before the final `/'. If the path is the root or an