From bd3e77cc167bbbaf294c2309511f42315ee6ad6a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 16 Jan 2019 00:20:38 +0100 Subject: [PATCH] Pass the process to CharacterDevice::read/write. This is much nicer than grabbing directly at 'current' inside a read(). --- Kernel/Console.cpp | 4 ++-- Kernel/Console.h | 4 ++-- Kernel/KSyms.cpp | 2 +- Kernel/Keyboard.cpp | 4 ++-- Kernel/Keyboard.h | 4 ++-- Kernel/MasterPTY.cpp | 4 ++-- Kernel/MasterPTY.h | 4 ++-- Kernel/PS2MouseDevice.cpp | 4 ++-- Kernel/PS2MouseDevice.h | 4 ++-- Kernel/Process.cpp | 8 ++++---- Kernel/TTY.cpp | 4 ++-- Kernel/TTY.h | 4 ++-- Kernel/kprintf.cpp | 3 ++- VirtualFileSystem/CharacterDevice.h | 4 ++-- VirtualFileSystem/FileDescriptor.cpp | 12 ++++++------ VirtualFileSystem/FileDescriptor.h | 6 +++--- VirtualFileSystem/FullDevice.cpp | 4 ++-- VirtualFileSystem/FullDevice.h | 4 ++-- VirtualFileSystem/NullDevice.cpp | 4 ++-- VirtualFileSystem/NullDevice.h | 4 ++-- VirtualFileSystem/RandomDevice.cpp | 4 ++-- VirtualFileSystem/RandomDevice.h | 4 ++-- VirtualFileSystem/ZeroDevice.cpp | 4 ++-- VirtualFileSystem/ZeroDevice.h | 4 ++-- Widgets/EventLoop.cpp | 2 +- Widgets/GUIEventDevice.cpp | 12 ++++++------ Widgets/GUIEventDevice.h | 4 ++-- 27 files changed, 63 insertions(+), 62 deletions(-) diff --git a/Kernel/Console.cpp b/Kernel/Console.cpp index eece98ac260..4dbd2df5b41 100644 --- a/Kernel/Console.cpp +++ b/Kernel/Console.cpp @@ -28,14 +28,14 @@ bool Console::can_read(Process&) const return false; } -ssize_t Console::read(byte*, size_t) +ssize_t Console::read(Process&, byte*, size_t) { // FIXME: Implement reading from the console. // Maybe we could use a ring buffer for this device? return 0; } -ssize_t Console::write(const byte* data, size_t size) +ssize_t Console::write(Process&, const byte* data, size_t size) { if (!size) return 0; diff --git a/Kernel/Console.h b/Kernel/Console.h index d8bcc5a24de..fe4c3aea707 100644 --- a/Kernel/Console.h +++ b/Kernel/Console.h @@ -20,8 +20,8 @@ public: virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } - virtual ssize_t read(byte* buffer, size_t size) override; - virtual ssize_t write(const byte* data, size_t size) override; + virtual ssize_t read(Process&, byte* buffer, size_t size) override; + virtual ssize_t write(Process&, const byte* data, size_t size) override; void setImplementation(ConsoleImplementation* implementation) { m_implementation = implementation; } diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index 3d0d0147679..4168e8a43cd 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -128,7 +128,7 @@ void load_ksyms() if (!descriptor) { kprintf("Failed to open /kernel.map\n"); } else { - auto buffer = descriptor->read_entire_file(); + auto buffer = descriptor->read_entire_file(*current); ASSERT(buffer); load_ksyms_from_data(buffer); } diff --git a/Kernel/Keyboard.cpp b/Kernel/Keyboard.cpp index f7c7b799e15..8aa18b32a3d 100644 --- a/Kernel/Keyboard.cpp +++ b/Kernel/Keyboard.cpp @@ -119,7 +119,7 @@ bool Keyboard::can_read(Process&) const return !m_queue.is_empty(); } -ssize_t Keyboard::read(byte* buffer, size_t size) +ssize_t Keyboard::read(Process&, byte* buffer, size_t size) { ssize_t nread = 0; while ((size_t)nread < size) { @@ -130,7 +130,7 @@ ssize_t Keyboard::read(byte* buffer, size_t size) return nread; } -ssize_t Keyboard::write(const byte*, size_t) +ssize_t Keyboard::write(Process&, const byte*, size_t) { return 0; } diff --git a/Kernel/Keyboard.h b/Kernel/Keyboard.h index 63226e756d9..7fab83bb44c 100644 --- a/Kernel/Keyboard.h +++ b/Kernel/Keyboard.h @@ -37,8 +37,8 @@ private: virtual void handle_irq() override; // ^CharacterDevice - virtual ssize_t read(byte* buffer, size_t) override; - virtual ssize_t write(const byte* buffer, size_t) override; + virtual ssize_t read(Process&, byte* buffer, size_t) override; + virtual ssize_t write(Process&, const byte* buffer, size_t) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } diff --git a/Kernel/MasterPTY.cpp b/Kernel/MasterPTY.cpp index af1fd38227c..138d9bc5b05 100644 --- a/Kernel/MasterPTY.cpp +++ b/Kernel/MasterPTY.cpp @@ -20,12 +20,12 @@ String MasterPTY::pts_name() const return buffer; } -ssize_t MasterPTY::read(byte* buffer, size_t size) +ssize_t MasterPTY::read(Process&, byte* buffer, size_t size) { return m_buffer.read(buffer, size); } -ssize_t MasterPTY::write(const byte* buffer, size_t size) +ssize_t MasterPTY::write(Process&, const byte* buffer, size_t size) { m_slave->on_master_write(buffer, size); return size; diff --git a/Kernel/MasterPTY.h b/Kernel/MasterPTY.h index deefe7793b8..822764f57a7 100644 --- a/Kernel/MasterPTY.h +++ b/Kernel/MasterPTY.h @@ -11,8 +11,8 @@ public: virtual ~MasterPTY() override; void set_slave(SlavePTY& slave) { m_slave = &slave; } - virtual ssize_t read(byte*, size_t) override; - virtual ssize_t write(const byte*, size_t) override; + virtual ssize_t read(Process&, byte*, size_t) override; + virtual ssize_t write(Process&, const byte*, size_t) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override; virtual bool is_master_pty() const override { return true; } diff --git a/Kernel/PS2MouseDevice.cpp b/Kernel/PS2MouseDevice.cpp index d3c0b6f7676..679410b72d4 100644 --- a/Kernel/PS2MouseDevice.cpp +++ b/Kernel/PS2MouseDevice.cpp @@ -121,12 +121,12 @@ bool PS2MouseDevice::can_read(Process&) const return !m_buffer.is_empty(); } -ssize_t PS2MouseDevice::read(byte* buffer, size_t size) +ssize_t PS2MouseDevice::read(Process&, byte* buffer, size_t size) { return m_buffer.read(buffer, size); } -ssize_t PS2MouseDevice::write(const byte*, size_t) +ssize_t PS2MouseDevice::write(Process&, const byte*, size_t) { return 0; } diff --git a/Kernel/PS2MouseDevice.h b/Kernel/PS2MouseDevice.h index 1c066c6f892..2dfbb2c1781 100644 --- a/Kernel/PS2MouseDevice.h +++ b/Kernel/PS2MouseDevice.h @@ -13,8 +13,8 @@ public: // ^CharacterDevice virtual bool can_read(Process&) const override; - virtual ssize_t read(byte* buffer, size_t) override; - virtual ssize_t write(const byte* buffer, size_t) override; + virtual ssize_t read(Process&, byte* buffer, size_t) override; + virtual ssize_t write(Process&, const byte* buffer, size_t) override; virtual bool can_write(Process&) const override { return true; } private: diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c08f5176bca..556304e69e8 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1031,7 +1031,7 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size) block(BlockedWrite); Scheduler::yield(); } - ssize_t rc = descriptor->write((const byte*)data + nwritten, size - nwritten); + ssize_t rc = descriptor->write(*this, (const byte*)data + nwritten, size - nwritten); #ifdef IO_DEBUG dbgprintf(" -> write returned %d\n", rc); #endif @@ -1051,7 +1051,7 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size) nwritten += rc; } } else { - nwritten = descriptor->write((const byte*)data, size); + nwritten = descriptor->write(*this, (const byte*)data, size); } if (has_unmasked_pending_signals()) { block(BlockedSignal); @@ -1084,7 +1084,7 @@ ssize_t Process::sys$read(int fd, void* outbuf, size_t nread) return -EINTR; } } - nread = descriptor->read((byte*)outbuf, nread); + nread = descriptor->read(*this, (byte*)outbuf, nread); #ifdef DEBUG_IO dbgprintf("%s(%u) Process::sys$read: nread=%u\n", name().characters(), pid(), nread); #endif @@ -1232,7 +1232,7 @@ int Process::sys$readlink(const char* path, char* buffer, size_t size) if (!descriptor->metadata().isSymbolicLink()) return -EINVAL; - auto contents = descriptor->read_entire_file(); + auto contents = descriptor->read_entire_file(*this); if (!contents) return -EIO; // FIXME: Get a more detailed error from VFS. diff --git a/Kernel/TTY.cpp b/Kernel/TTY.cpp index cc366083293..808e2976f04 100644 --- a/Kernel/TTY.cpp +++ b/Kernel/TTY.cpp @@ -24,12 +24,12 @@ void TTY::set_default_termios() memcpy(m_termios.c_cc, default_cc, sizeof(default_cc)); } -ssize_t TTY::read(byte* buffer, size_t size) +ssize_t TTY::read(Process&, byte* buffer, size_t size) { return m_buffer.read(buffer, size); } -ssize_t TTY::write(const byte* buffer, size_t size) +ssize_t TTY::write(Process&, const byte* buffer, size_t size) { #ifdef TTY_DEBUG dbgprintf("TTY::write {%u} ", size); diff --git a/Kernel/TTY.h b/Kernel/TTY.h index b708bed1d9a..abe06a9141b 100644 --- a/Kernel/TTY.h +++ b/Kernel/TTY.h @@ -10,8 +10,8 @@ class TTY : public CharacterDevice { public: virtual ~TTY() override; - virtual ssize_t read(byte*, size_t) override; - virtual ssize_t write(const byte*, size_t) override; + virtual ssize_t read(Process&, byte*, size_t) override; + virtual ssize_t write(Process&, const byte*, size_t) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override; virtual int ioctl(Process&, unsigned request, unsigned arg) override final; diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp index 412f915ea6b..a7de0d50dd1 100644 --- a/Kernel/kprintf.cpp +++ b/Kernel/kprintf.cpp @@ -2,12 +2,13 @@ #include "Console.h" #include "IO.h" #include +#include "Process.h" #include #include static void console_putch(char*&, char ch) { - Console::the().write((byte*)&ch, 1); + Console::the().write(*current, (byte*)&ch, 1); } int kprintf(const char* fmt, ...) diff --git a/VirtualFileSystem/CharacterDevice.h b/VirtualFileSystem/CharacterDevice.h index 5046f9b2c39..811e3404277 100644 --- a/VirtualFileSystem/CharacterDevice.h +++ b/VirtualFileSystem/CharacterDevice.h @@ -15,8 +15,8 @@ public: virtual bool can_read(Process&) const = 0; virtual bool can_write(Process&) const = 0; - virtual ssize_t read(byte* buffer, size_t bufferSize) = 0; - virtual ssize_t write(const byte* buffer, size_t bufferSize) = 0; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) = 0; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) = 0; unsigned major() const { return m_major; } unsigned minor() const { return m_minor; } diff --git a/VirtualFileSystem/FileDescriptor.cpp b/VirtualFileSystem/FileDescriptor.cpp index 66346673e65..bbfefd829b4 100644 --- a/VirtualFileSystem/FileDescriptor.cpp +++ b/VirtualFileSystem/FileDescriptor.cpp @@ -134,7 +134,7 @@ Unix::off_t FileDescriptor::seek(Unix::off_t offset, int whence) return m_current_offset; } -ssize_t FileDescriptor::read(byte* buffer, size_t count) +ssize_t FileDescriptor::read(Process& process, byte* buffer, size_t count) { if (is_fifo()) { ASSERT(fifo_direction() == FIFO::Reader); @@ -142,7 +142,7 @@ ssize_t FileDescriptor::read(byte* buffer, size_t count) } if (m_vnode->isCharacterDevice()) { // FIXME: What should happen to m_currentOffset? - return m_vnode->characterDevice()->read(buffer, count); + return m_vnode->characterDevice()->read(process, buffer, count); } ASSERT(inode()); ssize_t nread = inode()->read_bytes(m_current_offset, count, buffer, this); @@ -150,7 +150,7 @@ ssize_t FileDescriptor::read(byte* buffer, size_t count) return nread; } -ssize_t FileDescriptor::write(const byte* data, size_t size) +ssize_t FileDescriptor::write(Process& process, const byte* data, size_t size) { if (is_fifo()) { ASSERT(fifo_direction() == FIFO::Writer); @@ -158,7 +158,7 @@ ssize_t FileDescriptor::write(const byte* data, size_t size) } if (m_vnode->isCharacterDevice()) { // FIXME: What should happen to m_currentOffset? - return m_vnode->characterDevice()->write(data, size); + return m_vnode->characterDevice()->write(process, data, size); } // FIXME: Implement non-device writes. ASSERT_NOT_REACHED(); @@ -187,13 +187,13 @@ bool FileDescriptor::has_data_available_for_reading(Process& process) return true; } -ByteBuffer FileDescriptor::read_entire_file() +ByteBuffer FileDescriptor::read_entire_file(Process& process) { ASSERT(!is_fifo()); if (m_vnode->isCharacterDevice()) { auto buffer = ByteBuffer::create_uninitialized(1024); - ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size()); + ssize_t nread = m_vnode->characterDevice()->read(process, buffer.pointer(), buffer.size()); buffer.trim(nread); return buffer; } diff --git a/VirtualFileSystem/FileDescriptor.h b/VirtualFileSystem/FileDescriptor.h index 6fe5cdb32ba..7947954d7f8 100644 --- a/VirtualFileSystem/FileDescriptor.h +++ b/VirtualFileSystem/FileDescriptor.h @@ -25,8 +25,8 @@ public: int close(); Unix::off_t seek(Unix::off_t, int whence); - ssize_t read(byte*, size_t); - ssize_t write(const byte* data, size_t); + ssize_t read(Process&, byte*, size_t); + ssize_t write(Process&, const byte* data, size_t); int stat(Unix::stat*); bool has_data_available_for_reading(Process&); @@ -34,7 +34,7 @@ public: ssize_t get_dir_entries(byte* buffer, size_t); - ByteBuffer read_entire_file(); + ByteBuffer read_entire_file(Process&); String absolute_path(); diff --git a/VirtualFileSystem/FullDevice.cpp b/VirtualFileSystem/FullDevice.cpp index 231dcafe004..d9e94303fbf 100644 --- a/VirtualFileSystem/FullDevice.cpp +++ b/VirtualFileSystem/FullDevice.cpp @@ -18,14 +18,14 @@ bool FullDevice::can_read(Process&) const return true; } -ssize_t FullDevice::read(byte* buffer, size_t bufferSize) +ssize_t FullDevice::read(Process&, byte* buffer, size_t bufferSize) { size_t count = min(GoodBufferSize, bufferSize); memset(buffer, 0, count); return count; } -ssize_t FullDevice::write(const byte*, size_t bufferSize) +ssize_t FullDevice::write(Process&, const byte*, size_t bufferSize) { if (bufferSize == 0) return 0; diff --git a/VirtualFileSystem/FullDevice.h b/VirtualFileSystem/FullDevice.h index f12e65a427a..44b6af0a8c9 100644 --- a/VirtualFileSystem/FullDevice.h +++ b/VirtualFileSystem/FullDevice.h @@ -8,8 +8,8 @@ public: FullDevice(); virtual ~FullDevice() override; - virtual ssize_t read(byte* buffer, size_t bufferSize) override; - virtual ssize_t write(const byte* buffer, size_t bufferSize) override; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } }; diff --git a/VirtualFileSystem/NullDevice.cpp b/VirtualFileSystem/NullDevice.cpp index 7509ff6cc6b..3cc31f5e842 100644 --- a/VirtualFileSystem/NullDevice.cpp +++ b/VirtualFileSystem/NullDevice.cpp @@ -17,12 +17,12 @@ bool NullDevice::can_read(Process&) const return true; } -ssize_t NullDevice::read(byte*, size_t) +ssize_t NullDevice::read(Process&, byte*, size_t) { return 0; } -ssize_t NullDevice::write(const byte*, size_t bufferSize) +ssize_t NullDevice::write(Process&, const byte*, size_t bufferSize) { return min(GoodBufferSize, bufferSize); } diff --git a/VirtualFileSystem/NullDevice.h b/VirtualFileSystem/NullDevice.h index 901ea485180..9e51f1da5cd 100644 --- a/VirtualFileSystem/NullDevice.h +++ b/VirtualFileSystem/NullDevice.h @@ -8,8 +8,8 @@ public: NullDevice(); virtual ~NullDevice() override; - virtual ssize_t read(byte* buffer, size_t bufferSize) override; - virtual ssize_t write(const byte* buffer, size_t bufferSize) override; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual bool can_write(Process&) const override { return true; } virtual bool can_read(Process&) const override; }; diff --git a/VirtualFileSystem/RandomDevice.cpp b/VirtualFileSystem/RandomDevice.cpp index 13d01f9df08..3544080528d 100644 --- a/VirtualFileSystem/RandomDevice.cpp +++ b/VirtualFileSystem/RandomDevice.cpp @@ -34,7 +34,7 @@ bool RandomDevice::can_read(Process&) const return true; } -ssize_t RandomDevice::read(byte* buffer, size_t bufferSize) +ssize_t RandomDevice::read(Process&, byte* buffer, size_t bufferSize) { const int range = 'z' - 'a'; ssize_t nread = min(bufferSize, GoodBufferSize); @@ -45,7 +45,7 @@ ssize_t RandomDevice::read(byte* buffer, size_t bufferSize) return nread; } -ssize_t RandomDevice::write(const byte*, size_t bufferSize) +ssize_t RandomDevice::write(Process&, const byte*, size_t bufferSize) { // FIXME: Use input for entropy? I guess that could be a neat feature? return min(GoodBufferSize, bufferSize); diff --git a/VirtualFileSystem/RandomDevice.h b/VirtualFileSystem/RandomDevice.h index ea1a1040fdd..4711542a540 100644 --- a/VirtualFileSystem/RandomDevice.h +++ b/VirtualFileSystem/RandomDevice.h @@ -8,8 +8,8 @@ public: RandomDevice(); virtual ~RandomDevice() override; - virtual ssize_t read(byte* buffer, size_t bufferSize) override; - virtual ssize_t write(const byte* buffer, size_t bufferSize) override; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } }; diff --git a/VirtualFileSystem/ZeroDevice.cpp b/VirtualFileSystem/ZeroDevice.cpp index 20f3c47ad0d..2b05281e0ab 100644 --- a/VirtualFileSystem/ZeroDevice.cpp +++ b/VirtualFileSystem/ZeroDevice.cpp @@ -17,14 +17,14 @@ bool ZeroDevice::can_read(Process&) const return true; } -ssize_t ZeroDevice::read(byte* buffer, size_t bufferSize) +ssize_t ZeroDevice::read(Process&, byte* buffer, size_t bufferSize) { size_t count = min(GoodBufferSize, bufferSize); memset(buffer, 0, count); return count; } -ssize_t ZeroDevice::write(const byte*, size_t bufferSize) +ssize_t ZeroDevice::write(Process&, const byte*, size_t bufferSize) { return min(GoodBufferSize, bufferSize); } diff --git a/VirtualFileSystem/ZeroDevice.h b/VirtualFileSystem/ZeroDevice.h index a90fbd3c9fe..d3440781a05 100644 --- a/VirtualFileSystem/ZeroDevice.h +++ b/VirtualFileSystem/ZeroDevice.h @@ -8,8 +8,8 @@ public: ZeroDevice(); virtual ~ZeroDevice() override; - virtual ssize_t read(byte* buffer, size_t bufferSize) override; - virtual ssize_t write(const byte* buffer, size_t bufferSize) override; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } }; diff --git a/Widgets/EventLoop.cpp b/Widgets/EventLoop.cpp index 4574a767c94..cbc9c9b0bce 100644 --- a/Widgets/EventLoop.cpp +++ b/Widgets/EventLoop.cpp @@ -78,7 +78,7 @@ void EventLoop::waitForEvent() int dy = 0; while (mouse.can_read(*m_server_process)) { signed_byte data[3]; - ssize_t nread = mouse.read((byte*)data, 3); + ssize_t nread = mouse.read(*m_server_process, (byte*)data, 3); ASSERT(nread == 3); bool left_button = data[0] & 1; bool right_button = data[0] & 2; diff --git a/Widgets/GUIEventDevice.cpp b/Widgets/GUIEventDevice.cpp index 06019073f83..20ba6c917b3 100644 --- a/Widgets/GUIEventDevice.cpp +++ b/Widgets/GUIEventDevice.cpp @@ -19,20 +19,20 @@ bool GUIEventDevice::can_read(Process& process) const return !process.gui_events().is_empty(); } -ssize_t GUIEventDevice::read(byte* buffer, size_t size) +ssize_t GUIEventDevice::read(Process& process, byte* buffer, size_t size) { #ifdef GUIEVENTDEVICE_DEBUG - dbgprintf("GUIEventDevice::read(): %s<%u>, size=%u, sizeof(GUI_Event)=%u\n", current->name().characters(), current->pid(), size, sizeof(GUI_Event)); + dbgprintf("GUIEventDevice::read(): %s<%u>, size=%u, sizeof(GUI_Event)=%u\n", process.name().characters(), process.pid(), size, sizeof(GUI_Event)); #endif - if (current->gui_events().is_empty()) + if (process.gui_events().is_empty()) return 0; - LOCKER(current->gui_events_lock()); + LOCKER(process.gui_events_lock()); ASSERT(size == sizeof(GUI_Event)); - *reinterpret_cast(buffer) = current->gui_events().take_first(); + *reinterpret_cast(buffer) = process.gui_events().take_first(); return size; } -ssize_t GUIEventDevice::write(const byte*, size_t) +ssize_t GUIEventDevice::write(Process&, const byte*, size_t) { return -EINVAL; } diff --git a/Widgets/GUIEventDevice.h b/Widgets/GUIEventDevice.h index db589f664a0..e98b208f052 100644 --- a/Widgets/GUIEventDevice.h +++ b/Widgets/GUIEventDevice.h @@ -9,8 +9,8 @@ public: private: // ^CharacterDevice - virtual ssize_t read(byte* buffer, size_t bufferSize) override; - virtual ssize_t write(const byte* buffer, size_t bufferSize) override; + virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; + virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual bool can_read(Process&) const override; virtual bool can_write(Process&) const override { return true; } };