Compare commits
4 Commits
fbc0319cb6
...
cf9ba737f0
Author | SHA1 | Date |
---|---|---|
Bananymous | cf9ba737f0 | |
Bananymous | 2d0690ae2d | |
Bananymous | 71a2d0971f | |
Bananymous | 3bf57e0748 |
|
@ -103,7 +103,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<long> open_inode(VirtualFileSystem::File&&, int flags);
|
BAN::ErrorOr<long> open_inode(VirtualFileSystem::File&&, int flags);
|
||||||
|
|
||||||
BAN::ErrorOr<void> create_file_or_dir(const VirtualFileSystem::File& parent, BAN::StringView path, mode_t mode) const;
|
BAN::ErrorOr<void> create_file_or_dir(int fd, const char* path, mode_t mode) const;
|
||||||
BAN::ErrorOr<long> sys_openat(int, const char* path, int, mode_t);
|
BAN::ErrorOr<long> sys_openat(int, const char* path, int, mode_t);
|
||||||
BAN::ErrorOr<long> sys_close(int fd);
|
BAN::ErrorOr<long> sys_close(int fd);
|
||||||
BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count);
|
BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count);
|
||||||
|
@ -160,8 +160,6 @@ namespace Kernel
|
||||||
static BAN::ErrorOr<long> clean_poweroff(int command);
|
static BAN::ErrorOr<long> clean_poweroff(int command);
|
||||||
BAN::ErrorOr<long> sys_poweroff(int command);
|
BAN::ErrorOr<long> sys_poweroff(int command);
|
||||||
|
|
||||||
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_readdir(int fd, struct dirent* list, size_t list_len);
|
BAN::ErrorOr<long> sys_readdir(int fd, struct dirent* list, size_t list_len);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t*);
|
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t*);
|
||||||
|
@ -212,6 +210,7 @@ namespace Kernel
|
||||||
// Return false if access was page violation (segfault)
|
// Return false if access was page violation (segfault)
|
||||||
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr, bool wants_write);
|
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr, bool wants_write);
|
||||||
|
|
||||||
|
// FIXME: remove this API
|
||||||
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
|
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
|
||||||
|
|
||||||
// ONLY CALLED BY TIMER INTERRUPT
|
// ONLY CALLED BY TIMER INTERRUPT
|
||||||
|
@ -223,8 +222,15 @@ namespace Kernel
|
||||||
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
||||||
static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
|
static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags);
|
struct FileParent
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> find_parent(int fd, const char* path);
|
{
|
||||||
|
VirtualFileSystem::File parent;
|
||||||
|
BAN::StringView file_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags) const;
|
||||||
|
BAN::ErrorOr<FileParent> find_parent_file(int fd, const char* path, int flags) const;
|
||||||
|
BAN::ErrorOr<VirtualFileSystem::File> find_relative_parent(int fd, const char* path) const;
|
||||||
|
|
||||||
BAN::ErrorOr<void> validate_string_access(const char*);
|
BAN::ErrorOr<void> validate_string_access(const char*);
|
||||||
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
|
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
auto inode = BAN::RefPtr<ProcPidInode>::adopt(inode_ptr);
|
auto inode = BAN::RefPtr<ProcPidInode>::adopt(inode_ptr);
|
||||||
|
|
||||||
|
TRY(inode->link_inode(*inode, "."_sv));
|
||||||
|
TRY(inode->link_inode(static_cast<TmpInode&>(*fs.root_inode()), ".."_sv));
|
||||||
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_meminfo, fs, 0400)), "meminfo"_sv));
|
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_meminfo, fs, 0400)), "meminfo"_sv));
|
||||||
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0400)), "cmdline"_sv));
|
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0400)), "cmdline"_sv));
|
||||||
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_environ, fs, 0400)), "environ"_sv));
|
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_environ, fs, 0400)), "environ"_sv));
|
||||||
|
|
|
@ -200,11 +200,11 @@ namespace Kernel
|
||||||
[&path_parts](BAN::StringView path) -> BAN::ErrorOr<void>
|
[&path_parts](BAN::StringView path) -> BAN::ErrorOr<void>
|
||||||
{
|
{
|
||||||
auto split_path = TRY(path.split('/'));
|
auto split_path = TRY(path.split('/'));
|
||||||
split_path.reverse();
|
TRY(path_parts.reserve(path_parts.size() + split_path.size()));
|
||||||
for (auto part : split_path)
|
for (size_t i = split_path.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
TRY(path_parts.emplace_back());
|
TRY(path_parts.emplace_back());
|
||||||
TRY(path_parts.back().append(part));
|
TRY(path_parts.back().append(split_path[i - 1]));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -208,7 +208,7 @@ namespace Kernel
|
||||||
auto parent_file = bind_path.front() == '/'
|
auto parent_file = bind_path.front() == '/'
|
||||||
? VirtualFileSystem::get().root_file()
|
? VirtualFileSystem::get().root_file()
|
||||||
: TRY(Process::current().working_directory().clone());
|
: TRY(Process::current().working_directory().clone());
|
||||||
if (auto ret = Process::current().create_file_or_dir(parent_file, bind_path, 0755 | S_IFSOCK); ret.is_error())
|
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error())
|
||||||
{
|
{
|
||||||
if (ret.error().get_error_code() == EEXIST)
|
if (ret.error().get_error_code() == EEXIST)
|
||||||
return BAN::Error::from_errno(EADDRINUSE);
|
return BAN::Error::from_errno(EADDRINUSE);
|
||||||
|
|
|
@ -119,8 +119,9 @@ namespace Kernel
|
||||||
TRY(process->m_cmdline.push_back({}));
|
TRY(process->m_cmdline.push_back({}));
|
||||||
TRY(process->m_cmdline.back().append(path));
|
TRY(process->m_cmdline.back().append(path));
|
||||||
|
|
||||||
auto absolute_path = TRY(process->absolute_path_of(path));
|
LockGuard _(process->m_process_lock);
|
||||||
auto executable_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(process->m_credentials, absolute_path, O_EXEC)).inode;
|
|
||||||
|
auto executable_inode = TRY(process->find_file(AT_FDCWD, path.data(), O_EXEC)).inode;
|
||||||
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
|
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
|
||||||
process->m_mapped_regions = BAN::move(executable.regions);
|
process->m_mapped_regions = BAN::move(executable.regions);
|
||||||
|
|
||||||
|
@ -378,12 +379,61 @@ namespace Kernel
|
||||||
return read_from_vec_of_str(m_environ, offset, buffer);
|
return read_from_vec_of_str(m_environ, offset, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> Process::find_parent(int fd, const char* path)
|
BAN::ErrorOr<VirtualFileSystem::File> Process::find_file(int fd, const char* path, int flags) const
|
||||||
{
|
{
|
||||||
ASSERT(m_process_lock.is_locked());
|
ASSERT(m_process_lock.is_locked());
|
||||||
|
|
||||||
if (path)
|
auto parent_file = TRY(find_relative_parent(fd, path));
|
||||||
TRY(validate_string_access(path));
|
auto file = path
|
||||||
|
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
|
||||||
|
: BAN::move(parent_file);
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<Process::FileParent> Process::find_parent_file(int fd, const char* path, int flags) const
|
||||||
|
{
|
||||||
|
ASSERT(m_process_lock.is_locked());
|
||||||
|
|
||||||
|
auto relative_parent = TRY(find_relative_parent(fd, path));
|
||||||
|
|
||||||
|
VirtualFileSystem::File parent;
|
||||||
|
BAN::StringView file_name;
|
||||||
|
|
||||||
|
auto path_sv = path ? BAN::StringView(path) : ""_sv;
|
||||||
|
while (!path_sv.empty() && path_sv.back() == '/')
|
||||||
|
path_sv = path_sv.substring(0, path_sv.size() - 1);
|
||||||
|
|
||||||
|
if (auto index = path_sv.rfind('/'); index.has_value())
|
||||||
|
{
|
||||||
|
parent = TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
|
||||||
|
file_name = path_sv.substring(index.value() + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent = BAN::move(relative_parent);
|
||||||
|
file_name = path_sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parent.inode->can_access(m_credentials, flags))
|
||||||
|
return BAN::Error::from_errno(EACCES);
|
||||||
|
if (!parent.inode->mode().ifdir())
|
||||||
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
|
while (!file_name.empty() && file_name.front() == '/')
|
||||||
|
file_name = file_name.substring(1);
|
||||||
|
while (!file_name.empty() && file_name.back() == '/')
|
||||||
|
file_name = file_name.substring(0, file_name.size() - 1);
|
||||||
|
|
||||||
|
return FileParent {
|
||||||
|
.parent = BAN::move(parent),
|
||||||
|
.file_name = file_name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<VirtualFileSystem::File> Process::find_relative_parent(int fd, const char* path) const
|
||||||
|
{
|
||||||
|
ASSERT(m_process_lock.is_locked());
|
||||||
|
|
||||||
if (path && path[0] == '/')
|
if (path && path[0] == '/')
|
||||||
return VirtualFileSystem::get().root_file();
|
return VirtualFileSystem::get().root_file();
|
||||||
|
@ -398,21 +448,6 @@ namespace Kernel
|
||||||
return TRY(m_open_file_descriptors.file_of(fd));
|
return TRY(m_open_file_descriptors.file_of(fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> Process::find_file(int fd, const char* path, int flags)
|
|
||||||
{
|
|
||||||
ASSERT(m_process_lock.is_locked());
|
|
||||||
|
|
||||||
if (path)
|
|
||||||
TRY(validate_string_access(path));
|
|
||||||
|
|
||||||
auto parent_file = TRY(find_parent(fd, path));
|
|
||||||
auto file = path
|
|
||||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
|
|
||||||
: BAN::move(parent_file);
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_exit(int status)
|
BAN::ErrorOr<long> Process::sys_exit(int status)
|
||||||
{
|
{
|
||||||
ASSERT(this == &Process::current());
|
ASSERT(this == &Process::current());
|
||||||
|
@ -521,8 +556,7 @@ namespace Kernel
|
||||||
|
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
auto executable_file = TRY(find_file(AT_FDCWD, path, O_EXEC));
|
||||||
auto executable_file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_EXEC));
|
|
||||||
auto executable_inode = executable_file.inode;
|
auto executable_inode = executable_file.inode;
|
||||||
|
|
||||||
BAN::Vector<BAN::String> str_argv;
|
BAN::Vector<BAN::String> str_argv;
|
||||||
|
@ -875,7 +909,7 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::create_file_or_dir(const VirtualFileSystem::File& parent, BAN::StringView path, mode_t mode) const
|
BAN::ErrorOr<void> Process::create_file_or_dir(int fd, const char* path, mode_t mode) const
|
||||||
{
|
{
|
||||||
switch (mode & Inode::Mode::TYPE_MASK)
|
switch (mode & Inode::Mode::TYPE_MASK)
|
||||||
{
|
{
|
||||||
|
@ -889,26 +923,12 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Inode> parent_inode;
|
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_EXEC | O_WRONLY));
|
||||||
BAN::StringView file_name;
|
|
||||||
|
|
||||||
if (auto index = path.rfind('/'); index.has_value())
|
|
||||||
{
|
|
||||||
parent_inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, path.substring(0, index.value()), O_EXEC | O_WRONLY)).inode;
|
|
||||||
file_name = path.substring(index.value() + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parent_inode = parent.inode;
|
|
||||||
file_name = path;
|
|
||||||
if (!parent_inode->can_access(m_credentials, O_WRONLY))
|
|
||||||
return BAN::Error::from_errno(EACCES);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Inode::Mode(mode).ifdir())
|
if (Inode::Mode(mode).ifdir())
|
||||||
TRY(parent_inode->create_directory(file_name, mode, m_credentials.euid(), parent_inode->gid()));
|
TRY(parent.inode->create_directory(file_name, mode, m_credentials.euid(), parent.inode->gid()));
|
||||||
else
|
else
|
||||||
TRY(parent_inode->create_file(file_name, mode, m_credentials.euid(), parent_inode->gid()));
|
TRY(parent.inode->create_file(file_name, mode, m_credentials.euid(), parent.inode->gid()));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -952,8 +972,8 @@ namespace Kernel
|
||||||
|
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
|
|
||||||
auto parent_file = TRY(find_parent(fd, path));
|
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_RDONLY));
|
||||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags | O_NOFOLLOW);
|
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags);
|
||||||
|
|
||||||
VirtualFileSystem::File file;
|
VirtualFileSystem::File file;
|
||||||
if (file_or_error.is_error())
|
if (file_or_error.is_error())
|
||||||
|
@ -962,8 +982,8 @@ namespace Kernel
|
||||||
return file_or_error.release_error();
|
return file_or_error.release_error();
|
||||||
|
|
||||||
// FIXME: There is a race condition between next two lines
|
// FIXME: There is a race condition between next two lines
|
||||||
TRY(create_file_or_dir(parent_file, path, (mode & 0777) | Inode::Mode::IFREG));
|
TRY(parent.inode->create_file(file_name, (mode & 0777) | Inode::Mode::IFREG, m_credentials.euid(), m_credentials.egid()));
|
||||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags & ~O_RDWR));
|
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags & ~O_RDWR));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -975,8 +995,6 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(EISDIR);
|
return BAN::Error::from_errno(EISDIR);
|
||||||
if (!file.inode->mode().ifdir() && (flags & O_DIRECTORY))
|
if (!file.inode->mode().ifdir() && (flags & O_DIRECTORY))
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
if (file.inode->mode().iflnk() && !(flags & O_NOFOLLOW))
|
|
||||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto inode = file.inode;
|
auto inode = file.inode;
|
||||||
|
@ -1032,9 +1050,9 @@ namespace Kernel
|
||||||
credentials.set_euid(credentials.ruid());
|
credentials.set_euid(credentials.ruid());
|
||||||
credentials.set_egid(credentials.rgid());
|
credentials.set_egid(credentials.rgid());
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
auto relative_parent = TRY(find_relative_parent(AT_FDCWD, path));
|
||||||
|
TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, credentials, path, flags));
|
||||||
|
|
||||||
TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, absolute_path, flags));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,15 +1060,10 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
BAN::StringView path_sv(path);
|
|
||||||
if (!path_sv.empty() && path_sv.back() == '/')
|
auto [parent, file_name] = TRY(find_parent_file(AT_FDCWD, path, O_WRONLY));
|
||||||
path_sv = path_sv.substring(0, path_sv.size() - 1);
|
TRY(parent.inode->create_directory(file_name, (mode & 0777) | Inode::Mode::IFDIR, m_credentials.euid(), m_credentials.egid()));
|
||||||
if (path_sv.empty())
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
if (path[0] == '/')
|
|
||||||
TRY(create_file_or_dir(VirtualFileSystem::get().root_file(), path_sv, Inode::Mode::IFDIR | mode));
|
|
||||||
else
|
|
||||||
TRY(create_file_or_dir(m_working_directory, path_sv, Inode::Mode::IFDIR | mode));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,27 +1077,12 @@ namespace Kernel
|
||||||
if (inode->mode().ifdir())
|
if (inode->mode().ifdir())
|
||||||
return BAN::Error::from_errno(EISDIR);
|
return BAN::Error::from_errno(EISDIR);
|
||||||
|
|
||||||
auto parent = TRY(find_parent(fd2, path2));
|
auto [parent, file_name] = TRY(find_parent_file(fd2, path2, O_WRONLY));
|
||||||
|
if (!parent.inode->mode().ifdir())
|
||||||
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
BAN::RefPtr<Inode> parent_inode;
|
TRY(parent.inode->link_inode(file_name, inode));
|
||||||
BAN::StringView file_name;
|
|
||||||
|
|
||||||
BAN::StringView path2_sv = path2;
|
|
||||||
if (auto index = path2_sv.rfind('/'); index.has_value())
|
|
||||||
{
|
|
||||||
parent_inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, path2_sv.substring(0, index.value()), O_EXEC | O_WRONLY)).inode;
|
|
||||||
file_name = path2_sv.substring(index.value() + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parent_inode = parent.inode;
|
|
||||||
file_name = path2_sv;
|
|
||||||
if (!parent_inode->can_access(m_credentials, O_WRONLY))
|
|
||||||
return BAN::Error::from_errno(EACCES);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(parent_inode->mode().ifdir());
|
|
||||||
TRY(parent_inode->link_inode(file_name, inode));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,17 +1091,8 @@ namespace Kernel
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
auto [parent, file_name] = TRY(find_parent_file(AT_FDCWD, path, O_WRONLY));
|
||||||
|
TRY(parent.inode->unlink(file_name));
|
||||||
size_t index = absolute_path.size();
|
|
||||||
for (; index > 0; index--)
|
|
||||||
if (absolute_path[index - 1] == '/')
|
|
||||||
break;
|
|
||||||
auto directory = absolute_path.sv().substring(0, index);
|
|
||||||
auto file_name = absolute_path.sv().substring(index);
|
|
||||||
|
|
||||||
auto parent = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_EXEC | O_WRONLY)).inode;
|
|
||||||
TRY(parent->unlink(file_name));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1130,14 +1119,12 @@ namespace Kernel
|
||||||
TRY(validate_string_access(path1));
|
TRY(validate_string_access(path1));
|
||||||
TRY(validate_string_access(path2));
|
TRY(validate_string_access(path2));
|
||||||
|
|
||||||
auto parent_file = TRY(find_parent(fd, path2));
|
if (!find_file(fd, path2, O_NOFOLLOW).is_error())
|
||||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path2, O_NOFOLLOW);
|
|
||||||
if (!file_or_error.is_error())
|
|
||||||
return BAN::Error::from_errno(EEXIST);
|
return BAN::Error::from_errno(EEXIST);
|
||||||
|
|
||||||
TRY(create_file_or_dir(parent_file, path2, 0777 | Inode::Mode::IFLNK));
|
TRY(create_file_or_dir(fd, path2, 0777 | Inode::Mode::IFLNK));
|
||||||
|
|
||||||
auto symlink = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path2, O_NOFOLLOW));
|
auto symlink = TRY(find_file(fd, path2, O_NOFOLLOW));
|
||||||
TRY(symlink.inode->set_link_target(path1));
|
TRY(symlink.inode->set_link_target(path1));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1522,18 +1509,6 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::mount(BAN::StringView source, BAN::StringView target)
|
|
||||||
{
|
|
||||||
BAN::String absolute_source, absolute_target;
|
|
||||||
{
|
|
||||||
LockGuard _(m_process_lock);
|
|
||||||
TRY(absolute_source.append(TRY(absolute_path_of(source))));
|
|
||||||
TRY(absolute_target.append(TRY(absolute_path_of(target))));
|
|
||||||
}
|
|
||||||
TRY(VirtualFileSystem::get().mount(m_credentials, absolute_source, absolute_target));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flag)
|
BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flag)
|
||||||
{
|
{
|
||||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||||
|
@ -1597,9 +1572,7 @@ namespace Kernel
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
TRY(validate_pointer_access(buffer, PATH_MAX, true));
|
TRY(validate_pointer_access(buffer, PATH_MAX, true));
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
auto file = TRY(find_file(AT_FDCWD, path, O_RDONLY));
|
||||||
|
|
||||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_RDONLY));
|
|
||||||
if (file.canonical_path.size() >= PATH_MAX)
|
if (file.canonical_path.size() >= PATH_MAX)
|
||||||
return BAN::Error::from_errno(ENAMETOOLONG);
|
return BAN::Error::from_errno(ENAMETOOLONG);
|
||||||
|
|
||||||
|
@ -1653,20 +1626,10 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setpwd(const char* path)
|
BAN::ErrorOr<long> Process::sys_setpwd(const char* path)
|
||||||
{
|
|
||||||
BAN::String absolute_path;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
TRY(validate_string_access(path));
|
|
||||||
absolute_path = TRY(absolute_path_of(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_SEARCH));
|
auto file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||||
if (!file.inode->mode().ifdir())
|
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
|
||||||
|
|
||||||
LockGuard _(m_process_lock);
|
|
||||||
m_working_directory = BAN::move(file);
|
m_working_directory = BAN::move(file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@ set(AOC2024_PROJECTS
|
||||||
day4
|
day4
|
||||||
day5
|
day5
|
||||||
day6
|
day6
|
||||||
|
day7
|
||||||
full
|
full
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
set(SOURCES
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(aoc2024_day7 ${SOURCES})
|
||||||
|
banan_link_library(aoc2024_day7 ban)
|
||||||
|
banan_link_library(aoc2024_day7 libc)
|
||||||
|
|
||||||
|
install(TARGETS aoc2024_day7 OPTIONAL)
|
|
@ -0,0 +1,106 @@
|
||||||
|
#include <BAN/StringView.h>
|
||||||
|
#include <BAN/String.h>
|
||||||
|
#include <BAN/Vector.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
using i8 = int8_t;
|
||||||
|
using i16 = int16_t;
|
||||||
|
using i32 = int32_t;
|
||||||
|
using i64 = int64_t;
|
||||||
|
|
||||||
|
using u8 = uint8_t;
|
||||||
|
using u16 = uint16_t;
|
||||||
|
using u32 = uint32_t;
|
||||||
|
using u64 = uint64_t;
|
||||||
|
|
||||||
|
bool check_if_valid(const BAN::Vector<u64>& vals, size_t idx, u64 curr, bool concat)
|
||||||
|
{
|
||||||
|
// NOTE: This does not apply in general case, but puzzle input
|
||||||
|
// does not contain zeros or negative numbers
|
||||||
|
if (curr > vals[0])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (idx >= vals.size())
|
||||||
|
return curr == vals[0];
|
||||||
|
|
||||||
|
if (check_if_valid(vals, idx + 1, curr + vals[idx], concat))
|
||||||
|
return true;
|
||||||
|
if (check_if_valid(vals, idx + 1, curr * vals[idx], concat))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!concat)
|
||||||
|
return false;
|
||||||
|
u64 mult = 1;
|
||||||
|
while (mult <= vals[idx])
|
||||||
|
mult *= 10;
|
||||||
|
return check_if_valid(vals, idx + 1, curr * mult + vals[idx], concat);
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 part1(FILE* fp)
|
||||||
|
{
|
||||||
|
i64 result = 0;
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
while (fgets(buffer, sizeof(buffer), fp))
|
||||||
|
{
|
||||||
|
auto strs = MUST(BAN::StringView(buffer).split(' '));
|
||||||
|
if (strs.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
BAN::Vector<u64> vals;
|
||||||
|
for (auto str : strs)
|
||||||
|
MUST(vals.push_back(atoll(str.data())));
|
||||||
|
|
||||||
|
if (check_if_valid(vals, 2, vals[1], false))
|
||||||
|
result += vals[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 part2(FILE* fp)
|
||||||
|
{
|
||||||
|
i64 result = 0;
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
while (fgets(buffer, sizeof(buffer), fp))
|
||||||
|
{
|
||||||
|
auto strs = MUST(BAN::StringView(buffer).split(' '));
|
||||||
|
if (strs.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
BAN::Vector<u64> vals;
|
||||||
|
for (auto str : strs)
|
||||||
|
MUST(vals.push_back(atoll(str.data())));
|
||||||
|
|
||||||
|
if (check_if_valid(vals, 2, vals[1], true))
|
||||||
|
result += vals[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
const char* file_path = "/usr/share/aoc2024/day7_input.txt";
|
||||||
|
|
||||||
|
if (argc >= 2)
|
||||||
|
file_path = argv[1];
|
||||||
|
|
||||||
|
FILE* fp = fopen(file_path, "r");
|
||||||
|
if (fp == nullptr)
|
||||||
|
{
|
||||||
|
perror("fopen");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("part1: %" PRId64 "\n", part1(fp));
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
|
printf("part2: %" PRId64 "\n", part2(fp));
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
Loading…
Reference in New Issue