libroot_build: make path normalization more robust

In case we don't have read permission for an ancestor directory, we try
to guess the path from the CWD.
This commit is contained in:
Ingo Weinhold
2013-07-04 10:16:15 +02:00
parent 2ebcd86dfe
commit 2f5551ec2a
+43 -1
View File
@@ -252,6 +252,37 @@ find_dir_entry(const char *path, NodeRef ref, string &name, bool skipDot)
return error;
}
static bool
guess_normalized_dir_path(string path, NodeRef ref, string& _normalizedPath)
{
// We assume the CWD is normalized and hope that the directory is an
// ancestor of it. We just chop off path components until we find a match or
// hit root.
char cwd[B_PATH_NAME_LENGTH];
if (getcwd(cwd, sizeof(cwd)) == NULL)
return false;
while (cwd[0] == '/') {
struct stat st;
if (stat(cwd, &st) == 0) {
if (st.st_dev == ref.device && st.st_ino == ref.node) {
_normalizedPath = cwd;
return true;
}
}
*strrchr(cwd, '/') = '\0';
}
// TODO: If path is absolute, we could also try to work with that, though
// the other way around -- trying prefixes until we hit a "." or ".."
// component.
return false;
}
// normalize_dir_path
static status_t
normalize_dir_path(string path, NodeRef ref, string &normalizedPath)
@@ -274,8 +305,19 @@ normalize_dir_path(string path, NodeRef ref, string &normalizedPath)
// find the entry
string name;
status_t error = find_dir_entry(path.c_str(), ref, name, true) ;
if (error != B_OK)
if (error != B_OK) {
if (error != B_ENTRY_NOT_FOUND) {
// We couldn't open the directory. This might be because we don't
// have read permission. We're OK with not fully normalizing the
// path and try to guess the path in this case. Note: We don't check
// error for B_PERMISSION_DENIED, since opendir() may clobber the
// actual kernel error code with something not helpful.
if (guess_normalized_dir_path(path, ref, normalizedPath))
return B_OK;
}
return error;
}
// recurse to get the parent dir path, if found
error = normalize_dir_path(path, parentRef, normalizedPath);