1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

Kernel: Make ProcessTracer inherit from File.

This commit is contained in:
Andreas Kling 2019-04-28 15:02:55 +02:00
parent 7ec1f6ab3c
commit e886337a67
12 changed files with 105 additions and 182 deletions

View file

@ -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()) {