1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:28:12 +00:00

Kernel: Make File::write() and File::read() return KResultOr<size_t>

Instead of returning a ssize_t where negative values mean error,
we now return KResultOr<size_t> and use the error state to report
errors exclusively.
This commit is contained in:
Andreas Kling 2020-08-04 18:02:23 +02:00
parent 58feebeed2
commit 7a3ab6c517
58 changed files with 223 additions and 229 deletions

View file

@ -61,18 +61,18 @@ bool Console::can_read(const Kernel::FileDescription&, size_t) const
return false; return false;
} }
ssize_t Console::read(Kernel::FileDescription&, size_t, u8*, ssize_t) Kernel::KResultOr<size_t> Console::read(Kernel::FileDescription&, size_t, u8*, size_t)
{ {
// FIXME: Implement reading from the console. // FIXME: Implement reading from the console.
// Maybe we could use a ring buffer for this device? // Maybe we could use a ring buffer for this device?
return 0; return 0;
} }
ssize_t Console::write(Kernel::FileDescription&, size_t, const u8* data, ssize_t size) Kernel::KResultOr<size_t> Console::write(Kernel::FileDescription&, size_t, const u8* data, size_t size)
{ {
if (!size) if (!size)
return 0; return 0;
for (ssize_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
put_char(data[i]); put_char(data[i]);
return size; return size;
} }

View file

@ -42,8 +42,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(const Kernel::FileDescription&, size_t) const override; virtual bool can_read(const Kernel::FileDescription&, size_t) const override;
virtual bool can_write(const Kernel::FileDescription&, size_t) const override { return true; } virtual bool can_write(const Kernel::FileDescription&, size_t) const override { return true; }
virtual ssize_t read(Kernel::FileDescription&, size_t, u8*, ssize_t) override; virtual Kernel::KResultOr<size_t> read(Kernel::FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(Kernel::FileDescription&, size_t, const u8*, ssize_t) override; virtual Kernel::KResultOr<size_t> write(Kernel::FileDescription&, size_t, const u8*, size_t) override;
virtual const char* class_name() const override { return "Console"; } virtual const char* class_name() const override { return "Console"; }
void put_char(char); void put_char(char);

View file

@ -47,8 +47,8 @@ private:
virtual const char* class_name() const override { return "BXVGA"; } virtual const char* class_name() const override { return "BXVGA"; }
virtual bool can_read(const FileDescription&, size_t) const override { return true; } virtual bool can_read(const FileDescription&, size_t) const override { return true; }
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override { return -EINVAL; } virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override { return -EINVAL; }
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return -EINVAL; } virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override { return -EINVAL; }
virtual bool read_blocks(unsigned, u16, u8*) override { return false; } virtual bool read_blocks(unsigned, u16, u8*) override { return false; }
virtual bool write_blocks(unsigned, u16, const u8*) override { return false; } virtual bool write_blocks(unsigned, u16, const u8*) override { return false; }

View file

@ -48,7 +48,7 @@ DiskPartition::~DiskPartition()
{ {
} }
ssize_t DiskPartition::read(FileDescription& fd, size_t offset, u8* outbuf, ssize_t len) KResultOr<size_t> DiskPartition::read(FileDescription& fd, size_t offset, u8* outbuf, size_t len)
{ {
unsigned adjust = m_block_offset * block_size(); unsigned adjust = m_block_offset * block_size();
@ -70,7 +70,7 @@ bool DiskPartition::can_read(const FileDescription& fd, size_t offset) const
return m_device->can_read(fd, offset + adjust); return m_device->can_read(fd, offset + adjust);
} }
ssize_t DiskPartition::write(FileDescription& fd, size_t offset, const u8* inbuf, ssize_t len) KResultOr<size_t> DiskPartition::write(FileDescription& fd, size_t offset, const u8* inbuf, size_t len)
{ {
unsigned adjust = m_block_offset * block_size(); unsigned adjust = m_block_offset * block_size();

View file

@ -40,9 +40,9 @@ public:
virtual bool write_blocks(unsigned index, u16 count, const u8*) override; virtual bool write_blocks(unsigned index, u16 count, const u8*) override;
// ^BlockDevice // ^BlockDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
private: private:

View file

@ -46,18 +46,18 @@ bool FullDevice::can_read(const FileDescription&, size_t) const
return true; return true;
} }
ssize_t FullDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> FullDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
ssize_t count = min(static_cast<ssize_t>(PAGE_SIZE), size); ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
memset(buffer, 0, (size_t)count); memset(buffer, 0, count);
return count; return count;
} }
ssize_t FullDevice::write(FileDescription&, size_t, const u8*, ssize_t size) KResultOr<size_t> FullDevice::write(FileDescription&, size_t, const u8*, size_t size)
{ {
if (size == 0) if (size == 0)
return 0; return 0;
return -ENOSPC; return KResult(-ENOSPC);
} }
} }

View file

@ -38,8 +38,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* class_name() const override { return "FullDevice"; } virtual const char* class_name() const override { return "FullDevice"; }

View file

@ -366,9 +366,9 @@ bool KeyboardDevice::can_read(const FileDescription&, size_t) const
return !m_queue.is_empty(); return !m_queue.is_empty();
} }
ssize_t KeyboardDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> KeyboardDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
ssize_t nread = 0; size_t nread = 0;
while (nread < size) { while (nread < size) {
if (m_queue.is_empty()) if (m_queue.is_empty())
break; break;
@ -382,7 +382,7 @@ ssize_t KeyboardDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size)
return nread; return nread;
} }
ssize_t KeyboardDevice::write(FileDescription&, size_t, const u8*, ssize_t) KResultOr<size_t> KeyboardDevice::write(FileDescription&, size_t, const u8*, size_t)
{ {
return 0; return 0;
} }

View file

@ -54,9 +54,9 @@ public:
void set_maps(Keyboard::CharacterMapData character_map); void set_maps(Keyboard::CharacterMapData character_map);
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8* buffer, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t write(FileDescription&, size_t, const u8* buffer, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* purpose() const override { return class_name(); } virtual const char* purpose() const override { return class_name(); }

View file

@ -47,8 +47,8 @@ private:
virtual const char* class_name() const override { return "MBVGA"; } virtual const char* class_name() const override { return "MBVGA"; }
virtual bool can_read(const FileDescription&, size_t) const override { return true; } virtual bool can_read(const FileDescription&, size_t) const override { return true; }
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override { return -EINVAL; } virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override { return -EINVAL; }
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return -EINVAL; } virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override { return -EINVAL; }
virtual bool read_blocks(unsigned, u16, u8*) override { return false; } virtual bool read_blocks(unsigned, u16, u8*) override { return false; }
virtual bool write_blocks(unsigned, u16, const u8*) override { return false; } virtual bool write_blocks(unsigned, u16, const u8*) override { return false; }

