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:
@@ -252,6 +252,37 @@ find_dir_entry(const char *path, NodeRef ref, string &name, bool skipDot)
|
|||||||
return error;
|
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
|
// normalize_dir_path
|
||||||
static status_t
|
static status_t
|
||||||
normalize_dir_path(string path, NodeRef ref, string &normalizedPath)
|
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
|
// find the entry
|
||||||
string name;
|
string name;
|
||||||
status_t error = find_dir_entry(path.c_str(), ref, name, true) ;
|
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;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// recurse to get the parent dir path, if found
|
// recurse to get the parent dir path, if found
|
||||||
error = normalize_dir_path(path, parentRef, normalizedPath);
|
error = normalize_dir_path(path, parentRef, normalizedPath);
|
||||||
|
|||||||
Reference in New Issue
Block a user