1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +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;
}
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.
// Maybe we could use a ring buffer for this device?
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)
return 0;
for (ssize_t i = 0; i < size; ++i)
for (size_t i = 0; i < size; ++i)
put_char(data[i]);
return size;
}

View file

@ -42,8 +42,8 @@ public:
// ^CharacterDevice
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 ssize_t read(Kernel::FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(Kernel::FileDescription&, size_t, const u8*, ssize_t) override;
virtual Kernel::KResultOr<size_t> read(Kernel::FileDescription&, size_t, u8*, size_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"; }
void put_char(char);

View file

@ -47,8 +47,8 @@ private:
virtual const char* class_name() const override { return "BXVGA"; }
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 ssize_t read(FileDescription&, size_t, u8*, ssize_t) override { return -EINVAL; }
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return -EINVAL; }
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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 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();
@ -70,7 +70,7 @@ bool DiskPartition::can_read(const FileDescription& fd, size_t offset) const
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();

View file

@ -40,9 +40,9 @@ public:
virtual bool write_blocks(unsigned index, u16 count, const u8*) override;
// ^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 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;
private:

View file

@ -46,18 +46,18 @@ bool FullDevice::can_read(const FileDescription&, size_t) const
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);
memset(buffer, 0, (size_t)count);
ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
memset(buffer, 0, 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)
return 0;
return -ENOSPC;
return KResult(-ENOSPC);
}
}

View file

@ -38,8 +38,8 @@ public:
private:
// ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_write(const FileDescription&, size_t) const override { return true; }
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();
}
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) {
if (m_queue.is_empty())
break;
@ -382,7 +382,7 @@ ssize_t KeyboardDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size)
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;
}

View file

@ -54,9 +54,9 @@ public:
void set_maps(Keyboard::CharacterMapData character_map);
// ^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 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 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 bool can_read(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 ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return -EINVAL; }
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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 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;
}
ssize_t NullDevice::read(FileDescription&, size_t, u8*, ssize_t)
KResultOr<size_t> NullDevice::read(FileDescription&, size_t, u8*, size_t)
{
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:
// ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_read(const FileDescription&, size_t) const override;
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;
}
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();
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());
}
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();
u16 whole_blocks = len / block_size();

View file

@ -61,9 +61,9 @@ public:
void set_drive_geometry(u16, u16, u16);
// ^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 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;
protected:

View file

@ -324,7 +324,7 @@ bool PS2MouseDevice::can_read(const FileDescription&, size_t) const
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);
size_t nread = 0;
@ -344,7 +344,7 @@ ssize_t PS2MouseDevice::read(FileDescription&, size_t, u8* buffer, ssize_t size)
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;
}

View file

@ -44,8 +44,8 @@ public:
// ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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 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;
}
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);
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?
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:
// ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_write(const FileDescription&, size_t) const override { return true; }
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;
}
ssize_t SB16::read(FileDescription&, size_t, u8*, ssize_t)
KResultOr<size_t> SB16::read(FileDescription&, size_t, u8*, size_t)
{
return 0;
}
@ -226,7 +226,7 @@ void SB16::wait_for_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) {
auto page = MM.allocate_supervisor_physical_page();

View file

@ -46,8 +46,8 @@ public:
// ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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 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;
}
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)
return 0;
@ -63,7 +63,7 @@ bool SerialDevice::can_write(const FileDescription&, size_t) const
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)
return 0;

View file

@ -43,9 +43,9 @@ public:
// ^CharacterDevice
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 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 {
LowPowerMode = 0x01 << 5,

View file

@ -44,16 +44,16 @@ bool ZeroDevice::can_read(const FileDescription&, size_t) const
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);
memset(buffer, 0, (size_t)count);
ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
memset(buffer, 0, 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:
// ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_write(const FileDescription&, size_t) const override { return true; }
virtual const char* class_name() const override { return "ZeroDevice"; }

View file

@ -58,13 +58,13 @@ void DoubleBuffer::flip()
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)
return 0;
ASSERT(size > 0);
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;
m_write_buffer->size += bytes_to_write;
compute_lockfree_metadata();
@ -72,7 +72,7 @@ ssize_t DoubleBuffer::write(const u8* data, ssize_t size)
return bytes_to_write;
}
ssize_t DoubleBuffer::read(u8* data, ssize_t size)
size_t DoubleBuffer::read(u8* data, size_t size)
{
if (!size)
return 0;
@ -82,7 +82,7 @@ ssize_t DoubleBuffer::read(u8* data, ssize_t size)
flip();
if (m_read_buffer_index >= m_read_buffer->size)
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);
m_read_buffer_index += nread;
compute_lockfree_metadata();

View file

@ -36,8 +36,8 @@ class DoubleBuffer {
public:
explicit DoubleBuffer(size_t capacity = 65536);
ssize_t write(const u8*, ssize_t);
ssize_t read(u8*, ssize_t);
size_t write(const u8*, size_t);
size_t read(u8*, size_t);
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;
file_description().seek(base_offset, SEEK_SET);
auto nwritten = file_description().write(data, count);
if (nwritten < 0)
if (nwritten.is_error())
return false;
ASSERT(static_cast<size_t>(nwritten) == count);
ASSERT(nwritten.value() == count);
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);
file_description().seek(base_offset, SEEK_SET);
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;
}
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);
file_description().seek(base_offset, SEEK_SET);
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;
}
@ -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);
file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(buffer, count);
if (nread < 0)
if (nread.is_error())
return false;
ASSERT(static_cast<size_t>(nread) == count);
ASSERT(nread.value() == count);
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());
file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(entry.data, block_size());
if (nread < 0)
if (nread.is_error())
return false;
ASSERT(static_cast<size_t>(nread) == block_size());
ASSERT(nread.value() == block_size());
entry.has_data = true;
}
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;
}
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())
return 0;
#ifdef FIFO_DEBUG
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;
return m_buffer.read(buffer, size);
}
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) {
Thread::current()->send_signal(SIGPIPE, Process::current());
return -EPIPE;
}
#ifdef FIFO_DEBUG
dbg() << "fifo: write(" << (const void*)buffer << ", " << size << ")";
#endif
return m_buffer.write(buffer, size);
}

View file

@ -57,8 +57,8 @@ public:
private:
// ^File
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_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_write(const FileDescription&, size_t) 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_write(const FileDescription&, size_t) const = 0;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) = 0;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) = 0;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) = 0;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0;
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);

View file

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

View file

@ -60,8 +60,8 @@ public:
KResult close();
off_t seek(off_t, int whence);
ssize_t read(u8*, ssize_t);
ssize_t write(const u8* data, ssize_t);
KResultOr<size_t> read(u8*, size_t);
KResultOr<size_t> write(const u8* data, size_t);
KResult fstat(stat&);
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);
if (nread > 0)
Thread::current()->did_file_read(nread);
if (nread < 0)
return KResult(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);
if (nwritten > 0) {
m_inode->set_mtime(kgettimeofday().tv_sec);
Thread::current()->did_file_write(nwritten);
}
if (nwritten < 0)
return KResult(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_write(const FileDescription&, size_t) const override { return true; }
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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 String absolute_path(const FileDescription&) const override;

View file

@ -57,7 +57,7 @@ bool InodeWatcher::can_write(const FileDescription&, size_t) const
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);
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);
}
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

View file

@ -55,8 +55,8 @@ public:
virtual bool can_read(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 ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual String absolute_path(const FileDescription&) const override;
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())
return KResult(-EINTR);
}
ssize_t nwritten = description.write(data, size);
if (nwritten < 0)
return KResult(nwritten);
auto nwritten_or_error = description.write(data, size);
if (nwritten_or_error.is_error())
return nwritten_or_error.error();
auto nwritten = nwritten_or_error.value();
data += 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())
return KResult(-EINTR);
}
ssize_t nread = description.read(data, size);
if (nread < 0)
return KResult(nread);
auto nread_or_error = description.read(data, size);
if (nread_or_error.is_error())
return nread_or_error.error();
auto nread = nread_or_error.value();
if (nread == 0)
return KResult(-EIO);
data += nread;

View file