View file

@ -52,14 +52,14 @@ bool NullDevice::can_read(const FileDescription&, size_t) const
return true; return true;
} }
ssize_t NullDevice::read(FileDescription&, size_t, u8*, ssize_t) KResultOr<size_t> NullDevice::read(FileDescription&, size_t, u8*, size_t)
{ {
return 0; return 0;
} }
ssize_t NullDevice::write(FileDescription&, size_t, const u8*, ssize_t buffer_size) KResultOr<size_t> NullDevice::write(FileDescription&, size_t, const u8*, size_t buffer_size)
{ {
return min(static_cast<ssize_t>(PAGE_SIZE), buffer_size); return min(static_cast<size_t>(PAGE_SIZE), buffer_size);
} }
} }

View file

@ -40,8 +40,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual const char* class_name() const override { return "NullDevice"; } virtual const char* class_name() const override { return "NullDevice"; }

View file

@ -80,7 +80,7 @@ void PATADiskDevice::set_drive_geometry(u16 cyls, u16 heads, u16 spt)
m_sectors_per_track = spt; m_sectors_per_track = spt;
} }
ssize_t PATADiskDevice::read(FileDescription&, size_t offset, u8* outbuf, ssize_t len) KResultOr<size_t> PATADiskDevice::read(FileDescription&, size_t offset, u8* outbuf, size_t len)
{ {
unsigned index = offset / block_size(); unsigned index = offset / block_size();
u16 whole_blocks = len / block_size(); u16 whole_blocks = len / block_size();
@ -121,7 +121,7 @@ bool PATADiskDevice::can_read(const FileDescription&, size_t offset) const
return offset < (m_cylinders * m_heads * m_sectors_per_track * block_size()); return offset < (m_cylinders * m_heads * m_sectors_per_track * block_size());
} }
ssize_t PATADiskDevice::write(FileDescription&, size_t offset, const u8* inbuf, ssize_t len) KResultOr<size_t> PATADiskDevice::write(FileDescription&, size_t offset, const u8* inbuf, size_t len)
{ {
unsigned index = offset / block_size(); unsigned index = offset / block_size();
u16 whole_blocks = len / block_size(); u16 whole_blocks = len / block_size();

View file

@ -61,9 +61,9 @@ public:
void set_drive_geometry(u16, u16, u16); void set_drive_geometry(u16, u16, u16);
// ^BlockDevice // ^BlockDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
protected: protected:

View file

@ -324,7 +324,7 @@ bool PS2MouseDevice::can_read(const FileDescription&, size_t) const
return !m_queue.is_empty(); return !m_queue.is_empty();
} }
ssize_t PS2MouseDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> PS2MouseDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
ASSERT(size > 0); ASSERT(size > 0);
size_t nread = 0; size_t nread = 0;
@ -344,7 +344,7 @@ ssize_t PS2MouseDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size)
return nread; return nread;
} }
ssize_t PS2MouseDevice::write(FileDescription&, size_t, const u8*, ssize_t) KResultOr<size_t> PS2MouseDevice::write(FileDescription&, size_t, const u8*, size_t)
{ {
return 0; return 0;
} }

View file

@ -44,8 +44,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* purpose() const override { return class_name(); } virtual const char* purpose() const override { return class_name(); }

View file

@ -43,16 +43,16 @@ bool RandomDevice::can_read(const FileDescription&, size_t) const
return true; return true;
} }
ssize_t RandomDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> RandomDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
get_good_random_bytes(buffer, size); get_good_random_bytes(buffer, size);
return size; return size;
} }
ssize_t RandomDevice::write(FileDescription&, size_t, const u8*, ssize_t size) KResultOr<size_t> RandomDevice::write(FileDescription&, size_t, const u8*, size_t size)
{ {
// FIXME: Use input for entropy? I guess that could be a neat feature? // FIXME: Use input for entropy? I guess that could be a neat feature?
return min(static_cast<ssize_t>(PAGE_SIZE), size); return min(static_cast<size_t>(PAGE_SIZE), size);
} }
} }

View file

@ -38,8 +38,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* class_name() const override { return "RandomDevice"; } virtual const char* class_name() const override { return "RandomDevice"; }

View file

@ -172,7 +172,7 @@ bool SB16::can_read(const FileDescription&, size_t) const
return false; return false;
} }
ssize_t SB16::read(FileDescription&, size_t, u8*, ssize_t) KResultOr<size_t> SB16::read(FileDescription&, size_t, u8*, size_t)
{ {
return 0; return 0;
} }
@ -226,7 +226,7 @@ void SB16::wait_for_irq()
disable_irq(); disable_irq();
} }
ssize_t SB16::write(FileDescription&, size_t, const u8* data, ssize_t length) KResultOr<size_t> SB16::write(FileDescription&, size_t, const u8* data, size_t length)
{ {
if (!m_dma_region) { if (!m_dma_region) {
auto page = MM.allocate_supervisor_physical_page(); auto page = MM.allocate_supervisor_physical_page();

View file

@ -46,8 +46,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* purpose() const override { return class_name(); } virtual const char* purpose() const override { return class_name(); }

View file

@ -45,7 +45,7 @@ bool SerialDevice::can_read(const FileDescription&, size_t) const
return (get_line_status() & DataReady) != 0; return (get_line_status() & DataReady) != 0;
} }
ssize_t SerialDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> SerialDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
if (!size) if (!size)
return 0; return 0;
@ -63,7 +63,7 @@ bool SerialDevice::can_write(const FileDescription&, size_t) const
return (get_line_status() & EmptyTransmitterHoldingRegister) != 0; return (get_line_status() & EmptyTransmitterHoldingRegister) != 0;
} }
ssize_t SerialDevice::write(FileDescription&, size_t, const u8* buffer, ssize_t size) KResultOr<size_t> SerialDevice::write(FileDescription&, size_t, const u8* buffer, size_t size)
{ {
if (!size) if (!size)
return 0; return 0;

View file

@ -43,9 +43,9 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
enum InterruptEnable { enum InterruptEnable {
LowPowerMode = 0x01 << 5, LowPowerMode = 0x01 << 5,

View file

@ -44,16 +44,16 @@ bool ZeroDevice::can_read(const FileDescription&, size_t) const
return true; return true;
} }
ssize_t ZeroDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> ZeroDevice::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
ssize_t count = min(static_cast<ssize_t>(PAGE_SIZE), size); ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
memset(buffer, 0, (size_t)count); memset(buffer, 0, count);
return count; return count;
} }
ssize_t ZeroDevice::write(FileDescription&, size_t, const u8*, ssize_t size) KResultOr<size_t> ZeroDevice::write(FileDescription&, size_t, const u8*, size_t size)
{ {
return min(static_cast<ssize_t>(PAGE_SIZE), size); return min(static_cast<size_t>(PAGE_SIZE), size);
} }
} }

