libos+rm: Add recursive removal of directories
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
05144f65d1
commit
d56e8baca5
@ -4,12 +4,16 @@
|
|||||||
Result<int> luna_main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView path;
|
StringView path;
|
||||||
|
bool recursive;
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_positional_argument(path, "path"_sv, true);
|
parser.add_positional_argument(path, "path"_sv, true);
|
||||||
|
parser.add_switch_argument(recursive, 'r', "recursive"_sv);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
TRY(os::FileSystem::remove(path));
|
if (!recursive) TRY(os::FileSystem::remove(path));
|
||||||
|
else
|
||||||
|
TRY(os::FileSystem::remove_tree(path));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,10 @@ namespace os
|
|||||||
Result<void> create_directory(StringView path, mode_t mode);
|
Result<void> create_directory(StringView path, mode_t mode);
|
||||||
|
|
||||||
Result<void> remove(StringView path);
|
Result<void> remove(StringView path);
|
||||||
|
Result<void> removeat(int dirfd, StringView path);
|
||||||
|
|
||||||
|
Result<void> remove_tree(StringView path);
|
||||||
|
Result<void> remove_tree_at(int dirfd, StringView path);
|
||||||
|
|
||||||
Result<String> working_directory();
|
Result<String> working_directory();
|
||||||
Result<String> home_directory();
|
Result<String> home_directory();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
#include <os/FileSystem.h>
|
#include <os/FileSystem.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@ -38,11 +39,50 @@ namespace os::FileSystem
|
|||||||
|
|
||||||
Result<void> remove(StringView path)
|
Result<void> remove(StringView path)
|
||||||
{
|
{
|
||||||
long rc = syscall(SYS_unlinkat, AT_FDCWD, path.chars(), 0);
|
return removeat(AT_FDCWD, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void> removeat(int dirfd, StringView path)
|
||||||
|
{
|
||||||
|
long rc = syscall(SYS_unlinkat, dirfd, path.chars(), 0);
|
||||||
|
|
||||||
return Result<void>::from_syscall(rc);
|
return Result<void>::from_syscall(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> remove_tree(StringView path)
|
||||||
|
{
|
||||||
|
return remove_tree_at(AT_FDCWD, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void> remove_tree_at(int dirfd, StringView path)
|
||||||
|
{
|
||||||
|
auto rc = removeat(dirfd, path);
|
||||||
|
if (!rc.has_error()) return {};
|
||||||
|
if (rc.error() != ENOTEMPTY) return rc.release_error();
|
||||||
|
|
||||||
|
DIR* dp = opendir(path.chars());
|
||||||
|
if (!dp) return err(errno);
|
||||||
|
|
||||||
|
Vector<String> entries;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
struct dirent* ent;
|
||||||
|
while ((ent = readdir(dp)))
|
||||||
|
{
|
||||||
|
if ("."_sv == ent->d_name || ".."_sv == ent->d_name) continue;
|
||||||
|
auto entry = TRY(String::from_cstring(ent->d_name));
|
||||||
|
TRY(entries.try_append(move(entry)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& entry : entries) { TRY(remove_tree_at(dp->_fd, entry.view())); }
|
||||||
|
|
||||||
|
closedir(dp);
|
||||||
|
|
||||||
|
return removeat(dirfd, path);
|
||||||
|
}
|
||||||
|
|
||||||
Result<String> working_directory()
|
Result<String> working_directory()
|
||||||
{
|
{
|
||||||
char* ptr = getcwd(NULL, 0);
|
char* ptr = getcwd(NULL, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user