@ -193,16 +193,16 @@ int IPv4Socket::allocate_local_port_if_needed()
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;
if (addr && addr_length != sizeof(sockaddr_in))
return -EINVAL;
return KResult(-EINVAL);
if (addr) {
if (addr->sa_family != 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;
@ -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());
if (routing_decision.is_zero())
return -EHOSTUNREACH;
return KResult(-EHOSTUNREACH);
if (m_local_address.to_u32() == 0)
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;
}
int nsent = protocol_send(data, data_length);
if (nsent > 0)
Thread::current()->did_ipv4_socket_write(nsent);
return nsent;
auto nsent_or_error = protocol_send(data, data_length);
if (!nsent_or_error.is_error())
Thread::current()->did_ipv4_socket_write(nsent_or_error.value());
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());
if (m_receive_buffer.is_empty()) {
if (protocol_is_disconnected())
return 0;
if (!description.is_blocking())
return -EAGAIN;
return KResult(-EAGAIN);
locker.unlock();
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 (res.was_interrupted())
return -EINTR;
return KResult(-EINTR);
// 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;
}
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());
ReceivedPacket packet;
@ -278,7 +278,7 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
if (protocol_is_disconnected())
return 0;
if (!description.is_blocking())
return -EAGAIN;
return KResult(-EAGAIN);
}
if (!m_receive_queue.is_empty()) {
@ -301,10 +301,10 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
if (!m_can_read) {
if (res.was_interrupted())
return -EINTR;
return KResult(-EINTR);
// Unblocked due to timeout.
return -EAGAIN;
return KResult(-EAGAIN);
}
ASSERT(m_can_read);
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);
}
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))
return -EINVAL;
return KResult(-EINVAL);
#ifdef IPV4_SOCKET_DEBUG
klog() << "recvfrom: type=" << type() << ", local_port=" << local_port();
#endif
ssize_t nreceived = 0;
KResultOr<size_t> nreceived = 0;
if (buffer_mode() == BufferMode::Bytes)
nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, addr, addr_length);
else
nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, addr, addr_length);
if (nreceived > 0)
Thread::current()->did_ipv4_socket_read(nreceived);
if (!nreceived.is_error())
Thread::current()->did_ipv4_socket_read(nreceived.value());
return nreceived;
}
@ -374,8 +374,10 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
ASSERT(m_can_read);
return false;
}
int nreceived = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0);
m_receive_buffer.write(m_scratch_buffer.value().data(), nreceived);
auto nreceived_or_error = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0);
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();
} else {
// 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 bool can_read(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 ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const 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 getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override;
@ -96,8 +96,8 @@ protected:
virtual KResult protocol_bind() { return KSuccess; }
virtual KResult protocol_listen() { return KSuccess; }
virtual int 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_receive(const KBuffer&, void*, size_t, int) { return -ENOTIMPL; }
virtual KResultOr<size_t> protocol_send(const void*, size_t) { return -ENOTIMPL; }
virtual KResult protocol_connect(FileDescription&, ShouldBlock) { return KSuccess; }
virtual int protocol_allocate_local_port() { return 0; }
virtual bool protocol_is_disconnected() const { return false; }
@ -110,8 +110,8 @@ protected:
private:
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*);
ssize_t receive_packet_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*);
KResultOr<size_t> receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
IPv4Address m_local_address;
IPv4Address m_peer_address;

View file

@ -260,10 +260,10 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const
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))
return -EPIPE;
return KResult(-EPIPE);
ssize_t nwritten = send_buffer_for(description).write((const u8*)data, data_size);
if (nwritten > 0)
Thread::current()->did_unix_socket_write(nwritten);
@ -290,18 +290,18 @@ DoubleBuffer& LocalSocket::send_buffer_for(FileDescription& description)
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);
if (!description.is_blocking()) {
if (buffer_for_me.is_empty()) {
if (!has_attached_peer(description))
return 0;
return -EAGAIN;
return KResult(-EAGAIN);
}
} else if (!can_read(description, 0)) {
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())
return 0;

View file

@ -60,8 +60,8 @@ public:
virtual void detach(FileDescription&) override;
virtual bool can_read(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 ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const 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 chown(FileDescription&, uid_t, gid_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())
return 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())
return -EPIPE;

View file

@ -107,8 +107,8 @@ public:
virtual bool is_ipv4() const { return false; }
virtual void attach(FileDescription&) = 0;
virtual void detach(FileDescription&) = 0;
virtual ssize_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> sendto(FileDescription&, const void*, size_t, int flags, const 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 getsockopt(FileDescription&, int level, int option, void*, socklen_t*);
@ -124,8 +124,8 @@ public:
Lock& lock() { return m_lock; }
// ^File
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override final;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override final;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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;
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));
}
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;
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;
}
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);
return data_length;

View file

@ -178,8 +178,8 @@ private:
virtual void shut_down_for_writing() override;
virtual int 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_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
virtual KResultOr<size_t> protocol_send(const void*, size_t) override;
virtual KResult protocol_connect(FileDescription&, ShouldBlock) override;
virtual int protocol_allocate_local_port() 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));
}
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;
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);
}
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());
if (routing_decision.is_zero())
return -EHOSTUNREACH;
return KResult(-EHOSTUNREACH);
auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length);
auto& udp_packet = *(UDPPacket*)(buffer.data());
udp_packet.set_source_port(local_port());

View file

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

View file

@ -418,7 +418,10 @@ KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_exec
return KResult(-ENOEXEC);
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))
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
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
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()) {
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
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;
// We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out)
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;
}
}
// FIXME: We should have a read() that takes a Userspace<u8*>
return description->read(buffer.unsafe_userspace_ptr(), size);
auto result = 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())
return -EPIPE;
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)
@ -251,11 +254,13 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
if (flags & MSG_DONTWAIT)
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)
description->set_blocking(original_blocking);
return nrecv;
if (result.is_error())
return result.error();
return result.value();
}
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 nwritten = 0;
ssize_t total_nwritten = 0;
if (!description.is_blocking()) {
if (!description.can_write())
return -EAGAIN;
}
if (description.should_append()) {
#ifdef IO_DEBUG
dbg() << "seeking to end (O_APPEND)";
#endif
if (description.should_append())
description.seek(0, SEEK_END);
}
while (nwritten < data_size) {
#ifdef IO_DEBUG
dbg() << "while " << nwritten << " < " << size;
#endif
while (total_nwritten < data_size) {
if (!description.can_write()) {
if (!description.is_blocking()) {
// Short write: We can no longer write to this non-blocking description.
ASSERT(nwritten > 0);
return nwritten;
ASSERT(total_nwritten > 0);
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 (nwritten == 0)
if (total_nwritten == 0)
return -EINTR;
}
}
ssize_t rc = description.write(data + nwritten, data_size - nwritten);
#ifdef IO_DEBUG
dbg() << " -> write returned " << rc;
#endif
if (rc < 0) {
if (nwritten)
return nwritten;
return rc;
auto nwritten_or_error = description.write(data + total_nwritten, data_size - total_nwritten);
if (nwritten_or_error.is_error()) {
if (total_nwritten)
return total_nwritten;
return nwritten_or_error.error();
}
if (rc == 0)
if (nwritten_or_error.value() == 0)
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)

View file

@ -60,17 +60,17 @@ String MasterPTY::pts_name() const
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())
return 0;
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)
return -EIO;
return KResult(-EIO);
m_slave->on_master_write(buffer, size);
return size;
}

View file

@ -50,8 +50,8 @@ public:
private:
// ^CharacterDevice
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_write(const FileDescription&, size_t) const override;
virtual KResult close() override;

View file

@ -44,8 +44,8 @@ public:
// ^CharacterDevice
virtual KResultOr<NonnullRefPtr<FileDescription>> open(int options) override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override { return 0; }
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override { return 0; }
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_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);
}
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())
return 0;

View file

@ -48,7 +48,7 @@ private:
// ^CharacterDevice
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 const char* class_name() const override { return "SlavePTY"; }
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));
}
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))
size = m_input_buffer.size();
if (in_canonical_mode()) {
int i = 0;
size_t i = 0;
for (; i < size; i++) {
u8 ch = m_input_buffer.dequeue();
if (ch == '\0') {
@ -79,21 +77,14 @@ ssize_t TTY::read(FileDescription&, size_t, u8* buffer, ssize_t size)
return i;
}
for (int i = 0; i < size; i++)
for (size_t i = 0; i < size; i++)
buffer[i] = m_input_buffer.dequeue();
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);
return size;
}

View file

@ -39,8 +39,8 @@ class TTY : public CharacterDevice {
public:
virtual ~TTY() override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_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_write(const FileDescription&, size_t) const override;
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override final;