View file

@ -38,8 +38,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual const char* class_name() const override { return "ZeroDevice"; } virtual const char* class_name() const override { return "ZeroDevice"; }

View file

@ -58,13 +58,13 @@ void DoubleBuffer::flip()
compute_lockfree_metadata(); compute_lockfree_metadata();
} }
ssize_t DoubleBuffer::write(const u8* data, ssize_t size) size_t DoubleBuffer::write(const u8* data, size_t size)
{ {
if (!size) if (!size)
return 0; return 0;
ASSERT(size > 0); ASSERT(size > 0);
LOCKER(m_lock); LOCKER(m_lock);
ssize_t bytes_to_write = min(static_cast<size_t>(size), m_space_for_writing); size_t bytes_to_write = min(size, m_space_for_writing);
u8* write_ptr = m_write_buffer->data + m_write_buffer->size; u8* write_ptr = m_write_buffer->data + m_write_buffer->size;
m_write_buffer->size += bytes_to_write; m_write_buffer->size += bytes_to_write;
compute_lockfree_metadata(); compute_lockfree_metadata();
@ -72,7 +72,7 @@ ssize_t DoubleBuffer::write(const u8* data, ssize_t size)
return bytes_to_write; return bytes_to_write;
} }
ssize_t DoubleBuffer::read(u8* data, ssize_t size) size_t DoubleBuffer::read(u8* data, size_t size)
{ {
if (!size) if (!size)
return 0; return 0;
@ -82,7 +82,7 @@ ssize_t DoubleBuffer::read(u8* data, ssize_t size)
flip(); flip();
if (m_read_buffer_index >= m_read_buffer->size) if (m_read_buffer_index >= m_read_buffer->size)
return 0; return 0;
ssize_t nread = min((ssize_t)m_read_buffer->size - (ssize_t)m_read_buffer_index, size); size_t nread = min(m_read_buffer->size - m_read_buffer_index, size);
memcpy(data, m_read_buffer->data + m_read_buffer_index, nread); memcpy(data, m_read_buffer->data + m_read_buffer_index, nread);
m_read_buffer_index += nread; m_read_buffer_index += nread;
compute_lockfree_metadata(); compute_lockfree_metadata();

View file

@ -36,8 +36,8 @@ class DoubleBuffer {
public: public:
explicit DoubleBuffer(size_t capacity = 65536); explicit DoubleBuffer(size_t capacity = 65536);
ssize_t write(const u8*, ssize_t); size_t write(const u8*, size_t);
ssize_t read(u8*, ssize_t); size_t read(u8*, size_t);
bool is_empty() const { return m_empty; } bool is_empty() const { return m_empty; }

View file

@ -132,9 +132,9 @@ bool BlockBasedFS::write_block(unsigned index, const u8* data, size_t count, siz
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + offset; u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + offset;
file_description().seek(base_offset, SEEK_SET); file_description().seek(base_offset, SEEK_SET);
auto nwritten = file_description().write(data, count); auto nwritten = file_description().write(data, count);
if (nwritten < 0) if (nwritten.is_error())
return false; return false;
ASSERT(static_cast<size_t>(nwritten) == count); ASSERT(nwritten.value() == count);
return true; return true;
} }
@ -156,7 +156,8 @@ bool BlockBasedFS::raw_read(unsigned index, u8* buffer)
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size); u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size);
file_description().seek(base_offset, SEEK_SET); file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(buffer, m_logical_block_size); auto nread = file_description().read(buffer, m_logical_block_size);
ASSERT((size_t)nread == m_logical_block_size); ASSERT(!nread.is_error());
ASSERT(nread.value() == m_logical_block_size);
return true; return true;
} }
bool BlockBasedFS::raw_write(unsigned index, const u8* buffer) bool BlockBasedFS::raw_write(unsigned index, const u8* buffer)
@ -164,7 +165,8 @@ bool BlockBasedFS::raw_write(unsigned index, const u8* buffer)
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size); u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size);
file_description().seek(base_offset, SEEK_SET); file_description().seek(base_offset, SEEK_SET);
auto nwritten = file_description().write(buffer, m_logical_block_size); auto nwritten = file_description().write(buffer, m_logical_block_size);
ASSERT((size_t)nwritten == m_logical_block_size); ASSERT(!nwritten.is_error());
ASSERT(nwritten.value() == m_logical_block_size);
return true; return true;
} }
@ -211,9 +213,9 @@ bool BlockBasedFS::read_block(unsigned index, u8* buffer, size_t count, size_t o
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + static_cast<u32>(offset); u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + static_cast<u32>(offset);
file_description().seek(base_offset, SEEK_SET); file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(buffer, count); auto nread = file_description().read(buffer, count);
if (nread < 0) if (nread.is_error())
return false; return false;
ASSERT(static_cast<size_t>(nread) == count); ASSERT(nread.value() == count);
return true; return true;
} }
@ -222,9 +224,9 @@ bool BlockBasedFS::read_block(unsigned index, u8* buffer, size_t count, size_t o
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()); u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size());
file_description().seek(base_offset, SEEK_SET); file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(entry.data, block_size()); auto nread = file_description().read(entry.data, block_size());
if (nread < 0) if (nread.is_error())
return false; return false;
ASSERT(static_cast<size_t>(nread) == block_size()); ASSERT(nread.value() == block_size());
entry.has_data = true; entry.has_data = true;
} }
if (buffer) if (buffer)

View file

