mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 19:05:07 +00:00
Kernel: Move ProcFS related overrides in Process to ProcessProcFSTraits
This allows us to 1) let go of the Process when an inode is ref'ing for ProcFSExposedComponent related reasons, and 2) change our ref/unref implementation.
This commit is contained in:
parent
748938ea59
commit
2830a0ecda
7 changed files with 143 additions and 61 deletions
|
@ -182,6 +182,7 @@ set(KERNEL_SOURCES
|
||||||
ProcessExposed.cpp
|
ProcessExposed.cpp
|
||||||
ProcessSpecificExposed.cpp
|
ProcessSpecificExposed.cpp
|
||||||
ProcessGroup.cpp
|
ProcessGroup.cpp
|
||||||
|
ProcessProcFSTraits.cpp
|
||||||
RTC.cpp
|
RTC.cpp
|
||||||
Random.cpp
|
Random.cpp
|
||||||
Scheduler.cpp
|
Scheduler.cpp
|
||||||
|
|
|
@ -274,13 +274,15 @@ InodeMetadata ProcFSProcessDirectoryInode::metadata() const
|
||||||
auto process = Process::from_pid(associated_pid());
|
auto process = Process::from_pid(associated_pid());
|
||||||
if (!process)
|
if (!process)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
auto traits = process->procfs_traits();
|
||||||
InodeMetadata metadata;
|
InodeMetadata metadata;
|
||||||
metadata.inode = { fsid(), process->component_index() };
|
metadata.inode = { fsid(), traits->component_index() };
|
||||||
metadata.mode = S_IFDIR | process->required_mode();
|
metadata.mode = S_IFDIR | traits->required_mode();
|
||||||
metadata.uid = process->owner_user();
|
metadata.uid = traits->owner_user();
|
||||||
metadata.gid = process->owner_group();
|
metadata.gid = traits->owner_group();
|
||||||
metadata.size = 0;
|
metadata.size = 0;
|
||||||
metadata.mtime = process->modified_time();
|
metadata.mtime = traits->modified_time();
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +297,7 @@ KResult ProcFSProcessDirectoryInode::traverse_as_directory(Function<bool(FileSys
|
||||||
auto process = Process::from_pid(associated_pid());
|
auto process = Process::from_pid(associated_pid());
|
||||||
if (!process)
|
if (!process)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
return process->traverse_as_directory(procfs().fsid(), move(callback));
|
return process->procfs_traits()->traverse_as_directory(procfs().fsid(), move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<Inode>> ProcFSProcessDirectoryInode::lookup(StringView name)
|
KResultOr<NonnullRefPtr<Inode>> ProcFSProcessDirectoryInode::lookup(StringView name)
|
||||||
|
@ -400,13 +402,15 @@ InodeMetadata ProcFSProcessSubDirectoryInode::metadata() const
|
||||||
auto process = Process::from_pid(associated_pid());
|
auto process = Process::from_pid(associated_pid());
|
||||||
if (!process)
|
if (!process)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
auto traits = process->procfs_traits();
|
||||||
InodeMetadata metadata;
|
InodeMetadata metadata;
|
||||||
metadata.inode = { fsid(), process->component_index() };
|
metadata.inode = { fsid(), traits->component_index() };
|
||||||
metadata.mode = S_IFDIR | process->required_mode();
|
metadata.mode = S_IFDIR | traits->required_mode();
|
||||||
metadata.uid = process->owner_user();
|
metadata.uid = traits->owner_user();
|
||||||
metadata.gid = process->owner_group();
|
metadata.gid = traits->owner_group();
|
||||||
metadata.size = 0;
|
metadata.size = 0;
|
||||||
metadata.mtime = process->modified_time();
|
metadata.mtime = traits->modified_time();
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,13 +526,15 @@ InodeMetadata ProcFSProcessPropertyInode::metadata() const
|
||||||
auto process = Process::from_pid(associated_pid());
|
auto process = Process::from_pid(associated_pid());
|
||||||
if (!process)
|
if (!process)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
auto traits = process->procfs_traits();
|
||||||
InodeMetadata metadata;
|
InodeMetadata metadata;
|
||||||
metadata.inode = { fsid(), process->component_index() };
|
metadata.inode = { fsid(), traits->component_index() };
|
||||||
metadata.mode = determine_procfs_process_inode_mode(m_parent_sub_directory_type, m_possible_data.property_type);
|
metadata.mode = determine_procfs_process_inode_mode(m_parent_sub_directory_type, m_possible_data.property_type);
|
||||||
metadata.uid = process->owner_user();
|
metadata.uid = traits->owner_user();
|
||||||
metadata.gid = process->owner_group();
|
metadata.gid = traits->owner_group();
|
||||||
metadata.size = 0;
|
metadata.size = 0;
|
||||||
metadata.mtime = process->modified_time();
|
metadata.mtime = traits->modified_time();
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
KResult ProcFSProcessPropertyInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const
|
KResult ProcFSProcessPropertyInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const
|
||||||
|
|
|
@ -944,8 +944,9 @@ KResultOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSRootDirectory::lookup(Str
|
||||||
auto actual_pid = pid.value();
|
auto actual_pid = pid.value();
|
||||||
|
|
||||||
auto maybe_process = Process::from_pid(actual_pid);
|
auto maybe_process = Process::from_pid(actual_pid);
|
||||||
if (maybe_process)
|
if (maybe_process) {
|
||||||
return maybe_process.release_nonnull();
|
return maybe_process->procfs_traits();
|
||||||
|
}
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,11 @@ Process::Process(const String& name, uid_t uid, gid_t gid, ProcessID ppid, bool
|
||||||
m_protected_values.suid = uid;
|
m_protected_values.suid = uid;
|
||||||
m_protected_values.sgid = gid;
|
m_protected_values.sgid = gid;
|
||||||
|
|
||||||
|
auto maybe_procfs_traits = ProcessProcFSTraits::try_create({}, make_weak_ptr());
|
||||||
|
// NOTE: This can fail, but it should be very, *very* rare.
|
||||||
|
VERIFY(!maybe_procfs_traits.is_error());
|
||||||
|
m_procfs_traits = maybe_procfs_traits.release_value();
|
||||||
|
|
||||||
dbgln_if(PROCESS_DEBUG, "Created new process {}({})", m_name, this->pid().value());
|
dbgln_if(PROCESS_DEBUG, "Created new process {}({})", m_name, this->pid().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,9 @@ typedef HashMap<FlatPtr, RefPtr<FutexQueue>> FutexQueues;
|
||||||
struct LoadResult;
|
struct LoadResult;
|
||||||
|
|
||||||
class Process
|
class Process
|
||||||
: public ProcFSExposedComponent
|
: public RefCounted<Process>
|
||||||
, public Weakable<Process> {
|
, public Weakable<Process> {
|
||||||
|
|
||||||
private:
|
|
||||||
class ProtectedValues {
|
class ProtectedValues {
|
||||||
public:
|
public:
|
||||||
ProcessID pid { 0 };
|
ProcessID pid { 0 };
|
||||||
|
@ -145,6 +144,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
class ProcessProcFSTraits;
|
||||||
|
|
||||||
inline static Process* current()
|
inline static Process* current()
|
||||||
{
|
{
|
||||||
auto current_thread = Processor::current_thread();
|
auto current_thread = Processor::current_thread();
|
||||||
|
@ -549,13 +550,7 @@ private:
|
||||||
void setup_socket_fd(int fd, NonnullRefPtr<FileDescription> description, int type);
|
void setup_socket_fd(int fd, NonnullRefPtr<FileDescription> description, int type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ^ProcFSExposedComponent stats
|
NonnullRefPtr<ProcessProcFSTraits> procfs_traits() const { return *m_procfs_traits; }
|
||||||
virtual InodeIndex component_index() const override;
|
|
||||||
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override;
|
|
||||||
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
|
|
||||||
virtual mode_t required_mode() const override { return 0555; }
|
|
||||||
virtual uid_t owner_user() const override { return uid(); }
|
|
||||||
virtual gid_t owner_group() const override { return gid(); }
|
|
||||||
KResult procfs_get_fds_stats(KBufferBuilder& builder) const;
|
KResult procfs_get_fds_stats(KBufferBuilder& builder) const;
|
||||||
KResult procfs_get_perf_events(KBufferBuilder& builder) const;
|
KResult procfs_get_perf_events(KBufferBuilder& builder) const;
|
||||||
KResult procfs_get_unveil_stats(KBufferBuilder& builder) const;
|
KResult procfs_get_unveil_stats(KBufferBuilder& builder) const;
|
||||||
|
@ -713,6 +708,37 @@ public:
|
||||||
FileDescriptionAndFlags* m_description { nullptr };
|
FileDescriptionAndFlags* m_description { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ProcessProcFSTraits : public ProcFSExposedComponent {
|
||||||
|
public:
|
||||||
|
static KResultOr<NonnullRefPtr<ProcessProcFSTraits>> try_create(Badge<Process>, WeakPtr<Process> process)
|
||||||
|
{
|
||||||
|
auto result = adopt_ref_if_nonnull(new (nothrow) ProcessProcFSTraits(process));
|
||||||
|
if (!result)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
return result.release_nonnull();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual InodeIndex component_index() const override;
|
||||||
|
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override;
|
||||||
|
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
|
||||||
|
virtual mode_t required_mode() const override { return 0555; }
|
||||||
|
|
||||||
|
virtual uid_t owner_user() const override;
|
||||||
|
|
||||||
|
virtual gid_t owner_group() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProcessProcFSTraits(WeakPtr<Process> process)
|
||||||
|
: m_process(process)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: We need to weakly hold on to the process, because otherwise
|
||||||
|
// we would be creating a reference cycle.
|
||||||
|
WeakPtr<Process> m_process;
|
||||||
|
};
|
||||||
|
|
||||||
FileDescriptions& fds() { return m_fds; }
|
FileDescriptions& fds() { return m_fds; }
|
||||||
const FileDescriptions& fds() const { return m_fds; }
|
const FileDescriptions& fds() const { return m_fds; }
|
||||||
|
|
||||||
|
@ -770,9 +796,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
Array<CoredumpProperty, 4> m_coredump_properties;
|
Array<CoredumpProperty, 4> m_coredump_properties;
|
||||||
|
|
||||||
NonnullRefPtrVector<Thread> m_threads_for_coredump;
|
NonnullRefPtrVector<Thread> m_threads_for_coredump;
|
||||||
|
|
||||||
|
mutable RefPtr<ProcessProcFSTraits> m_procfs_traits;
|
||||||
|
|
||||||
static_assert(sizeof(ProtectedValues) < (PAGE_SIZE));
|
static_assert(sizeof(ProtectedValues) < (PAGE_SIZE));
|
||||||
alignas(4096) ProtectedValues m_protected_values;
|
alignas(4096) ProtectedValues m_protected_values;
|
||||||
u8 m_protected_values_padding[PAGE_SIZE - sizeof(ProtectedValues)];
|
u8 m_protected_values_padding[PAGE_SIZE - sizeof(ProtectedValues)];
|
||||||
|
|
72
Kernel/ProcessProcFSTraits.cpp
Normal file
72
Kernel/ProcessProcFSTraits.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/FileSystem/ProcFS.h>
|
||||||
|
#include <Kernel/Process.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
uid_t Process::ProcessProcFSTraits::owner_user() const
|
||||||
|
{
|
||||||
|
auto process = m_process.strong_ref();
|
||||||
|
if (!process)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return process->uid();
|
||||||
|
}
|
||||||
|
|
||||||
|
gid_t Process::ProcessProcFSTraits::owner_group() const
|
||||||
|
{
|
||||||
|
auto process = m_process.strong_ref();
|
||||||
|
if (!process)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return process->gid();
|
||||||
|
}
|
||||||
|
|
||||||
|
InodeIndex Process::ProcessProcFSTraits::component_index() const
|
||||||
|
{
|
||||||
|
auto process = m_process.strong_ref();
|
||||||
|
if (!process)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return SegmentedProcFSIndex::build_segmented_index_for_pid_directory(process->pid());
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<NonnullRefPtr<Inode>> Process::ProcessProcFSTraits::to_inode(const ProcFS& procfs_instance) const
|
||||||
|
{
|
||||||
|
auto process = m_process.strong_ref();
|
||||||
|
if (!process)
|
||||||
|
return ESRCH;
|
||||||
|
|
||||||
|
auto maybe_inode = ProcFSProcessDirectoryInode::try_create(procfs_instance, process->pid());
|
||||||
|
if (maybe_inode.is_error())
|
||||||
|
return maybe_inode.error();
|
||||||
|
return maybe_inode.release_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult Process::ProcessProcFSTraits::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
||||||
|
{
|
||||||
|
auto process = m_process.strong_ref();
|
||||||
|
if (!process)
|
||||||
|
return ESRCH;
|
||||||
|
|
||||||
|
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_pid_directory(process->pid()) }, 0 });
|
||||||
|
callback({ "..", { fsid, ProcFSComponentRegistry::the().root_directory().component_index() }, 0 });
|
||||||
|
callback({ "fd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions) }, 0 });
|
||||||
|
callback({ "stacks", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks) }, 0 });
|
||||||
|
callback({ "unveil", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Unveil) }, 0 });
|
||||||
|
callback({ "pledge", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Pledge) }, 0 });
|
||||||
|
callback({ "fds", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::FileDescriptions) }, 0 });
|
||||||
|
callback({ "exe", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink) }, 0 });
|
||||||
|
callback({ "cwd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink) }, 0 });
|
||||||
|
callback({ "perf_events", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents) }, 0 });
|
||||||
|
callback({ "vm", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats) }, 0 });
|
||||||
|
callback({ "root", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::RootLink) }, 0 });
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -40,40 +40,10 @@ KResultOr<size_t> Process::procfs_get_thread_stack(ThreadID thread_id, KBufferBu
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeIndex Process::component_index() const
|
|
||||||
{
|
|
||||||
return SegmentedProcFSIndex::build_segmented_index_for_pid_directory(pid());
|
|
||||||
}
|
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<Inode>> Process::to_inode(const ProcFS& procfs_instance) const
|
|
||||||
{
|
|
||||||
auto maybe_inode = ProcFSProcessDirectoryInode::try_create(procfs_instance, m_protected_values.pid);
|
|
||||||
if (maybe_inode.is_error())
|
|
||||||
return maybe_inode.error();
|
|
||||||
return maybe_inode.release_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
KResult Process::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
|
||||||
{
|
|
||||||
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_pid_directory(pid()) }, 0 });
|
|
||||||
callback({ "..", { fsid, ProcFSComponentRegistry::the().root_directory().component_index() }, 0 });
|
|
||||||
callback({ "fd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(pid(), SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions) }, 0 });
|
|
||||||
callback({ "stacks", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks) }, 0 });
|
|
||||||
callback({ "unveil", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::Unveil) }, 0 });
|
|
||||||
callback({ "pledge", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::Pledge) }, 0 });
|
|
||||||
callback({ "fds", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::FileDescriptions) }, 0 });
|
|
||||||
callback({ "exe", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink) }, 0 });
|
|
||||||
callback({ "cwd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink) }, 0 });
|
|
||||||
callback({ "perf_events", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents) }, 0 });
|
|
||||||
callback({ "vm", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats) }, 0 });
|
|
||||||
callback({ "root", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(pid(), SegmentedProcFSIndex::MainProcessProperty::RootLink) }, 0 });
|
|
||||||
return KSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
KResult Process::traverse_stacks_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
KResult Process::traverse_stacks_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
||||||
{
|
{
|
||||||
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property(pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, SegmentedProcFSIndex::MainProcessProperty::Reserved) }, 0 });
|
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property(pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, SegmentedProcFSIndex::MainProcessProperty::Reserved) }, 0 });
|
||||||
callback({ "..", { fsid, component_index() }, 0 });
|
callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 });
|
||||||
|
|
||||||
for_each_thread([&](const Thread& thread) {
|
for_each_thread([&](const Thread& thread) {
|
||||||
int tid = thread.tid().value();
|
int tid = thread.tid().value();
|
||||||
|
@ -119,8 +89,8 @@ KResultOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBuffer
|
||||||
|
|
||||||
KResult Process::traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
KResult Process::traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
||||||
{
|
{
|
||||||
callback({ ".", { fsid, component_index() }, 0 });
|
callback({ ".", { fsid, m_procfs_traits->component_index() }, 0 });
|
||||||
callback({ "..", { fsid, component_index() }, 0 });
|
callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 });
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
fds().enumerate([&](auto& file_description_metadata) {
|
fds().enumerate([&](auto& file_description_metadata) {
|
||||||
if (!file_description_metadata.is_valid()) {
|
if (!file_description_metadata.is_valid()) {
|
||||||
|
@ -309,7 +279,7 @@ mode_t Process::binary_link_required_mode() const
|
||||||
{
|
{
|
||||||
if (!executable())
|
if (!executable())
|
||||||
return 0;
|
return 0;
|
||||||
return ProcFSExposedComponent::required_mode();
|
return m_procfs_traits->required_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult Process::procfs_get_binary_link(KBufferBuilder& builder) const
|
KResult Process::procfs_get_binary_link(KBufferBuilder& builder) const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue