Kernel: Make ProcessTracer inherit from File.
This commit is contained in:
parent
7ec1f6ab3c
commit
e886337a67
Notes:
sideshowbarker
2024-07-19 14:33:44 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/e886337a674
12 changed files with 105 additions and 182 deletions
|
@ -84,7 +84,7 @@ dword BXVGADevice::find_framebuffer_address()
|
|||
return framebuffer_address;
|
||||
}
|
||||
|
||||
Region* BXVGADevice::mmap(Process& process, LinearAddress preferred_laddr, size_t offset, size_t size)
|
||||
KResultOr<Region*> BXVGADevice::mmap(Process& process, LinearAddress preferred_laddr, size_t offset, size_t size)
|
||||
{
|
||||
ASSERT(offset == 0);
|
||||
ASSERT(size == framebuffer_size_in_bytes());
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
void set_y_offset(int);
|
||||
|
||||
virtual int ioctl(Process&, unsigned request, unsigned arg) override;
|
||||
virtual Region* mmap(Process&, LinearAddress preferred_laddr, size_t offset, size_t) override;
|
||||
virtual KResultOr<Region*> mmap(Process&, LinearAddress preferred_laddr, size_t offset, size_t) override;
|
||||
|
||||
size_t framebuffer_size_in_bytes() const { return m_framebuffer_size.area() * sizeof(dword) * 2; }
|
||||
Size framebuffer_size() const { return m_framebuffer_size; }
|
||||
|
|
|
@ -7,7 +7,7 @@ class BlockDevice : public Device {
|
|||
public:
|
||||
virtual ~BlockDevice() override;
|
||||
|
||||
virtual Region* mmap(Process&, LinearAddress preferred_laddr, size_t offset, size_t size) = 0;
|
||||
virtual bool is_seekable() const override { return true; }
|
||||
|
||||
protected:
|
||||
BlockDevice(unsigned major, unsigned minor) : Device(major, minor) { }
|
||||
|
|
|
@ -13,17 +13,7 @@ Device::~Device()
|
|||
VFS::the().unregister_device(*this);
|
||||
}
|
||||
|
||||
KResultOr<Retained<FileDescriptor>> Device::open(int options)
|
||||
String Device::absolute_path() const
|
||||
{
|
||||
UNUSED_PARAM(options);
|
||||
return FileDescriptor::create(this);
|
||||
}
|
||||
|
||||
void Device::close()
|
||||
{
|
||||
}
|
||||
|
||||
int Device::ioctl(Process&, unsigned, unsigned)
|
||||
{
|
||||
return -ENOTTY;
|
||||
return String::format("device:%u,%u (%s)", m_major, m_minor, class_name());
|
||||
}
|
||||
|
|
|
@ -33,42 +33,21 @@
|
|||
// - Subclasses should take care to validate incoming addresses before dereferencing.
|
||||
//
|
||||
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/FileSystem/FileDescriptor.h>
|
||||
#include <Kernel/File.h>
|
||||
|
||||
class Process;
|
||||
|
||||
class Device : public Retainable<Device> {
|
||||
class Device : public File {
|
||||
public:
|
||||
virtual ~Device();
|
||||
|
||||
InodeMetadata metadata() const { return { }; }
|
||||
|
||||
virtual KResultOr<Retained<FileDescriptor>> open(int options);
|
||||
virtual void close();
|
||||
|
||||
virtual bool can_read(Process&) const = 0;
|
||||
virtual bool can_write(Process&) const = 0;
|
||||
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) = 0;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) = 0;
|
||||
virtual ~Device() override;
|
||||
|
||||
unsigned major() const { return m_major; }
|
||||
unsigned minor() const { return m_minor; }
|
||||
|
||||
virtual bool is_tty() const { return false; }
|
||||
virtual bool is_master_pty() const { return false; }
|
||||
|
||||
virtual int ioctl(Process&, unsigned request, unsigned arg);
|
||||
|
||||
virtual const char* class_name() const = 0;
|
||||
virtual String absolute_path() const override;
|
||||
|
||||
uid_t uid() const { return m_uid; }
|
||||
uid_t gid() const { return m_gid; }
|
||||
|
||||
virtual bool is_block_device() const { return false; }
|
||||
virtual bool is_character_device() const { return false; }
|
||||
virtual bool is_device() const override { return true; }
|
||||
|
||||
protected:
|
||||
Device(unsigned major, unsigned minor);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/FileSystem/FileDescriptor.h>
|
||||
|
|
|
@ -12,21 +12,15 @@
|
|||
#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)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(inode)));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Device>&& device)
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<File>&& file)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(device)));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<ProcessTracer>&& tracer)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(tracer)));
|
||||
return adopt(*new FileDescriptor(move(file)));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<SharedMemory>&& shared_memory)
|
||||
|
@ -54,13 +48,8 @@ FileDescriptor::FileDescriptor(RetainPtr<Inode>&& inode)
|
|||
{
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(RetainPtr<Device>&& device)
|
||||
: m_device(move(device))
|
||||
{
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(RetainPtr<ProcessTracer>&& tracer)
|
||||
: m_tracer(move(tracer))
|
||||
FileDescriptor::FileDescriptor(RetainPtr<File>&& file)
|
||||
: m_file(move(file))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -81,9 +70,9 @@ FileDescriptor::~FileDescriptor()
|
|||
m_socket->detach_fd(m_socket_role);
|
||||
m_socket = nullptr;
|
||||
}
|
||||
if (m_device) {
|
||||
m_device->close();
|
||||
m_device = nullptr;
|
||||
if (m_file) {
|
||||
m_file->close();
|
||||
m_file = nullptr;
|
||||
}
|
||||
if (m_fifo) {
|
||||
m_fifo->close(fifo_direction());
|
||||
|
@ -113,8 +102,8 @@ Retained<FileDescriptor> FileDescriptor::clone()
|
|||
? FileDescriptor::create_pipe_reader(*m_fifo)
|
||||
: FileDescriptor::create_pipe_writer(*m_fifo);
|
||||
} else {
|
||||
if (m_device) {
|
||||
descriptor = FileDescriptor::create(m_device.copy_ref());
|
||||
if (m_file) {
|
||||
descriptor = FileDescriptor::create(m_file.copy_ref());
|
||||
descriptor->m_inode = m_inode.copy_ref();
|
||||
} else if (m_socket) {
|
||||
descriptor = FileDescriptor::create(m_socket.copy_ref(), m_socket_role);
|
||||
|
@ -140,7 +129,7 @@ bool addition_would_overflow(off_t a, off_t b)
|
|||
KResult FileDescriptor::fstat(stat& buffer)
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
if (!m_inode && !m_device)
|
||||
if (!m_inode && !m_file)
|
||||
return KResult(-EBADF);
|
||||
|
||||
auto metadata = this->metadata();
|
||||
|
@ -173,7 +162,7 @@ KResult FileDescriptor::fchmod(mode_t mode)
|
|||
off_t FileDescriptor::seek(off_t offset, int whence)
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
if (!m_inode && !m_device)
|
||||
if (!m_inode && !m_file)
|
||||
return -EBADF;
|
||||
|
||||
// FIXME: The file type should be cached on the vnode.
|
||||
|
@ -210,15 +199,15 @@ 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);
|
||||
}
|
||||
if (m_device) {
|
||||
// FIXME: What should happen to m_currentOffset?
|
||||
return m_device->read(process, buffer, count);
|
||||
if (m_file) {
|
||||
int nread = m_file->read(process, buffer, count);
|
||||
if (!m_file->is_seekable())
|
||||
m_current_offset += nread;
|
||||
return nread;
|
||||
}
|
||||
if (m_socket)
|
||||
return m_socket->read(m_socket_role, buffer, count);
|
||||
|
@ -230,17 +219,15 @@ 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);
|
||||
}
|
||||
if (m_device) {
|
||||
// FIXME: What should happen to m_currentOffset?
|
||||
return m_device->write(process, data, size);
|
||||
if (m_file) {
|
||||
int nwritten = m_file->write(process, data, size);
|
||||
if (m_file->is_seekable())
|
||||
m_current_offset += nwritten;
|
||||
return nwritten;
|
||||
}
|
||||
if (m_socket)
|
||||
return m_socket->write(m_socket_role, data, size);
|
||||
|
@ -252,14 +239,12 @@ 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();
|
||||
}
|
||||
if (m_device)
|
||||
return m_device->can_write(process);
|
||||
if (m_file)
|
||||
return m_file->can_write(process);
|
||||
if (m_socket)
|
||||
return m_socket->can_write(m_socket_role);
|
||||
return true;
|
||||
|
@ -267,14 +252,12 @@ 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();
|
||||
}
|
||||
if (m_device)
|
||||
return m_device->can_read(process);
|
||||
if (m_file)
|
||||
return m_file->can_read(process);
|
||||
if (m_socket)
|
||||
return m_socket->can_read(m_socket_role);
|
||||
return true;
|
||||
|
@ -282,11 +265,13 @@ bool FileDescriptor::can_read(Process& process)
|
|||
|
||||
ByteBuffer FileDescriptor::read_entire_file(Process& process)
|
||||
{
|
||||
// HACK ALERT: (This entire function)
|
||||
|
||||
ASSERT(!is_fifo());
|
||||
|
||||
if (m_device) {
|
||||
if (m_file) {
|
||||
auto buffer = ByteBuffer::create_uninitialized(1024);
|
||||
ssize_t nread = m_device->read(process, buffer.pointer(), buffer.size());
|
||||
ssize_t nread = m_file->read(process, buffer.pointer(), buffer.size());
|
||||
ASSERT(nread >= 0);
|
||||
buffer.trim(nread);
|
||||
return buffer;
|
||||
|
@ -330,44 +315,47 @@ ssize_t FileDescriptor::get_dir_entries(byte* buffer, ssize_t size)
|
|||
return stream.offset();
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_device() const
|
||||
{
|
||||
return m_file && m_file->is_device();
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_tty() const
|
||||
{
|
||||
return m_device && m_device->is_tty();
|
||||
return m_file && m_file->is_tty();
|
||||
}
|
||||
|
||||
const TTY* FileDescriptor::tty() const
|
||||
{
|
||||
if (!is_tty())
|
||||
return nullptr;
|
||||
return static_cast<const TTY*>(m_device.ptr());
|
||||
return static_cast<const TTY*>(m_file.ptr());
|
||||
}
|
||||
|
||||
TTY* FileDescriptor::tty()
|
||||
{
|
||||
if (!is_tty())
|
||||
return nullptr;
|
||||
return static_cast<TTY*>(m_device.ptr());
|
||||
return static_cast<TTY*>(m_file.ptr());
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_master_pty() const
|
||||
{
|
||||
if (m_device)
|
||||
return m_device->is_master_pty();
|
||||
return false;
|
||||
return m_file && m_file->is_master_pty();
|
||||
}
|
||||
|
||||
const MasterPTY* FileDescriptor::master_pty() const
|
||||
{
|
||||
if (!is_master_pty())
|
||||
return nullptr;
|
||||
return static_cast<const MasterPTY*>(m_device.ptr());
|
||||
return static_cast<const MasterPTY*>(m_file.ptr());
|
||||
}
|
||||
|
||||
MasterPTY* FileDescriptor::master_pty()
|
||||
{
|
||||
if (!is_master_pty())
|
||||
return nullptr;
|
||||
return static_cast<MasterPTY*>(m_device.ptr());
|
||||
return static_cast<MasterPTY*>(m_file.ptr());
|
||||
}
|
||||
|
||||
int FileDescriptor::close()
|
||||
|
@ -389,22 +377,19 @@ const char* to_string(SocketRole role)
|
|||
}
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_file() const
|
||||
bool FileDescriptor::is_fsfile() const
|
||||
{
|
||||
return !is_tty() && !is_fifo() && !is_device() && !is_socket() && !is_shared_memory();
|
||||
}
|
||||
|
||||
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())
|
||||
return String::format("fifo:%u", m_fifo.ptr());
|
||||
if (is_device())
|
||||
return String::format("device:%u,%u (%s)", m_device->major(), m_device->minor(), m_device->class_name());
|
||||
if (m_file)
|
||||
return m_file->absolute_path();
|
||||
if (is_socket())
|
||||
return String::format("socket:%x (role: %s)", m_socket.ptr(), to_string(m_socket_role));
|
||||
ASSERT(m_inode);
|
||||
|
@ -426,32 +411,20 @@ InodeMetadata FileDescriptor::metadata() const
|
|||
return { };
|
||||
}
|
||||
|
||||
bool FileDescriptor::supports_mmap() const
|
||||
KResultOr<Region*> FileDescriptor::mmap(Process& process, LinearAddress laddr, size_t offset, size_t size, int prot)
|
||||
{
|
||||
if (m_tracer)
|
||||
return false;
|
||||
if (m_inode)
|
||||
return true;
|
||||
if (m_shared_memory)
|
||||
return true;
|
||||
if (m_device)
|
||||
return m_device->is_block_device();
|
||||
return false;
|
||||
}
|
||||
|
||||
Region* FileDescriptor::mmap(Process& process, LinearAddress laddr, size_t offset, size_t size, int prot)
|
||||
{
|
||||
ASSERT(supports_mmap());
|
||||
|
||||
if (is_block_device())
|
||||
return static_cast<BlockDevice&>(*m_device).mmap(process, laddr, offset, size);
|
||||
if (m_file)
|
||||
return m_file->mmap(process, laddr, offset, size);
|
||||
|
||||
if (is_shared_memory()) {
|
||||
if (!shared_memory()->vmo())
|
||||
return nullptr;
|
||||
return KResult(-ENODEV);
|
||||
return process.allocate_region_with_vmo(laddr, size, *shared_memory()->vmo(), offset, shared_memory()->name(), true, true);
|
||||
}
|
||||
|
||||
if (!is_fsfile())
|
||||
return KResult(-ENODEV);
|
||||
|
||||
ASSERT(m_inode);
|
||||
// FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec.
|
||||
String region_name;
|
||||
|
@ -469,26 +442,6 @@ Region* FileDescriptor::mmap(Process& process, LinearAddress laddr, size_t offse
|
|||
return region;
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_block_device() const
|
||||
{
|
||||
return m_device && m_device->is_block_device();
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_character_device() const
|
||||
{
|
||||
return m_device && m_device->is_character_device();
|
||||
}
|
||||
|
||||
CharacterDevice* FileDescriptor::character_device()
|
||||
{
|
||||
return is_character_device() ? static_cast<CharacterDevice*>(device()) : nullptr;
|
||||
}
|
||||
|
||||
const CharacterDevice* FileDescriptor::character_device() const
|
||||
{
|
||||
return is_character_device() ? static_cast<const CharacterDevice*>(device()) : nullptr;
|
||||
}
|
||||
|
||||
KResult FileDescriptor::truncate(off_t length)
|
||||
{
|
||||
if (is_file()) {
|
||||
|
|
|
@ -11,21 +11,19 @@
|
|||
#include <Kernel/Net/Socket.h>
|
||||
#include <Kernel/SharedMemory.h>
|
||||
|
||||
class File;
|
||||
class TTY;
|
||||
class MasterPTY;
|
||||
class Process;
|
||||
class ProcessTracer;
|
||||
class Region;
|
||||
class CharacterDevice;
|
||||
|
||||
class FileDescriptor : public Retainable<FileDescriptor> {
|
||||
public:
|
||||
|
||||
static Retained<FileDescriptor> create(RetainPtr<Socket>&&, SocketRole = SocketRole::None);
|
||||
static Retained<FileDescriptor> create(RetainPtr<Inode>&&);
|
||||
static Retained<FileDescriptor> create(RetainPtr<Device>&&);
|
||||
static Retained<FileDescriptor> create(RetainPtr<File>&&);
|
||||
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();
|
||||
|
@ -52,14 +50,12 @@ public:
|
|||
|
||||
bool is_directory() const;
|
||||
|
||||
bool is_device() const { return m_device.ptr(); }
|
||||
Device* device() { return m_device.ptr(); }
|
||||
const Device* device() const { return m_device.ptr(); }
|
||||
// FIXME: These should go away once everything is a File.
|
||||
bool is_file() const { return m_file.ptr(); }
|
||||
File* file() { return m_file.ptr(); }
|
||||
const File* file() const { return m_file.ptr(); }
|
||||
|
||||
bool is_block_device() const;
|
||||
bool is_character_device() const;
|
||||
CharacterDevice* character_device();
|
||||
const CharacterDevice* character_device() const;
|
||||
bool is_device() const;
|
||||
|
||||
bool is_tty() const;
|
||||
const TTY* tty() const;
|
||||
|
@ -73,8 +69,7 @@ public:
|
|||
Inode* inode() { return m_inode.ptr(); }
|
||||
const Inode* inode() const { return m_inode.ptr(); }
|
||||
|
||||
bool supports_mmap() const;
|
||||
Region* mmap(Process&, LinearAddress, size_t offset, size_t, int prot);
|
||||
KResultOr<Region*> mmap(Process&, LinearAddress, size_t offset, size_t, int prot);
|
||||
|
||||
bool is_blocking() const { return m_is_blocking; }
|
||||
void set_blocking(bool b) { m_is_blocking = b; }
|
||||
|
@ -89,7 +84,7 @@ public:
|
|||
bool is_fifo() const { return m_fifo; }
|
||||
FIFO::Direction fifo_direction() { return m_fifo_direction; }
|
||||
|
||||
bool is_file() const;
|
||||
bool is_fsfile() const;
|
||||
bool is_shared_memory() const { return m_shared_memory; }
|
||||
SharedMemory* shared_memory() { return m_shared_memory.ptr(); }
|
||||
const SharedMemory* shared_memory() const { return m_shared_memory.ptr(); }
|
||||
|
@ -103,20 +98,16 @@ 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<File>&&);
|
||||
explicit FileDescriptor(RetainPtr<SharedMemory>&&);
|
||||
FileDescriptor(FIFO&, FIFO::Direction);
|
||||
|
||||
RetainPtr<Inode> m_inode;
|
||||
RetainPtr<Device> m_device;
|
||||
RetainPtr<File> m_file;
|
||||
|
||||
off_t m_current_offset { 0 };
|
||||
|
||||
|
@ -132,7 +123,6 @@ private:
|
|||
FIFO::Direction m_fifo_direction { FIFO::Neither };
|
||||
|
||||
RetainPtr<SharedMemory> m_shared_memory;
|
||||
RetainPtr<ProcessTracer> m_tracer;
|
||||
|
||||
bool m_closed { false };
|
||||
};
|
||||
|
|
|
@ -48,7 +48,8 @@ KERNEL_OBJS = \
|
|||
Net/LoopbackAdapter.o \
|
||||
Net/Routing.o \
|
||||
Net/NetworkTask.o \
|
||||
ProcessTracer.o
|
||||
ProcessTracer.o \
|
||||
File.o
|
||||
|
||||
VFS_OBJS = \
|
||||
FileSystem/ProcFS.o \
|
||||
|
|
|
@ -175,11 +175,10 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* params)
|
|||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return (void*)-EBADF;
|
||||
if (!descriptor->supports_mmap())
|
||||
return (void*)-ENODEV;
|
||||
auto* region = descriptor->mmap(*this, LinearAddress((dword)addr), offset, size, prot);
|
||||
if (!region)
|
||||
return (void*)-ENOMEM;
|
||||
auto region_or_error = descriptor->mmap(*this, LinearAddress((dword)addr), offset, size, prot);
|
||||
if (region_or_error.is_error())
|
||||
return (void*)(int)region_or_error.error();
|
||||
auto region = region_or_error.value();
|
||||
if (flags & MAP_SHARED)
|
||||
region->set_shared(true);
|
||||
return region->laddr().as_ptr();
|
||||
|
@ -1539,9 +1538,9 @@ int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
|||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
if (!descriptor->is_device())
|
||||
if (!descriptor->is_file())
|
||||
return -ENOTTY;
|
||||
return descriptor->device()->ioctl(*this, request, arg);
|
||||
return descriptor->file()->ioctl(*this, request, arg);
|
||||
}
|
||||
|
||||
int Process::sys$getdtablesize()
|
||||
|
|
|
@ -18,14 +18,18 @@ void ProcessTracer::did_syscall(dword function, dword arg1, dword arg2, dword ar
|
|||
m_calls.enqueue(data);
|
||||
}
|
||||
|
||||
int ProcessTracer::read(byte* buffer, int buffer_size)
|
||||
int ProcessTracer::read(Process&, byte* buffer, int buffer_size)
|
||||
{
|
||||
if (!m_calls.is_empty()) {
|
||||
auto data = m_calls.dequeue();
|
||||
// FIXME: This should not be an assertion.
|
||||
ASSERT(buffer_size == sizeof(data));
|
||||
memcpy(buffer, &data, sizeof(data));
|
||||
return sizeof(data);
|
||||
}
|
||||
return 0;
|
||||
if (m_calls.is_empty())
|
||||
return 0;
|
||||
auto data = m_calls.dequeue();
|
||||
// FIXME: This should not be an assertion.
|
||||
ASSERT(buffer_size == sizeof(data));
|
||||
memcpy(buffer, &data, sizeof(data));
|
||||
return sizeof(data);
|
||||
}
|
||||
|
||||
String ProcessTracer::absolute_path() const
|
||||
{
|
||||
return String::format("tracer:%d", m_pid);
|
||||
}
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/Retained.h>
|
||||
#include <Kernel/File.h>
|
||||
#include <AK/CircularQueue.h>
|
||||
#include <Kernel/UnixTypes.h>
|
||||
|
||||
class ProcessTracer : public Retainable<ProcessTracer> {
|
||||
class ProcessTracer : public File {
|
||||
public:
|
||||
static Retained<ProcessTracer> create(pid_t pid) { return adopt(*new ProcessTracer(pid)); }
|
||||
~ProcessTracer();
|
||||
virtual ~ProcessTracer() override;
|
||||
|
||||
bool is_dead() const { return m_dead; }
|
||||
void set_dead() { m_dead = true; }
|
||||
|
||||
bool can_read() const { return !m_calls.is_empty() || m_dead; }
|
||||
int read(byte*, int);
|
||||
virtual bool can_read(Process&) const override { return !m_calls.is_empty() || m_dead; }
|
||||
virtual int read(Process&, byte*, int) override;
|
||||
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual int write(Process&, const byte*, int) override { return -EIO; }
|
||||
|
||||
virtual String absolute_path() const override;
|
||||
|
||||
void did_syscall(dword function, dword arg1, dword arg2, dword arg3, dword result);
|
||||
pid_t pid() const { return m_pid; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ProcessTracer"; }
|
||||
explicit ProcessTracer(pid_t);
|
||||
|
||||
struct CallData {
|
||||
|
|
Loading…
Add table
Reference in a new issue