@ -145,29 +145,19 @@ bool FIFO::can_write(const FileDescription&, size_t) const
return m_buffer.space_for_writing() || !m_readers; return m_buffer.space_for_writing() || !m_readers;
} }
ssize_t FIFO::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> FIFO::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
if (!m_writers && m_buffer.is_empty()) if (!m_writers && m_buffer.is_empty())
return 0; return 0;
#ifdef FIFO_DEBUG return m_buffer.read(buffer, size);
dbg() << "fifo: read(" << size << ")\n";
#endif
ssize_t nread = m_buffer.read(buffer, size);
#ifdef FIFO_DEBUG
dbg() << " -> read (" << String::format("%c", buffer[0]) << ") " << nread;
#endif
return nread;
} }
ssize_t FIFO::write(FileDescription&, size_t, const u8* buffer, ssize_t size) KResultOr<size_t> FIFO::write(FileDescription&, size_t, const u8* buffer, size_t size)
{ {
if (!m_readers) { if (!m_readers) {
Thread::current()->send_signal(SIGPIPE, Process::current()); Thread::current()->send_signal(SIGPIPE, Process::current());
return -EPIPE; return -EPIPE;
} }
#ifdef FIFO_DEBUG
dbg() << "fifo: write(" << (const void*)buffer << ", " << size << ")";
#endif
return m_buffer.write(buffer, size); return m_buffer.write(buffer, size);
} }

View file

@ -57,8 +57,8 @@ public:
private: private:
// ^File // ^File
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual String absolute_path(const FileDescription&) const override; virtual String absolute_path(const FileDescription&) const override;

View file

@ -74,8 +74,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const = 0; virtual bool can_read(const FileDescription&, size_t) const = 0;
virtual bool can_write(const FileDescription&, size_t) const = 0; virtual bool can_write(const FileDescription&, size_t) const = 0;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) = 0; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) = 0;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) = 0; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0;
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg); virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg);
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared); virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);

View file

@ -124,28 +124,32 @@ off_t FileDescription::seek(off_t offset, int whence)
return m_current_offset; return m_current_offset;
} }
ssize_t FileDescription::read(u8* buffer, ssize_t count) KResultOr<size_t> FileDescription::read(u8* buffer, size_t count)
{ {
LOCKER(m_lock); LOCKER(m_lock);
if ((m_current_offset + count) < 0) Checked<size_t> new_offset = m_current_offset;
new_offset += count;
if (new_offset.has_overflow())
return -EOVERFLOW; return -EOVERFLOW;
SmapDisabler disabler; SmapDisabler disabler;
int nread = m_file->read(*this, offset(), buffer, count); auto nread_or_error = m_file->read(*this, offset(), buffer, count);
if (nread > 0 && m_file->is_seekable()) if (!nread_or_error.is_error() && m_file->is_seekable())
m_current_offset += nread; m_current_offset += nread_or_error.value();
return nread; return nread_or_error;
} }
ssize_t FileDescription::write(const u8* data, ssize_t size) KResultOr<size_t> FileDescription::write(const u8* data, size_t size)
{ {
LOCKER(m_lock); LOCKER(m_lock);
if ((m_current_offset + size) < 0) Checked<size_t> new_offset = m_current_offset;
new_offset += size;
if (new_offset.has_overflow())
return -EOVERFLOW; return -EOVERFLOW;
SmapDisabler disabler; SmapDisabler disabler;
int nwritten = m_file->write(*this, offset(), data, size); auto nwritten_or_error = m_file->write(*this, offset(), data, size);
if (nwritten > 0 && m_file->is_seekable()) if (!nwritten_or_error.is_error() && m_file->is_seekable())
m_current_offset += nwritten; m_current_offset += nwritten_or_error.value();
return nwritten; return nwritten_or_error;
} }
bool FileDescription::can_write() const bool FileDescription::can_write() const

View file

@ -60,8 +60,8 @@ public:
KResult close(); KResult close();
off_t seek(off_t, int whence); off_t seek(off_t, int whence);
ssize_t read(u8*, ssize_t); KResultOr<size_t> read(u8*, size_t);
ssize_t write(const u8* data, ssize_t); KResultOr<size_t> write(const u8* data, size_t);
KResult fstat(stat&); KResult fstat(stat&);
KResult chmod(mode_t); KResult chmod(mode_t);

View file

@ -44,21 +44,25 @@ InodeFile::~InodeFile()
{ {
} }
ssize_t InodeFile::read(FileDescription& description, size_t offset, u8* buffer, ssize_t count) KResultOr<size_t> InodeFile::read(FileDescription& description, size_t offset, u8* buffer, size_t count)
{ {
ssize_t nread = m_inode->read_bytes(offset, count, buffer, &description); ssize_t nread = m_inode->read_bytes(offset, count, buffer, &description);
if (nread > 0) if (nread > 0)
Thread::current()->did_file_read(nread); Thread::current()->did_file_read(nread);
if (nread < 0)
return KResult(nread);
return nread; return nread;
} }
ssize_t InodeFile::write(FileDescription& description, size_t offset, const u8* data, ssize_t count) KResultOr<size_t> InodeFile::write(FileDescription& description, size_t offset, const u8* data, size_t count)
{ {
ssize_t nwritten = m_inode->write_bytes(offset, count, data, &description); ssize_t nwritten = m_inode->write_bytes(offset, count, data, &description);
if (nwritten > 0) { if (nwritten > 0) {
m_inode->set_mtime(kgettimeofday().tv_sec); m_inode->set_mtime(kgettimeofday().tv_sec);
Thread::current()->did_file_write(nwritten); Thread::current()->did_file_write(nwritten);
} }
if (nwritten < 0)
return KResult(nwritten);
return nwritten; return nwritten;
} }

View file

@ -47,8 +47,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const override { return true; } virtual bool can_read(const FileDescription&, size_t) const override { return true; }
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override; virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override;
virtual String absolute_path(const FileDescription&) const override; virtual String absolute_path(const FileDescription&) const override;

View file

@ -57,7 +57,7 @@ bool InodeWatcher::can_write(const FileDescription&, size_t) const
return true; return true;
} }
ssize_t InodeWatcher::read(FileDescription&, size_t, u8* buffer, ssize_t buffer_size) KResultOr<size_t> InodeWatcher::read(FileDescription&, size_t, u8* buffer, size_t buffer_size)
{ {
LOCKER(m_lock); LOCKER(m_lock);
ASSERT(!m_queue.is_empty() || !m_inode); ASSERT(!m_queue.is_empty() || !m_inode);
@ -72,9 +72,9 @@ ssize_t InodeWatcher::read(FileDescription&, size_t, u8* buffer, ssize_t buffer_
return sizeof(event); return sizeof(event);
} }
ssize_t InodeWatcher::write(FileDescription&, size_t, const u8*, ssize_t) KResultOr<size_t> InodeWatcher::write(FileDescription&, size_t, const u8*, size_t)
{ {
return -EIO; return KResult(-EIO);
} }
String InodeWatcher::absolute_path(const FileDescription&) const String InodeWatcher::absolute_path(const FileDescription&) const

View file

@ -55,8 +55,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual String absolute_path(const FileDescription&) const override; virtual String absolute_path(const FileDescription&) const override;
virtual const char* class_name() const override { return "InodeWatcher"; }; virtual const char* class_name() const override { return "InodeWatcher"; };

View file

@ -426,9 +426,10 @@ KResult Plan9FS::post_message(Message& message)
if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted()) if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted())
return KResult(-EINTR); return KResult(-EINTR);
} }
ssize_t nwritten = description.write(data, size); auto nwritten_or_error = description.write(data, size);
if (nwritten < 0) if (nwritten_or_error.is_error())
return KResult(nwritten); return nwritten_or_error.error();
auto nwritten = nwritten_or_error.value();
data += nwritten; data += nwritten;
size -= nwritten; size -= nwritten;
} }
@ -444,9 +445,10 @@ KResult Plan9FS::do_read(u8* data, size_t size)
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted()) if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted())
return KResult(-EINTR); return KResult(-EINTR);
} }
ssize_t nread = description.read(data, size); auto nread_or_error = description.read(data, size);
if (nread < 0) if (nread_or_error.is_error())
return KResult(nread); return nread_or_error.error();
auto nread = nread_or_error.value();
if (nread == 0) if (nread == 0)
return KResult(-EIO); return KResult(-EIO);
data += nread; data += nread;

View file

@ -193,16 +193,16 @@ int IPv4Socket::allocate_local_port_if_needed()
return port; return port;
} }
ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, const sockaddr* addr, socklen_t addr_length) KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, const sockaddr* addr, socklen_t addr_length)
{ {
(void)flags; (void)flags;
if (addr && addr_length != sizeof(sockaddr_in)) if (addr && addr_length != sizeof(sockaddr_in))
return -EINVAL; return KResult(-EINVAL);
if (addr) { if (addr) {
if (addr->sa_family != AF_INET) { if (addr->sa_family != AF_INET) {
klog() << "sendto: Bad address family: " << addr->sa_family << " is not AF_INET!"; klog() << "sendto: Bad address family: " << addr->sa_family << " is not AF_INET!";
return -EAFNOSUPPORT; return KResult(-EAFNOSUPPORT);
} }
auto& ia = *(const sockaddr_in*)addr; auto& ia = *(const sockaddr_in*)addr;
@ -212,7 +212,7 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt
auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface()); auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface());
if (routing_decision.is_zero()) if (routing_decision.is_zero())
return -EHOSTUNREACH; return KResult(-EHOSTUNREACH);
if (m_local_address.to_u32() == 0) if (m_local_address.to_u32() == 0)
m_local_address = routing_decision.adapter->ipv4_address(); m_local_address = routing_decision.adapter->ipv4_address();
@ -230,20 +230,20 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt
return data_length; return data_length;
} }
int nsent = protocol_send(data, data_length); auto nsent_or_error = protocol_send(data, data_length);
if (nsent > 0) if (!nsent_or_error.is_error())
Thread::current()->did_ipv4_socket_write(nsent); Thread::current()->did_ipv4_socket_write(nsent_or_error.value());
return nsent; return nsent_or_error;
} }
ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*) KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*)
{ {
Locker locker(lock()); Locker locker(lock());
if (m_receive_buffer.is_empty()) { if (m_receive_buffer.is_empty()) {
if (protocol_is_disconnected()) if (protocol_is_disconnected())
return 0; return 0;
if (!description.is_blocking()) if (!description.is_blocking())
return -EAGAIN; return KResult(-EAGAIN);
locker.unlock(); locker.unlock();
auto res = Thread::current()->block<Thread::ReadBlocker>(nullptr, description); auto res = Thread::current()->block<Thread::ReadBlocker>(nullptr, description);
@ -251,10 +251,10 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu
if (!m_can_read) { if (!m_can_read) {
if (res.was_interrupted()) if (res.was_interrupted())
return -EINTR; return KResult(-EINTR);
// Unblocked due to timeout. // Unblocked due to timeout.
return -EAGAIN; return KResult(-EAGAIN);
} }
} }
@ -267,7 +267,7 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu
return nreceived; return nreceived;
} }
ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length) KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
{ {
Locker locker(lock()); Locker locker(lock());
ReceivedPacket packet; ReceivedPacket packet;
@ -278,7 +278,7 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
if (protocol_is_disconnected()) if (protocol_is_disconnected())
return 0; return 0;
if (!description.is_blocking()) if (!description.is_blocking())
return -EAGAIN; return KResult(-EAGAIN);
} }
if (!m_receive_queue.is_empty()) { if (!m_receive_queue.is_empty()) {
@ -301,10 +301,10 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
if (!m_can_read) { if (!m_can_read) {
if (res.was_interrupted()) if (res.was_interrupted())
return -EINTR; return KResult(-EINTR);
// Unblocked due to timeout. // Unblocked due to timeout.
return -EAGAIN; return KResult(-EAGAIN);
} }
ASSERT(m_can_read); ASSERT(m_can_read);
ASSERT(!m_receive_queue.is_empty()); ASSERT(!m_receive_queue.is_empty());
@ -338,23 +338,23 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
return protocol_receive(packet.data.value(), buffer, buffer_length, flags); return protocol_receive(packet.data.value(), buffer, buffer_length, flags);
} }
ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length) KResultOr<size_t> IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
{ {
if (addr_length && *addr_length < sizeof(sockaddr_in)) if (addr_length && *addr_length < sizeof(sockaddr_in))
return -EINVAL; return KResult(-EINVAL);
#ifdef IPV4_SOCKET_DEBUG #ifdef IPV4_SOCKET_DEBUG
klog() << "recvfrom: type=" << type() << ", local_port=" << local_port(); klog() << "recvfrom: type=" << type() << ", local_port=" << local_port();
#endif #endif
ssize_t nreceived = 0; KResultOr<size_t> nreceived = 0;
if (buffer_mode() == BufferMode::Bytes) if (buffer_mode() == BufferMode::Bytes)
nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, addr, addr_length); nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, addr, addr_length);
else else
nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, addr, addr_length); nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, addr, addr_length);
if (nreceived > 0) if (!nreceived.is_error())
Thread::current()->did_ipv4_socket_read(nreceived); Thread::current()->did_ipv4_socket_read(nreceived.value());
return nreceived; return nreceived;
} }
@ -374,8 +374,10 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
ASSERT(m_can_read); ASSERT(m_can_read);
return false; return false;
} }
int nreceived = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0); auto nreceived_or_error = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0);
m_receive_buffer.write(m_scratch_buffer.value().data(), nreceived); if (nreceived_or_error.is_error())
return false;
m_receive_buffer.write(m_scratch_buffer.value().data(), nreceived_or_error.value());
m_can_read = !m_receive_buffer.is_empty(); m_can_read = !m_receive_buffer.is_empty();
} else { } else {
// FIXME: Maybe track the number of packets so we don't have to walk the entire packet queue to count them.. // FIXME: Maybe track the number of packets so we don't have to walk the entire packet queue to count them..

View file

@ -58,8 +58,8 @@ public:
virtual void detach(FileDescription&) override; virtual void detach(FileDescription&) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override; virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override; virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResult setsockopt(int level, int option, const void*, socklen_t) override; virtual KResult setsockopt(int level, int option, const void*, socklen_t) override;
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override; virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override;
@ -96,8 +96,8 @@ protected:
virtual KResult protocol_bind() { return KSuccess; } virtual KResult protocol_bind() { return KSuccess; }
virtual KResult protocol_listen() { return KSuccess; } virtual KResult protocol_listen() { return KSuccess; }
virtual int protocol_receive(const KBuffer&, void*, size_t, int) { return -ENOTIMPL; } virtual KResultOr<size_t> protocol_receive(const KBuffer&, void*, size_t, int) { return -ENOTIMPL; }
virtual int protocol_send(const void*, size_t) { return -ENOTIMPL; } virtual KResultOr<size_t> protocol_send(const void*, size_t) { return -ENOTIMPL; }
virtual KResult protocol_connect(FileDescription&, ShouldBlock) { return KSuccess; } virtual KResult protocol_connect(FileDescription&, ShouldBlock) { return KSuccess; }
virtual int protocol_allocate_local_port() { return 0; } virtual int protocol_allocate_local_port() { return 0; }
virtual bool protocol_is_disconnected() const { return false; } virtual bool protocol_is_disconnected() const { return false; }
@ -110,8 +110,8 @@ protected:
private: private:
virtual bool is_ipv4() const override { return true; } virtual bool is_ipv4() const override { return true; }
ssize_t receive_byte_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*); KResultOr<size_t> receive_byte_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
ssize_t receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*); KResultOr<size_t> receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
IPv4Address m_local_address; IPv4Address m_local_address;
IPv4Address m_peer_address; IPv4Address m_peer_address;

