LibGUI: Have GFileSystemModel use stat instead of lstat for the root

This allows you to set the GFileSystemModel root to a symlink to a
directory and it nicely opens that directory like you would expect.
This commit is contained in:
Andreas Kling 2020-01-27 22:10:19 +01:00
parent c64904a483
commit f2f0965edd
Notes: sideshowbarker 2024-07-19 09:46:15 +09:00
2 changed files with 10 additions and 7 deletions

View File

@ -49,12 +49,16 @@ GModelIndex GFileSystemModel::Node::index(const GFileSystemModel& model, int col
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
bool GFileSystemModel::Node::fetch_data_using_lstat(const String& full_path) bool GFileSystemModel::Node::fetch_data(const String& full_path, bool is_root)
{ {
struct stat st; struct stat st;
int rc = lstat(full_path.characters(), &st); int rc;
if (is_root)
rc = stat(full_path.characters(), &st);
else
rc = lstat(full_path.characters(), &st);
if (rc < 0) { if (rc < 0) {
perror("lstat"); perror("stat/lstat");
return false; return false;
} }
@ -64,7 +68,6 @@ bool GFileSystemModel::Node::fetch_data_using_lstat(const String& full_path)
gid = st.st_gid; gid = st.st_gid;
inode = st.st_ino; inode = st.st_ino;
mtime = st.st_mtime; mtime = st.st_mtime;
return true; return true;
} }
@ -86,7 +89,7 @@ void GFileSystemModel::Node::traverse_if_needed(const GFileSystemModel& model)
String name = di.next_path(); String name = di.next_path();
String child_path = String::format("%s/%s", full_path.characters(), name.characters()); String child_path = String::format("%s/%s", full_path.characters(), name.characters());
NonnullOwnPtr<Node> child = make<Node>(); NonnullOwnPtr<Node> child = make<Node>();
bool ok = child->fetch_data_using_lstat(child_path); bool ok = child->fetch_data(child_path, false);
if (!ok) if (!ok)
continue; continue;
if (model.m_mode == DirectoriesOnly && !S_ISDIR(child->mode)) if (model.m_mode == DirectoriesOnly && !S_ISDIR(child->mode))
@ -126,7 +129,7 @@ void GFileSystemModel::Node::reify_if_needed(const GFileSystemModel& model)
traverse_if_needed(model); traverse_if_needed(model);
if (mode != 0) if (mode != 0)
return; return;
fetch_data_using_lstat(full_path(model)); fetch_data(full_path(model), parent == nullptr);
} }
String GFileSystemModel::Node::full_path(const GFileSystemModel& model) const String GFileSystemModel::Node::full_path(const GFileSystemModel& model) const

View File

@ -88,7 +88,7 @@ public:
GModelIndex index(const GFileSystemModel&, int column) const; GModelIndex index(const GFileSystemModel&, int column) const;
void traverse_if_needed(const GFileSystemModel&); void traverse_if_needed(const GFileSystemModel&);
void reify_if_needed(const GFileSystemModel&); void reify_if_needed(const GFileSystemModel&);
bool fetch_data_using_lstat(const String& full_path); bool fetch_data(const String& full_path, bool is_root);
}; };
static NonnullRefPtr<GFileSystemModel> create(const StringView& root_path = "/", Mode mode = Mode::FilesAndDirectories) static NonnullRefPtr<GFileSystemModel> create(const StringView& root_path = "/", Mode mode = Mode::FilesAndDirectories)