libos: Add Directory::list()
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-04-28 22:41:44 +02:00
parent 6c5d6aaf00
commit ac4bbd135b
Signed by: apio
GPG Key ID: B8A7D06E42258954
7 changed files with 38 additions and 17 deletions

View File

@ -239,8 +239,9 @@ static Result<void> load_services()
{ {
auto dir = TRY(os::Directory::open("/etc/init")); auto dir = TRY(os::Directory::open("/etc/init"));
String entry; auto services = TRY(dir->list(os::Directory::Filter::ParentAndBase));
while ((entry = TRY(dir->next(os::Directory::Filter::ParentAndBase))), !entry.is_empty())
for (const auto& entry : services)
{ {
auto service_path = TRY(PathParser::join("/etc/init"_sv, entry.view())); auto service_path = TRY(PathParser::join("/etc/init"_sv, entry.view()));
TRY(load_service(service_path.view())); TRY(load_service(service_path.view()));

View File

@ -25,13 +25,14 @@ Result<int> luna_main(int argc, char** argv)
else if (show_all) else if (show_all)
filter = os::Directory::Filter::None; filter = os::Directory::Filter::None;
auto files = TRY(dir->list(filter));
int first_ent = 1; int first_ent = 1;
do { for (const auto& file : files)
auto ent = TRY(dir->next(filter)); {
if (ent.is_empty()) break; printf(first_ent ? "%s" : " %s", file.chars());
printf(first_ent ? "%s" : " %s", ent.chars());
first_ent = 0; first_ent = 0;
} while (1); }
putchar('\n'); putchar('\n');

View File

@ -26,6 +26,7 @@ extern "C"
struct dirent* readdir(DIR* stream); struct dirent* readdir(DIR* stream);
int closedir(DIR* stream); int closedir(DIR* stream);
int dirfd(DIR* stream); int dirfd(DIR* stream);
void rewinddir(DIR* stream);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -66,4 +66,9 @@ extern "C"
{ {
return stream->_fd; return stream->_fd;
} }
void rewinddir(DIR* stream)
{
lseek(stream->_fd, 0, SEEK_SET);
}
} }

View File

@ -2,6 +2,7 @@
#include <dirent.h> #include <dirent.h>
#include <luna/SharedPtr.h> #include <luna/SharedPtr.h>
#include <luna/String.h> #include <luna/String.h>
#include <luna/Vector.h>
namespace os namespace os
{ {
@ -21,6 +22,10 @@ namespace os
Result<String> next(Filter filter); Result<String> next(Filter filter);
Result<Vector<String>> list(Filter filter);
void rewind();
int fd() int fd()
{ {
return dirfd(m_dirp); return dirfd(m_dirp);

View File

@ -66,6 +66,23 @@ namespace os
return String::from_cstring(ent->d_name); return String::from_cstring(ent->d_name);
} }
Result<Vector<String>> Directory::list(Filter filter)
{
Vector<String> result;
rewind();
String entry {};
while ((entry = TRY(next(filter))), !entry.is_empty()) TRY(result.try_append(move(entry)));
return result;
}
void Directory::rewind()
{
rewinddir(m_dirp);
}
Directory::~Directory() Directory::~Directory()
{ {
if (m_dirp) closedir(m_dirp); if (m_dirp) closedir(m_dirp);

View File

@ -63,16 +63,7 @@ namespace os::FileSystem
auto dir = TRY(os::Directory::openat(dirfd, path)); auto dir = TRY(os::Directory::openat(dirfd, path));
Vector<String> entries; Vector<String> entries = TRY(dir->list(os::Directory::Filter::ParentAndBase));
// FIXME: This is done because the kernel doesn't appreciate us deleting entries while iterating over
// directories. This means that we have to iterate first, then delete.
String ent;
while ((ent = TRY(dir->next(os::Directory::Filter::ParentAndBase))), !ent.is_empty())
{
TRY(entries.try_append(move(ent)));
}
for (const auto& entry : entries) { TRY(remove_tree_at(dir->fd(), entry.view())); } for (const auto& entry : entries) { TRY(remove_tree_at(dir->fd(), entry.view())); }