View file

@ -260,10 +260,10 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const
return false; return false;
} }
ssize_t LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, const sockaddr*, socklen_t) KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, const sockaddr*, socklen_t)
{ {
if (!has_attached_peer(description)) if (!has_attached_peer(description))
return -EPIPE; return KResult(-EPIPE);
ssize_t nwritten = send_buffer_for(description).write((const u8*)data, data_size); ssize_t nwritten = send_buffer_for(description).write((const u8*)data, data_size);
if (nwritten > 0) if (nwritten > 0)
Thread::current()->did_unix_socket_write(nwritten); Thread::current()->did_unix_socket_write(nwritten);
@ -290,18 +290,18 @@ DoubleBuffer& LocalSocket::send_buffer_for(FileDescription& description)
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
ssize_t LocalSocket::recvfrom(FileDescription& description, void* buffer, size_t buffer_size, int, sockaddr*, socklen_t*) KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, void* buffer, size_t buffer_size, int, sockaddr*, socklen_t*)
{ {
auto& buffer_for_me = receive_buffer_for(description); auto& buffer_for_me = receive_buffer_for(description);
if (!description.is_blocking()) { if (!description.is_blocking()) {
if (buffer_for_me.is_empty()) { if (buffer_for_me.is_empty()) {
if (!has_attached_peer(description)) if (!has_attached_peer(description))
return 0; return 0;
return -EAGAIN; return KResult(-EAGAIN);
} }
} else if (!can_read(description, 0)) { } else if (!can_read(description, 0)) {
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted()) if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted())
return -EINTR; return KResult(-EINTR);
} }
if (!has_attached_peer(description) && buffer_for_me.is_empty()) if (!has_attached_peer(description) && buffer_for_me.is_empty())
return 0; return 0;

View file

@ -60,8 +60,8 @@ public:
virtual void detach(FileDescription&) override; virtual void detach(FileDescription&) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override; virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override; virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override; virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override;
virtual KResult chown(FileDescription&, uid_t, gid_t) override; virtual KResult chown(FileDescription&, uid_t, gid_t) override;
virtual KResult chmod(FileDescription&, mode_t) override; virtual KResult chmod(FileDescription&, mode_t) override;

View file

@ -178,14 +178,14 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, void* value,
} }
} }
ssize_t Socket::read(FileDescription& description, size_t, u8* buffer, ssize_t size) KResultOr<size_t> Socket::read(FileDescription& description, size_t, u8* buffer, size_t size)
{ {
if (is_shut_down_for_reading()) if (is_shut_down_for_reading())
return 0; return 0;
return recvfrom(description, buffer, size, 0, nullptr, 0); return recvfrom(description, buffer, size, 0, nullptr, 0);
} }
ssize_t Socket::write(FileDescription& description, size_t, const u8* data, ssize_t size) KResultOr<size_t> Socket::write(FileDescription& description, size_t, const u8* data, size_t size)
{ {
if (is_shut_down_for_writing()) if (is_shut_down_for_writing())
return -EPIPE; return -EPIPE;

View file

@ -107,8 +107,8 @@ public:
virtual bool is_ipv4() const { return false; } virtual bool is_ipv4() const { return false; }
virtual void attach(FileDescription&) = 0; virtual void attach(FileDescription&) = 0;
virtual void detach(FileDescription&) = 0; virtual void detach(FileDescription&) = 0;
virtual ssize_t sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0; virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0;
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0; virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0;
virtual KResult setsockopt(int level, int option, const void*, socklen_t); virtual KResult setsockopt(int level, int option, const void*, socklen_t);
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*); virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*);
@ -124,8 +124,8 @@ public:
Lock& lock() { return m_lock; } Lock& lock() { return m_lock; }
// ^File // ^File
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override final; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override final; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final;
virtual String absolute_path(const FileDescription&) const override = 0; virtual String absolute_path(const FileDescription&) const override = 0;
bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; } bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; }

View file

@ -161,7 +161,7 @@ NonnullRefPtr<TCPSocket> TCPSocket::create(int protocol)
return adopt(*new TCPSocket(protocol)); return adopt(*new TCPSocket(protocol));
} }
int TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags) KResultOr<size_t> TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
{ {
(void)flags; (void)flags;
auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data()); auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data());
@ -175,7 +175,7 @@ int TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size
return payload_size; return payload_size;
} }
int TCPSocket::protocol_send(const void* data, size_t data_length) KResultOr<size_t> TCPSocket::protocol_send(const void* data, size_t data_length)
{ {
send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, data, data_length); send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, data, data_length);
return data_length; return data_length;

View file

@ -178,8 +178,8 @@ private:
virtual void shut_down_for_writing() override; virtual void shut_down_for_writing() override;
virtual int protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override; virtual KResultOr<size_t> protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
virtual int protocol_send(const void*, size_t) override; virtual KResultOr<size_t> protocol_send(const void*, size_t) override;
virtual KResult protocol_connect(FileDescription&, ShouldBlock) override; virtual KResult protocol_connect(FileDescription&, ShouldBlock) override;
virtual int protocol_allocate_local_port() override; virtual int protocol_allocate_local_port() override;
virtual bool protocol_is_disconnected() const override; virtual bool protocol_is_disconnected() const override;

View file

@ -79,7 +79,7 @@ NonnullRefPtr<UDPSocket> UDPSocket::create(int protocol)
return adopt(*new UDPSocket(protocol)); return adopt(*new UDPSocket(protocol));
} }
int UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags) KResultOr<size_t> UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
{ {
(void)flags; (void)flags;
auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data()); auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data());
@ -90,11 +90,11 @@ int UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size
return udp_packet.length() - sizeof(UDPPacket); return udp_packet.length() - sizeof(UDPPacket);
} }
int UDPSocket::protocol_send(const void* data, size_t data_length) KResultOr<size_t> UDPSocket::protocol_send(const void* data, size_t data_length)
{ {
auto routing_decision = route_to(peer_address(), local_address(), bound_interface()); auto routing_decision = route_to(peer_address(), local_address(), bound_interface());
if (routing_decision.is_zero()) if (routing_decision.is_zero())
return -EHOSTUNREACH; return KResult(-EHOSTUNREACH);
auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length); auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length);
auto& udp_packet = *(UDPPacket*)(buffer.data()); auto& udp_packet = *(UDPPacket*)(buffer.data());
udp_packet.set_source_port(local_port()); udp_packet.set_source_port(local_port());

View file

@ -43,8 +43,8 @@ private:
virtual const char* class_name() const override { return "UDPSocket"; } virtual const char* class_name() const override { return "UDPSocket"; }
static Lockable<HashMap<u16, UDPSocket*>>& sockets_by_port(); static Lockable<HashMap<u16, UDPSocket*>>& sockets_by_port();
virtual int protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override; virtual KResultOr<size_t> protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
virtual int protocol_send(const void*, size_t) override; virtual KResultOr<size_t> protocol_send(const void*, size_t) override;
virtual KResult protocol_connect(FileDescription&, ShouldBlock) override; virtual KResult protocol_connect(FileDescription&, ShouldBlock) override;
virtual int protocol_allocate_local_port() override; virtual int protocol_allocate_local_port() override;
virtual KResult protocol_bind() override; virtual KResult protocol_bind() override;

View file

@ -418,7 +418,10 @@ KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_exec
return KResult(-ENOEXEC); return KResult(-ENOEXEC);
memset(first_page, 0, sizeof(first_page)); memset(first_page, 0, sizeof(first_page));
nread = interpreter_description->read((u8*)&first_page, sizeof(first_page)); auto nread_or_error = interpreter_description->read((u8*)&first_page, sizeof(first_page));
if (nread_or_error.is_error())
return KResult(-ENOEXEC);
nread = nread_or_error.value();
if (nread < (int)sizeof(Elf32_Ehdr)) if (nread < (int)sizeof(Elf32_Ehdr))
return KResult(-ENOEXEC); return KResult(-ENOEXEC);
@ -482,10 +485,12 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
// Read the first page of the program into memory so we can validate the binfmt of it // Read the first page of the program into memory so we can validate the binfmt of it
char first_page[PAGE_SIZE]; char first_page[PAGE_SIZE];
int nread = description->read((u8*)&first_page, sizeof(first_page)); auto nread_or_error = description->read((u8*)&first_page, sizeof(first_page));
if (nread_or_error.is_error())
return -ENOEXEC;
// 1) #! interpreted file // 1) #! interpreted file
auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread); auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread_or_error.value());
if (!shebang_result.is_error()) { if (!shebang_result.is_error()) {
Vector<String> new_arguments(shebang_result.value()); Vector<String> new_arguments(shebang_result.value());
@ -498,7 +503,7 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
} }
// #2) ELF32 for i386 // #2) ELF32 for i386
auto elf_result = find_elf_interpreter_for_executable(path, first_page, nread, metadata.size); auto elf_result = find_elf_interpreter_for_executable(path, first_page, nread_or_error.value(), metadata.size);
RefPtr<FileDescription> interpreter_description; RefPtr<FileDescription> interpreter_description;
// We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out) // We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out)
if (!elf_result.is_error()) if (!elf_result.is_error())

View file

@ -56,8 +56,10 @@ ssize_t Process::sys$read(int fd, Userspace<u8*> buffer, ssize_t size)
return -EAGAIN; return -EAGAIN;
} }
} }
// FIXME: We should have a read() that takes a Userspace<u8*> auto result = description->read(buffer.unsafe_userspace_ptr(), size);
return description->read(buffer.unsafe_userspace_ptr(), size); if (result.is_error())
return result.error();
return result.value();
} }
} }

View file

@ -211,7 +211,10 @@ ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
if (socket.is_shut_down_for_writing()) if (socket.is_shut_down_for_writing())
return -EPIPE; return -EPIPE;
SmapDisabler disabler; SmapDisabler disabler;
return socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length); auto result = socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
if (result.is_error())
return result.error();
return result.value();
} }
ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params) ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
@ -251,11 +254,13 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
if (flags & MSG_DONTWAIT) if (flags & MSG_DONTWAIT)
description->set_blocking(false); description->set_blocking(false);
auto nrecv = socket.recvfrom(*description, params.buffer.data, params.buffer.size, flags, addr, addr_length); auto result = socket.recvfrom(*description, params.buffer.data, params.buffer.size, flags, addr, addr_length);
if (flags & MSG_DONTWAIT) if (flags & MSG_DONTWAIT)
description->set_blocking(original_blocking); description->set_blocking(original_blocking);
return nrecv; if (result.is_error())
return result.error();
return result.value();
} }
template<bool sockname, typename Params> template<bool sockname, typename Params>

View file

@ -74,51 +74,38 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
ssize_t Process::do_write(FileDescription& description, const u8* data, int data_size) ssize_t Process::do_write(FileDescription& description, const u8* data, int data_size)
{ {
ssize_t nwritten = 0; ssize_t total_nwritten = 0;
if (!description.is_blocking()) { if (!description.is_blocking()) {
if (!description.can_write()) if (!description.can_write())
return -EAGAIN; return -EAGAIN;
} }
if (description.should_append()) { if (description.should_append())
#ifdef IO_DEBUG
dbg() << "seeking to end (O_APPEND)";
#endif
description.seek(0, SEEK_END); description.seek(0, SEEK_END);
}
while (nwritten < data_size) { while (total_nwritten < data_size) {
#ifdef IO_DEBUG
dbg() << "while " << nwritten << " < " << size;
#endif
if (!description.can_write()) { if (!description.can_write()) {
if (!description.is_blocking()) { if (!description.is_blocking()) {
// Short write: We can no longer write to this non-blocking description. // Short write: We can no longer write to this non-blocking description.
ASSERT(nwritten > 0); ASSERT(total_nwritten > 0);
return nwritten; return total_nwritten;
} }
#ifdef IO_DEBUG
dbg() << "block write on " << description.absolute_path();
#endif
if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted()) { if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted()) {
if (nwritten == 0) if (total_nwritten == 0)
return -EINTR; return -EINTR;
} }
} }
ssize_t rc = description.write(data + nwritten, data_size - nwritten); auto nwritten_or_error = description.write(data + total_nwritten, data_size - total_nwritten);
#ifdef IO_DEBUG if (nwritten_or_error.is_error()) {
dbg() << " -> write returned " << rc; if (total_nwritten)
#endif return total_nwritten;
if (rc < 0) { return nwritten_or_error.error();
if (nwritten)
return nwritten;
return rc;
} }
if (rc == 0) if (nwritten_or_error.value() == 0)
break; break;
nwritten += rc; total_nwritten += nwritten_or_error.value();
} }
return nwritten; return total_nwritten;
} }
ssize_t Process::sys$write(int fd, const u8* data, ssize_t size) ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)

View file

@ -60,17 +60,17 @@ String MasterPTY::pts_name() const
return m_pts_name; return m_pts_name;
} }
ssize_t MasterPTY::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> MasterPTY::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
if (!m_slave && m_buffer.is_empty()) if (!m_slave && m_buffer.is_empty())
return 0; return 0;
return m_buffer.read(buffer, size); return m_buffer.read(buffer, size);
} }
ssize_t MasterPTY::write(FileDescription&, size_t, const u8* buffer, ssize_t size) KResultOr<size_t> MasterPTY::write(FileDescription&, size_t, const u8* buffer, size_t size)
{ {
if (!m_slave) if (!m_slave)
return -EIO; return KResult(-EIO);
m_slave->on_master_write(buffer, size); m_slave->on_master_write(buffer, size);
return size; return size;
} }

View file

@ -50,8 +50,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual KResult close() override; virtual KResult close() override;

View file

@ -44,8 +44,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual KResultOr<NonnullRefPtr<FileDescription>> open(int options) override; virtual KResultOr<NonnullRefPtr<FileDescription>> open(int options) override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override { return 0; } virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override { return 0; }
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return 0; } virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override { return 0; }
virtual bool can_read(const FileDescription&, size_t) const override { return true; } virtual bool can_read(const FileDescription&, size_t) const override { return true; }
virtual bool can_write(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return true; }

View file

@ -89,7 +89,7 @@ bool SlavePTY::can_read(const FileDescription& description, size_t offset) const
return TTY::can_read(description, offset); return TTY::can_read(description, offset);
} }
ssize_t SlavePTY::read(FileDescription& description, size_t offset, u8* buffer, ssize_t size) KResultOr<size_t> SlavePTY::read(FileDescription& description, size_t offset, u8* buffer, size_t size)
{ {
if (m_master->is_closed()) if (m_master->is_closed())
return 0; return 0;

View file

@ -48,7 +48,7 @@ private:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual const char* class_name() const override { return "SlavePTY"; } virtual const char* class_name() const override { return "SlavePTY"; }
virtual KResult close() override; virtual KResult close() override;

View file

@ -52,15 +52,13 @@ void TTY::set_default_termios()
memcpy(m_termios.c_cc, default_cc, sizeof(default_cc)); memcpy(m_termios.c_cc, default_cc, sizeof(default_cc));
} }
ssize_t TTY::read(FileDescription&, size_t, u8* buffer, ssize_t size) KResultOr<size_t> TTY::read(FileDescription&, size_t, u8* buffer, size_t size)
{ {
ASSERT(size >= 0);
if (m_input_buffer.size() < static_cast<size_t>(size)) if (m_input_buffer.size() < static_cast<size_t>(size))
size = m_input_buffer.size(); size = m_input_buffer.size();
if (in_canonical_mode()) { if (in_canonical_mode()) {
int i = 0; size_t i = 0;
for (; i < size; i++) { for (; i < size; i++) {
u8 ch = m_input_buffer.dequeue(); u8 ch = m_input_buffer.dequeue();
if (ch == '\0') { if (ch == '\0') {
@ -79,21 +77,14 @@ ssize_t TTY::read(FileDescription&, size_t, u8* buffer, ssize_t size)
return i; return i;
} }
for (int i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
buffer[i] = m_input_buffer.dequeue(); buffer[i] = m_input_buffer.dequeue();
return size; return size;
} }
ssize_t TTY::write(FileDescription&, size_t, const u8* buffer, ssize_t size) KResultOr<size_t> TTY::write(FileDescription&, size_t, const u8* buffer, size_t size)
{ {
#ifdef TTY_DEBUG
dbg() << "TTY::write {" << String::format("%u", size) << "} ";
for (size_t i = 0; i < size; ++i) {
dbg() << String::format("%b ", buffer[i]);
}
dbg() << "";
#endif
on_tty_write(buffer, size); on_tty_write(buffer, size);
return size; return size;
} }

View file

@ -39,8 +39,8 @@ class TTY : public CharacterDevice {
public: public:
virtual ~TTY() override; virtual ~TTY() override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override; virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override; virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override; virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override; virtual bool can_write(const FileDescription&, size_t) const override;
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override final; virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override final;