summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-22 18:44:45 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-22 18:44:45 +0200
commit5c68929aa1724867eec6b65c0ae50dc8a8d4c589 (patch)
treeee997e95163743f7c92354f87f5fe722f31b1031 /Kernel/FileSystem
parent6693cfb26acf9d5b53d090be309956456f546239 (diff)
downloadserenity-5c68929aa1724867eec6b65c0ae50dc8a8d4c589.zip
Kernel: Add a systrace() syscall and implement /bin/strace using it.
Calling systrace(pid) gives you a file descriptor with a stream of the syscalls made by a peer process. The process must be owned by the same UID who calls systrace(). :^)
Diffstat (limited to 'Kernel/FileSystem')
-rw-r--r--Kernel/FileSystem/FileDescriptor.cpp25
-rw-r--r--Kernel/FileSystem/FileDescriptor.h7
2 files changed, 32 insertions, 0 deletions
diff --git a/Kernel/FileSystem/FileDescriptor.cpp b/Kernel/FileSystem/FileDescriptor.cpp
index fd839a55a3..5b482affc8 100644
--- a/Kernel/FileSystem/FileDescriptor.cpp
+++ b/Kernel/FileSystem/FileDescriptor.cpp
@@ -12,6 +12,7 @@
#include <Kernel/Devices/BlockDevice.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/SharedMemory.h>
+#include <Kernel/ProcessTracer.h>
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Inode>&& inode)
{
@@ -23,6 +24,11 @@ Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Device>&& device)
return adopt(*new FileDescriptor(move(device)));
}
+Retained<FileDescriptor> FileDescriptor::create(RetainPtr<ProcessTracer>&& tracer)
+{
+ return adopt(*new FileDescriptor(move(tracer)));
+}
+
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<SharedMemory>&& shared_memory)
{
return adopt(*new FileDescriptor(move(shared_memory)));
@@ -53,6 +59,11 @@ FileDescriptor::FileDescriptor(RetainPtr<Device>&& device)
{
}
+FileDescriptor::FileDescriptor(RetainPtr<ProcessTracer>&& tracer)
+ : m_tracer(move(tracer))
+{
+}
+
FileDescriptor::FileDescriptor(RetainPtr<SharedMemory>&& shared_memory)
: m_shared_memory(move(shared_memory))
{
@@ -199,6 +210,8 @@ off_t FileDescriptor::seek(off_t offset, int whence)
ssize_t FileDescriptor::read(Process& process, byte* buffer, ssize_t count)
{
+ if (m_tracer)
+ return m_tracer->read(buffer, count);
if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Reader);
return m_fifo->read(buffer, count);
@@ -217,6 +230,10 @@ ssize_t FileDescriptor::read(Process& process, byte* buffer, ssize_t count)
ssize_t FileDescriptor::write(Process& process, const byte* data, ssize_t size)
{
+ if (m_tracer) {
+ // FIXME: Figure out what the right error code would be.
+ return -EIO;
+ }
if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Writer);
return m_fifo->write(data, size);
@@ -235,6 +252,8 @@ ssize_t FileDescriptor::write(Process& process, const byte* data, ssize_t size)
bool FileDescriptor::can_write(Process& process)
{
+ if (m_tracer)
+ return true;
if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Writer);
return m_fifo->can_write();
@@ -248,6 +267,8 @@ bool FileDescriptor::can_write(Process& process)
bool FileDescriptor::can_read(Process& process)
{
+ if (m_tracer)
+ return m_tracer->can_read();
if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Reader);
return m_fifo->can_read();
@@ -376,6 +397,8 @@ bool FileDescriptor::is_file() const
KResultOr<String> FileDescriptor::absolute_path()
{
Stopwatch sw("absolute_path");
+ if (m_tracer)
+ return String::format("tracer:%d", m_tracer->pid());
if (is_tty())
return tty()->tty_name();
if (is_fifo())
@@ -405,6 +428,8 @@ InodeMetadata FileDescriptor::metadata() const
bool FileDescriptor::supports_mmap() const
{
+ if (m_tracer)
+ return false;
if (m_inode)
return true;
if (m_shared_memory)
diff --git a/Kernel/FileSystem/FileDescriptor.h b/Kernel/FileSystem/FileDescriptor.h
index 4b0892651e..e0f8e71049 100644
--- a/Kernel/FileSystem/FileDescriptor.h
+++ b/Kernel/FileSystem/FileDescriptor.h
@@ -14,6 +14,7 @@
class TTY;
class MasterPTY;
class Process;
+class ProcessTracer;
class Region;
class CharacterDevice;
@@ -24,6 +25,7 @@ public:
static Retained<FileDescriptor> create(RetainPtr<Inode>&&);
static Retained<FileDescriptor> create(RetainPtr<Device>&&);
static Retained<FileDescriptor> create(RetainPtr<SharedMemory>&&);
+ static Retained<FileDescriptor> create(RetainPtr<ProcessTracer>&&);
static Retained<FileDescriptor> create_pipe_writer(FIFO&);
static Retained<FileDescriptor> create_pipe_reader(FIFO&);
~FileDescriptor();
@@ -101,11 +103,15 @@ public:
KResult truncate(off_t);
+ ProcessTracer* tracer() { return m_tracer.ptr(); }
+ const ProcessTracer* tracer() const { return m_tracer.ptr(); }
+
private:
friend class VFS;
FileDescriptor(RetainPtr<Socket>&&, SocketRole);
explicit FileDescriptor(RetainPtr<Inode>&&);
explicit FileDescriptor(RetainPtr<Device>&&);
+ explicit FileDescriptor(RetainPtr<ProcessTracer>&&);
explicit FileDescriptor(RetainPtr<SharedMemory>&&);
FileDescriptor(FIFO&, FIFO::Direction);
@@ -126,6 +132,7 @@ private:
FIFO::Direction m_fifo_direction { FIFO::Neither };
RetainPtr<SharedMemory> m_shared_memory;
+ RetainPtr<ProcessTracer> m_tracer;
bool m_closed { false };
};