mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-27 23:09:08 +00:00
Kernel: Let symlinks resolve themselves
Symlink resolution is now a virtual method on an inode, Inode::resolve_as_symlink(). The default implementation just reads the stored inode contents, treats them as a path and calls through to VFS::resolve_path(). This will let us support other, magical files that appear to be plain old symlinks but resolve to something else. This is particularly useful for ProcFS.
This commit is contained in:
parent
e0013a6b4c
commit
ae64fd1b27
Notes:
sideshowbarker
2024-07-19 10:01:19 +09:00
Author: https://github.com/bugaevc
Commit: ae64fd1b27
Pull-request: https://github.com/SerenityOS/serenity/pull/1079
Reviewed-by: https://github.com/awesomekling
3 changed files with 22 additions and 10 deletions
|
@ -4,6 +4,8 @@
|
|||
#include <Kernel/FileSystem/InodeWatcher.h>
|
||||
#include <Kernel/Net/LocalSocket.h>
|
||||
#include <Kernel/VM/InodeVMObject.h>
|
||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||
#include <Kernel/FileSystem/Custody.h>
|
||||
|
||||
InlineLinkedList<Inode>& all_inodes()
|
||||
{
|
||||
|
@ -56,6 +58,23 @@ ByteBuffer Inode::read_entire(FileDescription* descriptor) const
|
|||
return builder.to_byte_buffer();
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<Custody>> Inode::resolve_as_link(Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level) const
|
||||
{
|
||||
// The default implementation simply treats the stored
|
||||
// contents as a path and resolves that. That is, it
|
||||
// behaves exactly how you would expect a symlink to work.
|
||||
auto contents = read_entire();
|
||||
|
||||
if (!contents) {
|
||||
if (out_parent)
|
||||
*out_parent = nullptr;
|
||||
return KResult(-ENOENT);
|
||||
}
|
||||
|
||||
auto path = StringView(contents.data(), contents.size());
|
||||
return VFS::the().resolve_path(path, base, out_parent, options, symlink_recursion_level);
|
||||
}
|
||||
|
||||
unsigned Inode::fsid() const
|
||||
{
|
||||
return m_fs.fsid();
|
||||
|
|
|
@ -15,6 +15,7 @@ class FileDescription;
|
|||
class InodeVMObject;
|
||||
class InodeWatcher;
|
||||
class LocalSocket;
|
||||
class Custody;
|
||||
|
||||
class Inode : public RefCounted<Inode>
|
||||
, public Weakable<Inode>
|
||||
|
@ -53,6 +54,7 @@ public:
|
|||
virtual KResult chmod(mode_t) = 0;
|
||||
virtual KResult chown(uid_t, gid_t) = 0;
|
||||
virtual KResult truncate(off_t) { return KSuccess; }
|
||||
virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0) const;
|
||||
|
||||
LocalSocket* socket() { return m_socket.ptr(); }
|
||||
const LocalSocket* socket() const { return m_socket.ptr(); }
|
||||
|
|
|
@ -741,16 +741,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
|||
if (options & O_NOFOLLOW_NOERROR)
|
||||
break;
|
||||
}
|
||||
auto symlink_contents = child_inode->read_entire();
|
||||
if (!symlink_contents) {
|
||||
if (out_parent)
|
||||
*out_parent = nullptr;
|
||||
return KResult(-ENOENT);
|
||||
}
|
||||
|
||||
auto symlink_path = StringView(symlink_contents.data(), symlink_contents.size());
|
||||
auto symlink_target = resolve_path(symlink_path, parent, out_parent, options, symlink_recursion_level + 1);
|
||||
|
||||
auto symlink_target = child_inode->resolve_as_link(parent, out_parent, options, symlink_recursion_level + 1);
|
||||
if (symlink_target.is_error() || !have_more_parts)
|
||||
return symlink_target;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue