forked from Bananymous/banan-os
Kernel: Symlinks are now working
We still have to implement loop or depth detection
This commit is contained in:
parent
feea2d4024
commit
4d4d0e26a9
|
@ -25,7 +25,7 @@ namespace Kernel
|
|||
BAN::RefPtr<Inode> inode;
|
||||
BAN::String canonical_path;
|
||||
};
|
||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView, bool follow_links);
|
||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView, bool follow_link);
|
||||
|
||||
private:
|
||||
VirtualFileSystem() = default;
|
||||
|
@ -39,7 +39,7 @@ namespace Kernel
|
|||
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
||||
|
||||
private:
|
||||
RecursiveSpinLock m_lock;
|
||||
SpinLock m_lock;
|
||||
FileSystem* m_root_fs = nullptr;
|
||||
BAN::Vector<MountPoint> m_mount_points;
|
||||
};
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace Kernel
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path, bool follow_links)
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path, bool follow_link)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
|
@ -93,13 +93,22 @@ namespace Kernel
|
|||
|
||||
BAN::String canonical_path;
|
||||
|
||||
const auto path_parts = TRY(path.split('/'));
|
||||
BAN::Vector<BAN::String> path_parts;
|
||||
|
||||
for (auto path_part : path_parts)
|
||||
{
|
||||
auto temp = TRY(path.split('/'));
|
||||
for (size_t i = 0; i < temp.size(); i++)
|
||||
TRY(path_parts.push_back(temp[temp.size() - i - 1]));
|
||||
}
|
||||
|
||||
while (!path_parts.empty())
|
||||
{
|
||||
const auto& path_part = path_parts.back();
|
||||
auto orig = inode;
|
||||
|
||||
if (path_part.empty() || path_part == "."sv)
|
||||
{
|
||||
continue;
|
||||
|
||||
}
|
||||
else if (path_part == ".."sv)
|
||||
{
|
||||
|
@ -119,32 +128,42 @@ namespace Kernel
|
|||
else
|
||||
{
|
||||
inode = TRY(inode->read_directory_inode(path_part));
|
||||
TRY(canonical_path.push_back('/'));
|
||||
TRY(canonical_path.append(path_part));
|
||||
|
||||
if (auto* mount_point = mount_from_host_inode(inode))
|
||||
inode = mount_point->target->root_inode();
|
||||
|
||||
if (follow_links && inode->mode().iflnk())
|
||||
TRY(canonical_path.push_back('/'));
|
||||
TRY(canonical_path.append(path_part));
|
||||
}
|
||||
|
||||
path_parts.pop_back();
|
||||
|
||||
if (inode->mode().iflnk() && (follow_link || !path_parts.empty()))
|
||||
{
|
||||
auto target = TRY(inode->link_target());
|
||||
if (target.empty())
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
|
||||
if (target.front() == '/')
|
||||
{
|
||||
auto target = TRY(inode->link_target());
|
||||
if (target.empty())
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
if (target.front() == '/')
|
||||
{
|
||||
File file = TRY(file_from_absolute_path(target, follow_links));
|
||||
inode = file.inode;
|
||||
canonical_path = BAN::move(file.canonical_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (canonical_path.back() != '/')
|
||||
canonical_path.pop_back();
|
||||
TRY(canonical_path.append(target));
|
||||
File file = TRY(file_from_absolute_path(canonical_path, follow_links));
|
||||
inode = file.inode;
|
||||
canonical_path = BAN::move(file.canonical_path);
|
||||
}
|
||||
inode = root_inode();
|
||||
canonical_path.clear();
|
||||
|
||||
auto temp = TRY(target.sv().split('/'));
|
||||
for (size_t i = 0; i < temp.size(); i++)
|
||||
TRY(path_parts.emplace_back(temp[temp.size() - i - 1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
inode = orig;
|
||||
|
||||
while (canonical_path.back() != '/')
|
||||
canonical_path.pop_back();
|
||||
canonical_path.pop_back();
|
||||
|
||||
auto new_parts = TRY(target.sv().split('/'));
|
||||
for (size_t i = 0; i < new_parts.size(); i++)
|
||||
TRY(path_parts.emplace_back(new_parts[new_parts.size() - i - 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<int> Process::open(BAN::StringView path, int flags)
|
||||
{
|
||||
if (flags & ~O_RDWR)
|
||||
if (flags & ~(O_RDONLY | O_WRONLY | O_NOFOLLOW))
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
|
||||
BAN::String absolute_path = TRY(absolute_path_of(path));
|
||||
|
@ -468,7 +468,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out)
|
||||
{
|
||||
int fd = TRY(open(path, O_RDONLY));
|
||||
int fd = TRY(open(path, O_RDONLY | O_NOFOLLOW));
|
||||
auto ret = fstat(fd, out);
|
||||
MUST(close(fd));
|
||||
return ret;
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace Kernel
|
|||
mode.ifdir() ? 'd' :
|
||||
mode.ifblk() ? 'b' :
|
||||
mode.ifchr() ? 'c' :
|
||||
mode.iflnk() ? 'l' :
|
||||
'-';
|
||||
|
||||
buffer[1] = (mode.mode & Inode::Mode::IRUSR) ? 'r' : '-';
|
||||
|
|
Loading…
Reference in New Issue