diff --git a/Kernel/InlineLinkedList.h b/Kernel/InlineLinkedList.h index c51ef13cea..f5e6a3f405 100644 --- a/Kernel/InlineLinkedList.h +++ b/Kernel/InlineLinkedList.h @@ -45,7 +45,7 @@ public: InlineLinkedList() { } bool isEmpty() const { return !m_head; } - size_t size() const; + size_t sizeSlow() const; void clear(); T* head() const { return m_head; } @@ -72,7 +72,7 @@ private: T* m_tail { nullptr }; }; -template inline size_t InlineLinkedList::size() const +template inline size_t InlineLinkedList::sizeSlow() const { size_t size = 0; for (T* node = m_head; node; node = node->next()) diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 751d5e9c8d..c28c31aed2 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -1,5 +1,5 @@ #include "ProcFileSystem.h" -#include +#include "Task.h" RetainPtr ProcFileSystem::create() { @@ -18,7 +18,24 @@ bool ProcFileSystem::initialize() { SyntheticFileSystem::initialize(); addFile(createGeneratedFile("summary", [] { - return String("Process summary!").toByteBuffer(); + cli(); + auto tasks = Task::allTasks(); + char* buffer; + auto stringImpl = StringImpl::createUninitialized(tasks.size() * 64, buffer); + memset(buffer, 0, stringImpl->length()); + char* ptr = buffer; + ptr += ksprintf(ptr, "PID OWNER STATE NAME\n"); + for (auto* task : tasks) { + ptr += ksprintf(ptr, "%w %w:%w %b %s\n", + task->pid(), + task->uid(), + task->gid(), + task->state(), + task->name().characters()); + } + *ptr = '\0'; + sti(); + return ByteBuffer::copy((byte*)buffer, ptr - buffer); })); return true; } diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 065fe02869..c4c1f13ad7 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -95,6 +95,15 @@ void Task::allocateLDT() m_tss.ldt = newLDTSelector; } +Vector Task::allTasks() +{ + Vector tasks; + tasks.ensureCapacity(s_tasks->sizeSlow()); + for (auto* task = s_tasks->head(); task; task = task->next()) + tasks.append(task); + return tasks; +} + Task::Region* Task::allocateRegion(size_t size, String&& name) { // FIXME: This needs sanity checks. What if this overlaps existing regions? diff --git a/Kernel/Task.h b/Kernel/Task.h index 10c115e082..d06024fd4f 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -19,6 +19,8 @@ public: static Task* create(const String& path, uid_t, gid_t); Task(String&& name, uid_t, gid_t); + static Vector allTasks(); + #ifdef TASK_SANITY_CHECKS static void checkSanity(const char* msg = nullptr); #else @@ -58,6 +60,8 @@ public: TSS32& tss() { return m_tss; } State state() const { return m_state; } IPC::Handle handle() const { return m_handle; } + uid_t uid() const { return m_uid; } + uid_t gid() const { return m_gid; } const FarPtr& farPtr() const { return m_farPtr; } diff --git a/Kernel/init.cpp b/Kernel/init.cpp index c71010136f..7200c199fa 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -138,7 +138,7 @@ static void init_stage2() vfs->mount(procfs.copyRef(), "/proc"); { - auto motdFile = vfs->open("/motd.txt"); + auto motdFile = vfs->open("/proc/summary"); ASSERT(motdFile); auto motdData = motdFile->readEntireFile();