Compare commits
No commits in common. "6c5d6aaf0001e27f0830de4f06e6e45de1e2034b" and "ae7c841fff3359928c98c6a60bfa53e61edc3895" have entirely different histories.
6c5d6aaf00
...
ae7c841fff
@ -1,10 +1,10 @@
|
||||
#include <luna/PathParser.h>
|
||||
#include <luna/String.h>
|
||||
#include <luna/Vector.h>
|
||||
#include <os/Directory.h>
|
||||
#include <os/File.h>
|
||||
#include <os/Process.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -237,15 +237,24 @@ static Result<void> load_service(StringView path)
|
||||
|
||||
static Result<void> load_services()
|
||||
{
|
||||
auto dir = TRY(os::Directory::open("/etc/init"));
|
||||
|
||||
String entry;
|
||||
while ((entry = TRY(dir->next(os::Directory::Filter::ParentAndBase))), !entry.is_empty())
|
||||
DIR* dp = opendir("/etc/init");
|
||||
if (!dp)
|
||||
{
|
||||
auto service_path = TRY(PathParser::join("/etc/init"_sv, entry.view()));
|
||||
fprintf(g_init_log, "[init] cannot open service directory: %s\n", strerror(errno));
|
||||
return {};
|
||||
}
|
||||
|
||||
dirent* ent;
|
||||
while ((ent = readdir(dp)))
|
||||
{
|
||||
if ("."_sv == ent->d_name || ".."_sv == ent->d_name) continue;
|
||||
|
||||
auto service_path = TRY(PathParser::join("/etc/init"_sv, ent->d_name));
|
||||
TRY(load_service(service_path.view()));
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
24
apps/ls.cpp
24
apps/ls.cpp
@ -1,6 +1,7 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/Directory.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -18,22 +19,25 @@ Result<int> luna_main(int argc, char** argv)
|
||||
parser.add_switch_argument(show_almost_all, 'A', "almost-all"_sv, "list all files except '.' and '..'"_sv);
|
||||
parser.parse(argc, argv);
|
||||
|
||||
auto dir = TRY(os::Directory::open(pathname));
|
||||
|
||||
auto filter = os::Directory::Filter::Hidden;
|
||||
if (show_almost_all) filter = os::Directory::Filter::ParentAndBase;
|
||||
else if (show_all)
|
||||
filter = os::Directory::Filter::None;
|
||||
DIR* dp = opendir(pathname.chars());
|
||||
if (!dp)
|
||||
{
|
||||
perror("opendir");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int first_ent = 1;
|
||||
do {
|
||||
auto ent = TRY(dir->next(filter));
|
||||
if (ent.is_empty()) break;
|
||||
printf(first_ent ? "%s" : " %s", ent.chars());
|
||||
struct dirent* ent = readdir(dp);
|
||||
if (!ent) break;
|
||||
if (show_almost_all && (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))) continue;
|
||||
if (!show_all && !show_almost_all && *ent->d_name == '.') continue;
|
||||
printf(first_ent ? "%s" : " %s", ent->d_name);
|
||||
first_ent = 0;
|
||||
} while (1);
|
||||
|
||||
putchar('\n');
|
||||
|
||||
closedir(dp);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "Log.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "sys/Syscall.h"
|
||||
#include "thread/Scheduler.h"
|
||||
@ -19,8 +18,6 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
|
||||
|
||||
if (basename.view() == ".") return err(EINVAL);
|
||||
|
||||
kinfoln("unlinkat: remove %s from directory %s, dirfd is %d", basename.chars(), dirname.chars(), dirfd);
|
||||
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, dirname, false));
|
||||
if (!VFS::can_write(inode, current->auth)) return err(EACCES);
|
||||
|
||||
|
@ -22,10 +22,8 @@ extern "C"
|
||||
#endif
|
||||
|
||||
DIR* opendir(const char* path);
|
||||
DIR* fdopendir(int fd);
|
||||
struct dirent* readdir(DIR* stream);
|
||||
int closedir(DIR* stream);
|
||||
int dirfd(DIR* stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -25,16 +25,6 @@ extern "C"
|
||||
return dp;
|
||||
}
|
||||
|
||||
DIR* fdopendir(int fd)
|
||||
{
|
||||
DIR* dp = (DIR*)malloc(sizeof(DIR));
|
||||
if (!dp) { return nullptr; }
|
||||
|
||||
dp->_fd = fd;
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
struct dirent* readdir(DIR* stream)
|
||||
{
|
||||
// FIXME: Very hackish, right now luna_dirent and dirent have the same layout.
|
||||
@ -61,9 +51,4 @@ extern "C"
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dirfd(DIR* stream)
|
||||
{
|
||||
return stream->_fd;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,5 @@ class String
|
||||
|
||||
usize m_length { 0 };
|
||||
|
||||
void empty();
|
||||
|
||||
static Result<String> vformat(StringView fmt, va_list ap);
|
||||
};
|
||||
|
@ -5,11 +5,6 @@
|
||||
#include <luna/Vector.h>
|
||||
|
||||
String::String()
|
||||
{
|
||||
empty();
|
||||
}
|
||||
|
||||
void String::empty()
|
||||
{
|
||||
m_inline = true;
|
||||
m_length = 0;
|
||||
@ -25,7 +20,7 @@ String::String(String&& other)
|
||||
|
||||
if (m_inline) memcpy(m_inline_storage, other.m_inline_storage, sizeof(m_inline_storage));
|
||||
|
||||
other.empty();
|
||||
other.m_string = nullptr;
|
||||
}
|
||||
|
||||
String& String::operator=(String&& other)
|
||||
@ -41,7 +36,7 @@ String& String::operator=(String&& other)
|
||||
|
||||
if (m_inline) memcpy(m_inline_storage, other.m_inline_storage, sizeof(m_inline_storage));
|
||||
|
||||
other.empty();
|
||||
other.m_string = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ set(SOURCES
|
||||
src/File.cpp
|
||||
src/FileSystem.cpp
|
||||
src/Process.cpp
|
||||
src/Directory.cpp
|
||||
src/Main.cpp
|
||||
)
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#include <dirent.h>
|
||||
#include <luna/SharedPtr.h>
|
||||
#include <luna/String.h>
|
||||
|
||||
namespace os
|
||||
{
|
||||
class Directory
|
||||
{
|
||||
public:
|
||||
static Result<SharedPtr<Directory>> open(StringView path);
|
||||
|
||||
static Result<SharedPtr<Directory>> openat(int dirfd, StringView path);
|
||||
|
||||
enum class Filter
|
||||
{
|
||||
None,
|
||||
Hidden,
|
||||
ParentAndBase
|
||||
};
|
||||
|
||||
Result<String> next(Filter filter);
|
||||
|
||||
int fd()
|
||||
{
|
||||
return dirfd(m_dirp);
|
||||
}
|
||||
|
||||
~Directory();
|
||||
|
||||
private:
|
||||
Directory(Badge<Directory>);
|
||||
|
||||
DIR* m_dirp { nullptr };
|
||||
};
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
#include <luna/CString.h>
|
||||
#include <os/Directory.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static bool should_skip_entry(const char* name, os::Directory::Filter filter)
|
||||
{
|
||||
if (filter == os::Directory::Filter::None) return false;
|
||||
|
||||
if (filter == os::Directory::Filter::Hidden) return *name == '.';
|
||||
|
||||
if (filter == os::Directory::Filter::ParentAndBase) return !strcmp(name, ".") || !strcmp(name, "..");
|
||||
|
||||
unreachable();
|
||||
}
|
||||
|
||||
namespace os
|
||||
{
|
||||
Result<SharedPtr<Directory>> Directory::open(StringView path)
|
||||
{
|
||||
auto dir = TRY(adopt_shared_if_nonnull(new (std::nothrow) Directory({})));
|
||||
|
||||
DIR* dp = opendir(path.chars());
|
||||
if (!dp) return err(errno);
|
||||
|
||||
dir->m_dirp = dp;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
Result<SharedPtr<Directory>> Directory::openat(int dirfd, StringView path)
|
||||
{
|
||||
auto dir = TRY(adopt_shared_if_nonnull(new (std::nothrow) Directory({})));
|
||||
|
||||
long rc = syscall(SYS_openat, dirfd, path.chars(), O_RDONLY | O_DIRECTORY, 0);
|
||||
int fd = TRY(Result<int>::from_syscall(rc));
|
||||
|
||||
DIR* dp = fdopendir(fd);
|
||||
if (!dp)
|
||||
{
|
||||
close(fd);
|
||||
return err(errno);
|
||||
}
|
||||
|
||||
dir->m_dirp = dp;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
Result<String> Directory::next(Filter filter)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
struct dirent* ent;
|
||||
do {
|
||||
ent = readdir(m_dirp);
|
||||
} while (ent && should_skip_entry(ent->d_name, filter));
|
||||
|
||||
if (!ent && errno) return err(errno);
|
||||
|
||||
if (!ent) return String {};
|
||||
|
||||
return String::from_cstring(ent->d_name);
|
||||
}
|
||||
|
||||
Directory::~Directory()
|
||||
{
|
||||
if (m_dirp) closedir(m_dirp);
|
||||
}
|
||||
|
||||
Directory::Directory(Badge<Directory>)
|
||||
{
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#include <luna/String.h>
|
||||
#include <os/Directory.h>
|
||||
#include <os/FileSystem.h>
|
||||
|
||||
#include <dirent.h>
|
||||
@ -61,20 +60,25 @@ namespace os::FileSystem
|
||||
if (!rc.has_error()) return {};
|
||||
if (rc.error() != ENOTEMPTY) return rc.release_error();
|
||||
|
||||
auto dir = TRY(os::Directory::openat(dirfd, path));
|
||||
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.
|
||||
|
||||
String ent;
|
||||
while ((ent = TRY(dir->next(os::Directory::Filter::ParentAndBase))), !ent.is_empty())
|
||||
struct dirent* ent;
|
||||
while ((ent = readdir(dp)))
|
||||
{
|
||||
TRY(entries.try_append(move(ent)));
|
||||
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(dir->fd(), entry.view())); }
|
||||
for (const auto& entry : entries) { TRY(remove_tree_at(dp->_fd, entry.view())); }
|
||||
|
||||
closedir(dp);
|
||||
|
||||
return removeat(dirfd, path);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user