summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-07-29 07:26:01 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-29 07:26:01 +0200
commit5ded77df39e816f565b26761624893d085ca6eef (patch)
treeb840f17e0038d3e8e09f5e530a6b3af3c1d802ac /Kernel
parent7356fd389f4e73f98f3c28b91830189fea109b5b (diff)
downloadserenity-5ded77df39e816f565b26761624893d085ca6eef.zip
Kernel+ProcessManager: Let processes have an icon and show it in the table.
Processes can now have an icon assigned, which is essentially a 16x16 RGBA32 bitmap exposed as a shared buffer ID. You set the icon ID by calling set_process_icon(int) and the icon ID will be exposed through /proc/all. To make this work, I added a mechanism for making shared buffers globally accessible. For safety reasons, each app seals the icon buffer before making it global. Right now the first call to GWindow::set_icon() is what determines the process icon. We'll probably change this in the future. :^)
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/ProcFS.cpp1
-rw-r--r--Kernel/Process.cpp26
-rw-r--r--Kernel/Process.h7
-rw-r--r--Kernel/SharedBuffer.cpp17
-rw-r--r--Kernel/SharedBuffer.h3
-rw-r--r--Kernel/Syscall.cpp4
-rw-r--r--Kernel/Syscall.h4
7 files changed, 60 insertions, 2 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp
index b1ea7d9491..5041fd10c9 100644
--- a/Kernel/FileSystem/ProcFS.cpp
+++ b/Kernel/FileSystem/ProcFS.cpp
@@ -548,6 +548,7 @@ ByteBuffer procfs$all(InodeIdentifier)
process_object.set("ticks", process.main_thread().ticks());
process_object.set("priority", to_string(process.priority()));
process_object.set("syscall_count", process.syscall_count());
+ process_object.set("icon_id", process.icon_id());
array.append(process_object);
};
build_process(*Scheduler::colonel());
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index ef8803a85e..a4d1b41644 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -2452,6 +2452,19 @@ int Process::sys$share_buffer_with(int shared_buffer_id, pid_t peer_pid)
return 0;
}
+int Process::sys$share_buffer_globally(int shared_buffer_id)
+{
+ LOCKER(shared_buffers().lock());
+ auto it = shared_buffers().resource().find(shared_buffer_id);
+ if (it == shared_buffers().resource().end())
+ return -EINVAL;
+ auto& shared_buffer = *(*it).value;
+ if (!shared_buffer.is_shared_with(m_pid))
+ return -EPERM;
+ shared_buffer.share_globally();
+ return 0;
+}
+
int Process::sys$release_shared_buffer(int shared_buffer_id)
{
LOCKER(shared_buffers().lock());
@@ -2773,3 +2786,16 @@ String Process::backtrace(ProcessInspectionHandle& handle) const
});
return builder.to_string();
}
+
+int Process::sys$set_process_icon(int icon_id)
+{
+ LOCKER(shared_buffers().lock());
+ auto it = shared_buffers().resource().find(icon_id);
+ if (it == shared_buffers().resource().end())
+ return -EINVAL;
+ auto& shared_buffer = *(*it).value;
+ if (!shared_buffer.is_shared_with(m_pid))
+ return -EPERM;
+ m_icon_id = icon_id;
+ return 0;
+}
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 7f38cb5e71..e114bc0cbf 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -22,6 +22,7 @@ class PageDirectory;
class Region;
class VMObject;
class ProcessTracer;
+class SharedBuffer;
timeval kgettimeofday();
void kgettimeofday(timeval&);
@@ -208,12 +209,14 @@ public:
int sys$mknod(const char* pathname, mode_t, dev_t);
int sys$create_shared_buffer(int, void** buffer);
int sys$share_buffer_with(int, pid_t peer_pid);
+ int sys$share_buffer_globally(int);
void* sys$get_shared_buffer(int shared_buffer_id);
int sys$release_shared_buffer(int shared_buffer_id);
int sys$seal_shared_buffer(int shared_buffer_id);
int sys$get_shared_buffer_size(int shared_buffer_id);
int sys$halt();
int sys$reboot();
+ int sys$set_process_icon(int icon_id);
static void initialize();
@@ -281,6 +284,8 @@ public:
const ELFLoader* elf_loader() const { return m_elf_loader.ptr(); }
+ int icon_id() const { return m_icon_id; }
+
private:
friend class MemoryManager;
friend class Scheduler;
@@ -359,6 +364,8 @@ private:
Lock m_big_lock { "Process" };
u64 m_alarm_deadline { 0 };
+
+ int m_icon_id { -1 };
};
class ProcessInspectionHandle {
diff --git a/Kernel/SharedBuffer.cpp b/Kernel/SharedBuffer.cpp
index 29665e3bc9..5753a2a6b3 100644
--- a/Kernel/SharedBuffer.cpp
+++ b/Kernel/SharedBuffer.cpp
@@ -1,5 +1,5 @@
-#include <Kernel/SharedBuffer.h>
#include <Kernel/Process.h>
+#include <Kernel/SharedBuffer.h>
Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>& shared_buffers()
{
@@ -29,6 +29,8 @@ void SharedBuffer::sanity_check(const char* what)
bool SharedBuffer::is_shared_with(pid_t peer_pid)
{
LOCKER(shared_buffers().lock());
+ if (m_global)
+ return true;
for (auto& ref : m_refs) {
if (ref.pid == peer_pid) {
return true;
@@ -42,6 +44,18 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process)
{
LOCKER(shared_buffers().lock());
ASSERT(is_shared_with(process.pid()));
+ if (m_global) {
+ bool found = false;
+ for (auto& ref : m_refs) {
+ if (ref.pid == process.pid()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ m_refs.append(Reference(process.pid()));
+ }
+
for (auto& ref : m_refs) {
if (ref.pid == process.pid()) {
ref.count++;
@@ -93,6 +107,7 @@ void SharedBuffer::deref_for_process(Process& process)
destroy_if_unused();
return;
}
+ return;
}
}
diff --git a/Kernel/SharedBuffer.h b/Kernel/SharedBuffer.h
index e779186892..bd2751471d 100644
--- a/Kernel/SharedBuffer.h
+++ b/Kernel/SharedBuffer.h
@@ -36,14 +36,17 @@ public:
bool is_shared_with(pid_t peer_pid);
void* ref_for_process_and_get_address(Process& process);
void share_with(pid_t peer_pid);
+ void share_globally() { m_global = true; }
void deref_for_process(Process& process);
void disown(pid_t pid);
size_t size() const { return m_vmo->size(); }
void destroy_if_unused();
void seal();
+ int id() const { return m_shared_buffer_id; }
int m_shared_buffer_id { -1 };
bool m_writable { true };
+ bool m_global { false };
NonnullRefPtr<VMObject> m_vmo;
Vector<Reference, 2> m_refs;
unsigned m_total_refs { 0 };
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp
index 43db79393e..432a593bba 100644
--- a/Kernel/Syscall.cpp
+++ b/Kernel/Syscall.cpp
@@ -299,6 +299,10 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3
return current->process().sys$dump_backtrace();
case Syscall::SC_watch_file:
return current->process().sys$watch_file((const char*)arg1, (int)arg2);
+ case Syscall::SC_share_buffer_globally:
+ return current->process().sys$share_buffer_globally((int)arg1);
+ case Syscall::SC_set_process_icon:
+ return current->process().sys$set_process_icon((int)arg1);
default:
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
return -ENOSYS;
diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h
index b45343964f..44ba85cd88 100644
--- a/Kernel/Syscall.h
+++ b/Kernel/Syscall.h
@@ -119,7 +119,9 @@ struct timeval;
__ENUMERATE_SYSCALL(dump_backtrace) \
__ENUMERATE_SYSCALL(dbgputch) \
__ENUMERATE_SYSCALL(dbgputstr) \
- __ENUMERATE_SYSCALL(watch_file)
+ __ENUMERATE_SYSCALL(watch_file) \
+ __ENUMERATE_SYSCALL(share_buffer_globally) \
+ __ENUMERATE_SYSCALL(set_process_icon)
namespace Syscall {