mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-14 01:04:38 +03:00
Kernel: Make syscalls that take a buffer size use ssize_t instead of size_t.
Dealing with the unsigned overflow propagation here just seems unreasonably error prone. Let's limit ourselves to 2GB buffer sizes instead.
This commit is contained in:
parent
5af4e622b9
commit
beda478821
Notes:
sideshowbarker
2024-07-19 15:37:56 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/beda4788216
@ -132,12 +132,12 @@ bool BXVGADevice::can_write(Process&) const
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ssize_t BXVGADevice::read(Process&, byte*, size_t)
|
||||
ssize_t BXVGADevice::read(Process&, byte*, ssize_t)
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ssize_t BXVGADevice::write(Process&, const byte*, size_t)
|
||||
ssize_t BXVGADevice::write(Process&, const byte*, ssize_t)
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ private:
|
||||
virtual const char* class_name() const override { return "BXVGA"; }
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override;
|
||||
virtual ssize_t read(Process&, byte*, size_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, size_t) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
|
||||
void set_register(word index, word value);
|
||||
dword find_framebuffer_address();
|
||||
|
@ -28,20 +28,20 @@ bool Console::can_read(Process&) const
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t Console::read(Process&, byte*, size_t)
|
||||
ssize_t Console::read(Process&, byte*, ssize_t)
|
||||
{
|
||||
// FIXME: Implement reading from the console.
|
||||
// Maybe we could use a ring buffer for this device?
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t Console::write(Process&, const byte* data, size_t size)
|
||||
ssize_t Console::write(Process&, const byte* data, ssize_t size)
|
||||
{
|
||||
if (!size)
|
||||
return 0;
|
||||
if (!m_implementation)
|
||||
return 0;
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
for (ssize_t i = 0; i < size; ++i)
|
||||
put_char(data[i]);
|
||||
return size;
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ public:
|
||||
// ^CharacterDevice
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t size) override;
|
||||
virtual ssize_t write(Process&, const byte* data, size_t size) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual const char* class_name() const override { return "Console"; }
|
||||
|
||||
void set_implementation(ConsoleImplementation* implementation) { m_implementation = implementation; }
|
||||
|
@ -19,8 +19,8 @@ public:
|
||||
virtual bool can_read(Process&) const = 0;
|
||||
virtual bool can_write(Process&) const = 0;
|
||||
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) = 0;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) = 0;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) = 0;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) = 0;
|
||||
|
||||
unsigned major() const { return m_major; }
|
||||
unsigned minor() const { return m_minor; }
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "DoubleBuffer.h"
|
||||
#include <Kernel/DoubleBuffer.h>
|
||||
|
||||
inline void DoubleBuffer::compute_emptiness()
|
||||
{
|
||||
@ -17,24 +17,22 @@ void DoubleBuffer::flip()
|
||||
compute_emptiness();
|
||||
}
|
||||
|
||||
ssize_t DoubleBuffer::write(const byte* data, size_t size)
|
||||
ssize_t DoubleBuffer::write(const byte* data, ssize_t size)
|
||||
{
|
||||
ASSERT_INTERRUPTS_ENABLED();
|
||||
LOCKER(m_lock);
|
||||
m_write_buffer->append(data, size);
|
||||
compute_emptiness();
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t DoubleBuffer::read(byte* data, size_t size)
|
||||
ssize_t DoubleBuffer::read(byte* data, ssize_t size)
|
||||
{
|
||||
ASSERT_INTERRUPTS_ENABLED();
|
||||
LOCKER(m_lock);
|
||||
if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->is_empty())
|
||||
flip();
|
||||
if (m_read_buffer_index >= m_read_buffer->size())
|
||||
return 0;
|
||||
ssize_t nread = min(m_read_buffer->size() - m_read_buffer_index, size);
|
||||
ssize_t nread = min((ssize_t)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_emptiness();
|
||||
|
@ -13,13 +13,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t write(const byte*, size_t);
|
||||
ssize_t read(byte*, size_t);
|
||||
ssize_t write(const byte*, ssize_t);
|
||||
ssize_t read(byte*, ssize_t);
|
||||
|
||||
bool is_empty() const { return m_empty; }
|
||||
|
||||
// FIXME: Isn't this racy? What if we get interrupted between getting the buffer pointer and dereferencing it?
|
||||
size_t bytes_in_write_buffer() const { return m_write_buffer->size(); }
|
||||
ssize_t bytes_in_write_buffer() const { return (ssize_t)m_write_buffer->size(); }
|
||||
|
||||
private:
|
||||
void flip();
|
||||
@ -29,7 +29,7 @@ private:
|
||||
Vector<byte>* m_read_buffer { nullptr };
|
||||
Vector<byte> m_buffer1;
|
||||
Vector<byte> m_buffer2;
|
||||
size_t m_read_buffer_index { 0 };
|
||||
ssize_t m_read_buffer_index { 0 };
|
||||
bool m_empty { true };
|
||||
Lock m_lock;
|
||||
};
|
||||
|
@ -54,21 +54,21 @@ bool FIFO::can_write() const
|
||||
return m_buffer.bytes_in_write_buffer() < 4096;
|
||||
}
|
||||
|
||||
ssize_t FIFO::read(byte* buffer, size_t size)
|
||||
ssize_t FIFO::read(byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_writers && m_buffer.is_empty())
|
||||
return 0;
|
||||
#ifdef FIFO_DEBUG
|
||||
dbgprintf("fifo: read(%u)\n",size);
|
||||
#endif
|
||||
size_t nread = m_buffer.read(buffer, size);
|
||||
ssize_t nread = m_buffer.read(buffer, size);
|
||||
#ifdef FIFO_DEBUG
|
||||
dbgprintf(" -> read (%c) %u\n", buffer[0], nread);
|
||||
#endif
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t FIFO::write(const byte* buffer, size_t size)
|
||||
ssize_t FIFO::write(const byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_readers)
|
||||
return 0;
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
void open(Direction);
|
||||
void close(Direction);
|
||||
|
||||
ssize_t write(const byte*, size_t);
|
||||
ssize_t read(byte*, size_t);
|
||||
ssize_t write(const byte*, ssize_t);
|
||||
ssize_t read(byte*, ssize_t);
|
||||
|
||||
bool can_read() const;
|
||||
bool can_write() const;
|
||||
|
@ -176,7 +176,7 @@ off_t FileDescriptor::seek(off_t offset, int whence)
|
||||
return m_current_offset;
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::read(Process& process, byte* buffer, size_t count)
|
||||
ssize_t FileDescriptor::read(Process& process, byte* buffer, ssize_t count)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Reader);
|
||||
@ -194,7 +194,7 @@ ssize_t FileDescriptor::read(Process& process, byte* buffer, size_t count)
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::write(Process& process, const byte* data, size_t size)
|
||||
ssize_t FileDescriptor::write(Process& process, const byte* data, ssize_t size)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Writer);
|
||||
@ -245,6 +245,7 @@ ByteBuffer FileDescriptor::read_entire_file(Process& process)
|
||||
if (m_device) {
|
||||
auto buffer = ByteBuffer::create_uninitialized(1024);
|
||||
ssize_t nread = m_device->read(process, buffer.pointer(), buffer.size());
|
||||
ASSERT(nread >= 0);
|
||||
buffer.trim(nread);
|
||||
return buffer;
|
||||
}
|
||||
@ -259,7 +260,7 @@ bool FileDescriptor::is_directory() const
|
||||
return metadata().is_directory();
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::get_dir_entries(byte* buffer, size_t size)
|
||||
ssize_t FileDescriptor::get_dir_entries(byte* buffer, ssize_t size)
|
||||
{
|
||||
auto metadata = this->metadata();
|
||||
if (!metadata.is_valid())
|
||||
|
@ -30,14 +30,14 @@ public:
|
||||
int close();
|
||||
|
||||
off_t seek(off_t, int whence);
|
||||
ssize_t read(Process&, byte*, size_t);
|
||||
ssize_t write(Process&, const byte* data, size_t);
|
||||
ssize_t read(Process&, byte*, ssize_t);
|
||||
ssize_t write(Process&, const byte* data, ssize_t);
|
||||
int fstat(stat*);
|
||||
|
||||
bool can_read(Process&);
|
||||
bool can_write(Process&);
|
||||
|
||||
ssize_t get_dir_entries(byte* buffer, size_t);
|
||||
ssize_t get_dir_entries(byte* buffer, ssize_t);
|
||||
|
||||
ByteBuffer read_entire_file(Process&);
|
||||
|
||||
|
@ -18,16 +18,16 @@ bool FullDevice::can_read(Process&) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t FullDevice::read(Process&, byte* buffer, size_t bufferSize)
|
||||
ssize_t FullDevice::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
size_t count = min(GoodBufferSize, bufferSize);
|
||||
memset(buffer, 0, count);
|
||||
ssize_t count = min(GoodBufferSize, size);
|
||||
memset(buffer, 0, (size_t)count);
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t FullDevice::write(Process&, const byte*, size_t bufferSize)
|
||||
ssize_t FullDevice::write(Process&, const byte*, ssize_t size)
|
||||
{
|
||||
if (bufferSize == 0)
|
||||
if (size == 0)
|
||||
return 0;
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ public:
|
||||
|
||||
private:
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual const char* class_name() const override { return "FullDevice"; }
|
||||
|
@ -177,14 +177,14 @@ bool KeyboardDevice::can_read(Process&) const
|
||||
return !m_queue.is_empty();
|
||||
}
|
||||
|
||||
ssize_t KeyboardDevice::read(Process&, byte* buffer, size_t size)
|
||||
ssize_t KeyboardDevice::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
ssize_t nread = 0;
|
||||
while ((size_t)nread < size) {
|
||||
while (nread < size) {
|
||||
if (m_queue.is_empty())
|
||||
break;
|
||||
// Don't return partial data frames.
|
||||
if ((size - nread) < sizeof(Event))
|
||||
if ((size - nread) < (ssize_t)sizeof(Event))
|
||||
break;
|
||||
auto event = m_queue.dequeue();
|
||||
memcpy(buffer, &event, sizeof(Event));
|
||||
@ -193,7 +193,7 @@ ssize_t KeyboardDevice::read(Process&, byte* buffer, size_t size)
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t KeyboardDevice::write(Process&, const byte*, size_t)
|
||||
ssize_t KeyboardDevice::write(Process&, const byte*, ssize_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ public:
|
||||
void set_client(KeyboardClient* client) { m_client = client; }
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t) override;
|
||||
virtual ssize_t read(Process&, byte* buffer, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, ssize_t) override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
|
||||
private:
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
inline static const off_t maxFileOffset = 2147483647;
|
||||
|
||||
static const size_t GoodBufferSize = 4096;
|
||||
static const ssize_t GoodBufferSize = 4096;
|
||||
|
||||
|
||||
|
@ -137,7 +137,7 @@ bool LocalSocket::can_read(SocketRole role) const
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ssize_t LocalSocket::read(SocketRole role, byte* buffer, size_t size)
|
||||
ssize_t LocalSocket::read(SocketRole role, byte* buffer, ssize_t size)
|
||||
{
|
||||
if (role == SocketRole::Accepted)
|
||||
return m_for_server.read(buffer, size);
|
||||
@ -146,7 +146,7 @@ ssize_t LocalSocket::read(SocketRole role, byte* buffer, size_t size)
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ssize_t LocalSocket::write(SocketRole role, const byte* data, size_t size)
|
||||
ssize_t LocalSocket::write(SocketRole role, const byte* data, ssize_t size)
|
||||
{
|
||||
if (role == SocketRole::Accepted) {
|
||||
if (!m_accepted_fds_open)
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
virtual void attach_fd(SocketRole) override;
|
||||
virtual void detach_fd(SocketRole) override;
|
||||
virtual bool can_read(SocketRole) const override;
|
||||
virtual ssize_t read(SocketRole, byte*, size_t) override;
|
||||
virtual ssize_t write(SocketRole, const byte*, size_t) override;
|
||||
virtual ssize_t read(SocketRole, byte*, ssize_t) override;
|
||||
virtual ssize_t write(SocketRole, const byte*, ssize_t) override;
|
||||
virtual bool can_write(SocketRole) const override;
|
||||
|
||||
private:
|
||||
|
@ -26,14 +26,14 @@ String MasterPTY::pts_name() const
|
||||
return String::format("/dev/pts/%u", m_index);
|
||||
}
|
||||
|
||||
ssize_t MasterPTY::read(Process&, byte* buffer, size_t size)
|
||||
ssize_t MasterPTY::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_slave && m_buffer.is_empty())
|
||||
return 0;
|
||||
return m_buffer.read(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t MasterPTY::write(Process&, const byte* buffer, size_t size)
|
||||
ssize_t MasterPTY::write(Process&, const byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_slave)
|
||||
return -EIO;
|
||||
@ -62,7 +62,7 @@ void MasterPTY::notify_slave_closed(Badge<SlavePTY>)
|
||||
m_slave = nullptr;
|
||||
}
|
||||
|
||||
ssize_t MasterPTY::on_slave_write(const byte* data, size_t size)
|
||||
ssize_t MasterPTY::on_slave_write(const byte* data, ssize_t size)
|
||||
{
|
||||
if (m_closed)
|
||||
return -EIO;
|
||||
|
@ -13,15 +13,15 @@ public:
|
||||
|
||||
unsigned index() const { return m_index; }
|
||||
String pts_name() const;
|
||||
ssize_t on_slave_write(const byte*, size_t);
|
||||
ssize_t on_slave_write(const byte*, ssize_t);
|
||||
bool can_write_from_slave() const;
|
||||
void notify_slave_closed(Badge<SlavePTY>);
|
||||
bool is_closed() const { return m_closed; }
|
||||
|
||||
private:
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte*, size_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, size_t) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override;
|
||||
virtual void close() override;
|
||||
|
@ -815,6 +815,8 @@ void VMObject::inode_size_changed(Badge<Inode>, size_t old_size, size_t new_size
|
||||
|
||||
void VMObject::inode_contents_changed(Badge<Inode>, off_t offset, size_t size, const byte* data)
|
||||
{
|
||||
(void)size;
|
||||
(void)data;
|
||||
InterruptDisabler disabler;
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
|
@ -26,13 +26,13 @@ bool NullDevice::can_read(Process&) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t NullDevice::read(Process&, byte*, size_t)
|
||||
ssize_t NullDevice::read(Process&, byte*, ssize_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t NullDevice::write(Process&, const byte*, size_t bufferSize)
|
||||
ssize_t NullDevice::write(Process&, const byte*, ssize_t buffer_size)
|
||||
{
|
||||
return min(GoodBufferSize, bufferSize);
|
||||
return min(GoodBufferSize, buffer_size);
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@ public:
|
||||
|
||||
private:
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual const char* class_name() const override { return "NullDevice"; }
|
||||
|
@ -144,10 +144,10 @@ bool PS2MouseDevice::can_read(Process&) const
|
||||
return !m_queue.is_empty();
|
||||
}
|
||||
|
||||
ssize_t PS2MouseDevice::read(Process&, byte* buffer, size_t size)
|
||||
ssize_t PS2MouseDevice::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
ssize_t nread = 0;
|
||||
while ((size_t)nread < size) {
|
||||
while (nread < size) {
|
||||
if (m_queue.is_empty())
|
||||
break;
|
||||
// FIXME: Don't return partial data frames.
|
||||
@ -156,7 +156,7 @@ ssize_t PS2MouseDevice::read(Process&, byte* buffer, size_t size)
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t PS2MouseDevice::write(Process&, const byte*, size_t)
|
||||
ssize_t PS2MouseDevice::write(Process&, const byte*, ssize_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ public:
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
|
||||
private:
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual RetainPtr<FileDescriptor> open(int& error, int options) override;
|
||||
virtual ssize_t read(Process&, byte*, size_t) override { return 0; }
|
||||
virtual ssize_t write(Process&, const byte*, size_t) override { return 0; }
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override { return 0; }
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override { return 0; }
|
||||
virtual bool can_read(Process&) const override { return true; }
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
|
||||
|
@ -199,8 +199,10 @@ int Process::sys$munmap(void* addr, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$gethostname(char* buffer, size_t size)
|
||||
int Process::sys$gethostname(char* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
LOCKER(*s_hostname_lock);
|
||||
@ -971,8 +973,10 @@ const FileDescriptor* Process::file_descriptor(int fd) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ssize_t Process::sys$get_dir_entries(int fd, void* buffer, size_t size)
|
||||
ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
@ -989,8 +993,10 @@ int Process::sys$lseek(int fd, off_t offset, int whence)
|
||||
return descriptor->seek(offset, whence);
|
||||
}
|
||||
|
||||
int Process::sys$ttyname_r(int fd, char* buffer, size_t size)
|
||||
int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
@ -1005,8 +1011,10 @@ int Process::sys$ttyname_r(int fd, char* buffer, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$ptsname_r(int fd, char* buffer, size_t size)
|
||||
int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
@ -1022,8 +1030,10 @@ int Process::sys$ptsname_r(int fd, char* buffer, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t Process::sys$write(int fd, const void* data, size_t size)
|
||||
ssize_t Process::sys$write(int fd, const byte* data, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_read(data, size))
|
||||
return -EFAULT;
|
||||
#ifdef DEBUG_IO
|
||||
@ -1074,26 +1084,21 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
|
||||
if (nwritten == 0)
|
||||
return -EINTR;
|
||||
}
|
||||
#ifdef DEBUG_IO
|
||||
dbgprintf("%s(%u) sys$write: nwritten=%u\n", name().characters(), pid(), nwritten);
|
||||
#endif
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
|
||||
ssize_t Process::sys$read(int fd, byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!validate_write(outbuf, nread))
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
#ifdef DEBUG_IO
|
||||
dbgprintf("%s(%u) sys$read(%d, %p, %u)\n", name().characters(), pid(), fd, outbuf, nread);
|
||||
dbgprintf("%s(%u) sys$read(%d, %p, %u)\n", name().characters(), pid(), fd, buffer, size);
|
||||
#endif
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
#ifdef DEBUG_IO
|
||||
dbgprintf(" > descriptor:%p, is_blocking:%u, can_read:%u\n", descriptor, descriptor->is_blocking(), descriptor->can_read(*this));
|
||||
dbgprintf(" > inode:K%x, device:K%x\n", descriptor->inode(), descriptor->character_device());
|
||||
#endif
|
||||
if (descriptor->is_blocking()) {
|
||||
if (!descriptor->can_read(*this)) {
|
||||
m_blocked_fd = fd;
|
||||
@ -1103,11 +1108,7 @@ ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
nread = descriptor->read(*this, (byte*)outbuf, nread);
|
||||
#ifdef DEBUG_IO
|
||||
dbgprintf("%s(%u) Process::sys$read: nread=%u\n", name().characters(), pid(), nread);
|
||||
#endif
|
||||
return nread;
|
||||
return descriptor->read(*this, buffer, size);
|
||||
}
|
||||
|
||||
int Process::sys$close(int fd)
|
||||
@ -1221,8 +1222,10 @@ int Process::sys$stat(const char* path, stat* statbuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$readlink(const char* path, char* buffer, size_t size)
|
||||
int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_read_str(path))
|
||||
return -EFAULT;
|
||||
if (!validate_write(buffer, size))
|
||||
@ -1240,7 +1243,7 @@ int Process::sys$readlink(const char* path, char* buffer, size_t size)
|
||||
if (!contents)
|
||||
return -EIO; // FIXME: Get a more detailed error from VFS.
|
||||
|
||||
memcpy(buffer, contents.pointer(), min(size, contents.size()));
|
||||
memcpy(buffer, contents.pointer(), min(size, (ssize_t)contents.size()));
|
||||
if (contents.size() + 1 < size)
|
||||
buffer[contents.size()] = '\0';
|
||||
return 0;
|
||||
@ -1260,8 +1263,10 @@ int Process::sys$chdir(const char* path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$getcwd(char* buffer, size_t size)
|
||||
int Process::sys$getcwd(char* buffer, ssize_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return -EINVAL;
|
||||
if (!validate_write(buffer, size))
|
||||
return -EFAULT;
|
||||
auto path = VFS::the().absolute_path(cwd_inode());
|
||||
@ -1655,8 +1660,9 @@ bool Process::validate_read_str(const char* str)
|
||||
return validate_read(str, strlen(str) + 1);
|
||||
}
|
||||
|
||||
bool Process::validate_read(const void* address, size_t size) const
|
||||
bool Process::validate_read(const void* address, ssize_t size) const
|
||||
{
|
||||
ASSERT(size >= 0);
|
||||
LinearAddress first_address((dword)address);
|
||||
LinearAddress last_address = first_address.offset(size - 1);
|
||||
if (is_ring0()) {
|
||||
@ -1678,8 +1684,9 @@ bool Process::validate_read(const void* address, size_t size) const
|
||||
return MM.validate_user_read(*this, first_address);
|
||||
}
|
||||
|
||||
bool Process::validate_write(void* address, size_t size) const
|
||||
bool Process::validate_write(void* address, ssize_t size) const
|
||||
{
|
||||
ASSERT(size >= 0);
|
||||
LinearAddress first_address((dword)address);
|
||||
LinearAddress last_address = first_address.offset(size - 1);
|
||||
if (is_ring0()) {
|
||||
|
@ -162,8 +162,8 @@ public:
|
||||
mode_t sys$umask(mode_t);
|
||||
int sys$open(const char* path, int options, mode_t mode = 0);
|
||||
int sys$close(int fd);
|
||||
ssize_t sys$read(int fd, void* outbuf, size_t nread);
|
||||
ssize_t sys$write(int fd, const void*, size_t);
|
||||
ssize_t sys$read(int fd, byte*, ssize_t);
|
||||
ssize_t sys$write(int fd, const byte*, ssize_t);
|
||||
int sys$fstat(int fd, stat*);
|
||||
int sys$lstat(const char*, stat*);
|
||||
int sys$stat(const char*, stat*);
|
||||
@ -178,17 +178,17 @@ public:
|
||||
int sys$set_mmap_name(void*, size_t, const char*);
|
||||
int sys$select(const Syscall::SC_select_params*);
|
||||
int sys$poll(pollfd*, int nfds, int timeout);
|
||||
ssize_t sys$get_dir_entries(int fd, void*, size_t);
|
||||
int sys$getcwd(char*, size_t);
|
||||
ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
|
||||
int sys$getcwd(char*, ssize_t);
|
||||
int sys$chdir(const char*);
|
||||
int sys$sleep(unsigned seconds);
|
||||
int sys$usleep(useconds_t usec);
|
||||
int sys$gettimeofday(timeval*);
|
||||
int sys$gethostname(char* name, size_t length);
|
||||
int sys$gethostname(char*, ssize_t);
|
||||
int sys$uname(utsname*);
|
||||
int sys$readlink(const char*, char*, size_t);
|
||||
int sys$ttyname_r(int fd, char*, size_t);
|
||||
int sys$ptsname_r(int fd, char*, size_t);
|
||||
int sys$readlink(const char*, char*, ssize_t);
|
||||
int sys$ttyname_r(int fd, char*, ssize_t);
|
||||
int sys$ptsname_r(int fd, char*, ssize_t);
|
||||
pid_t sys$fork(RegisterDump&);
|
||||
int sys$execve(const char* filename, const char** argv, const char** envp);
|
||||
int sys$isatty(int fd);
|
||||
@ -257,8 +257,8 @@ public:
|
||||
|
||||
bool validate_read_from_kernel(LinearAddress) const;
|
||||
|
||||
bool validate_read(const void*, size_t) const;
|
||||
bool validate_write(void*, size_t) const;
|
||||
bool validate_read(const void*, ssize_t) const;
|
||||
bool validate_write(void*, ssize_t) const;
|
||||
bool validate_read_str(const char* str);
|
||||
template<typename T> bool validate_read_typed(T* value, size_t count = 1) { return validate_read(value, sizeof(T) * count); }
|
||||
template<typename T> bool validate_write_typed(T* value, size_t count = 1) { return validate_write(value, sizeof(T) * count); }
|
||||
|
@ -34,20 +34,20 @@ bool RandomDevice::can_read(Process&) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t RandomDevice::read(Process&, byte* buffer, size_t bufferSize)
|
||||
ssize_t RandomDevice::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
const int range = 'z' - 'a';
|
||||
ssize_t nread = min(bufferSize, GoodBufferSize);
|
||||
ssize_t nread = min(size, GoodBufferSize);
|
||||
for (ssize_t i = 0; i < nread; ++i) {
|
||||
dword r = myrand() % range;
|
||||
buffer[i] = 'a' + r;
|
||||
buffer[i] = (byte)('a' + r);
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t RandomDevice::write(Process&, const byte*, size_t bufferSize)
|
||||
ssize_t RandomDevice::write(Process&, const byte*, ssize_t size)
|
||||
{
|
||||
// FIXME: Use input for entropy? I guess that could be a neat feature?
|
||||
return min(GoodBufferSize, bufferSize);
|
||||
return min(GoodBufferSize, size);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ public:
|
||||
|
||||
private:
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual const char* class_name() const override { return "RandomDevice"; }
|
||||
|
@ -25,13 +25,13 @@ String SlavePTY::tty_name() const
|
||||
return String::format("/dev/pts/%u", m_index);
|
||||
}
|
||||
|
||||
void SlavePTY::on_master_write(const byte* buffer, size_t size)
|
||||
void SlavePTY::on_master_write(const byte* buffer, ssize_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
for (ssize_t i = 0; i < size; ++i)
|
||||
emit(buffer[i]);
|
||||
}
|
||||
|
||||
ssize_t SlavePTY::on_tty_write(const byte* data, size_t size)
|
||||
ssize_t SlavePTY::on_tty_write(const byte* data, ssize_t size)
|
||||
{
|
||||
return m_master->on_slave_write(data, size);
|
||||
}
|
||||
@ -48,7 +48,7 @@ bool SlavePTY::can_read(Process& process) const
|
||||
return TTY::can_read(process);
|
||||
}
|
||||
|
||||
ssize_t SlavePTY::read(Process& process, byte* buffer, size_t size)
|
||||
ssize_t SlavePTY::read(Process& process, byte* buffer, ssize_t size)
|
||||
{
|
||||
if (m_master->is_closed())
|
||||
return 0;
|
||||
|
@ -8,7 +8,7 @@ class SlavePTY final : public TTY {
|
||||
public:
|
||||
virtual ~SlavePTY() override;
|
||||
|
||||
void on_master_write(const byte*, size_t);
|
||||
void on_master_write(const byte*, ssize_t);
|
||||
unsigned index() const { return m_index; }
|
||||
|
||||
InodeIdentifier devpts_inode_id() const { return m_devpts_inode_id; }
|
||||
@ -17,11 +17,11 @@ public:
|
||||
private:
|
||||
// ^TTY
|
||||
virtual String tty_name() const override;
|
||||
virtual ssize_t on_tty_write(const byte*, size_t) override;
|
||||
virtual ssize_t on_tty_write(const byte*, ssize_t) override;
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual ssize_t read(Process&, byte*, size_t) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual bool can_write(Process&) const override;
|
||||
virtual const char* class_name() const override { return "SlavePTY"; }
|
||||
virtual void close() override;
|
||||
|
@ -30,8 +30,8 @@ public:
|
||||
virtual void attach_fd(SocketRole) = 0;
|
||||
virtual void detach_fd(SocketRole) = 0;
|
||||
virtual bool can_read(SocketRole) const = 0;
|
||||
virtual ssize_t read(SocketRole, byte*, size_t) = 0;
|
||||
virtual ssize_t write(SocketRole, const byte*, size_t) = 0;
|
||||
virtual ssize_t read(SocketRole, byte*, ssize_t) = 0;
|
||||
virtual ssize_t write(SocketRole, const byte*, ssize_t) = 0;
|
||||
virtual bool can_write(SocketRole) const = 0;
|
||||
|
||||
pid_t origin_pid() const { return m_origin_pid; }
|
||||
|
@ -77,11 +77,11 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
||||
case Syscall::SC_open:
|
||||
return current->sys$open((const char*)arg1, (int)arg2, (mode_t)arg3);
|
||||
case Syscall::SC_write:
|
||||
return current->sys$write((int)arg1, (const void*)arg2, (size_t)arg3);
|
||||
return current->sys$write((int)arg1, (const byte*)arg2, (ssize_t)arg3);
|
||||
case Syscall::SC_close:
|
||||
return current->sys$close((int)arg1);
|
||||
case Syscall::SC_read:
|
||||
return current->sys$read((int)arg1, (void*)arg2, (size_t)arg3);
|
||||
return current->sys$read((int)arg1, (byte*)arg2, (ssize_t)arg3);
|
||||
case Syscall::SC_lseek:
|
||||
return current->sys$lseek((int)arg1, (off_t)arg2, (int)arg3);
|
||||
case Syscall::SC_kill:
|
||||
|
@ -24,12 +24,12 @@ void TTY::set_default_termios()
|
||||
memcpy(m_termios.c_cc, default_cc, sizeof(default_cc));
|
||||
}
|
||||
|
||||
ssize_t TTY::read(Process&, byte* buffer, size_t size)
|
||||
ssize_t TTY::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
return m_buffer.read(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t TTY::write(Process&, const byte* buffer, size_t size)
|
||||
ssize_t TTY::write(Process&, const byte* buffer, ssize_t size)
|
||||
{
|
||||
#ifdef TTY_DEBUG
|
||||
dbgprintf("TTY::write {%u} ", size);
|
||||
|
@ -10,8 +10,8 @@ class TTY : public CharacterDevice {
|
||||
public:
|
||||
virtual ~TTY() override;
|
||||
|
||||
virtual ssize_t read(Process&, byte*, size_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, size_t) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override;
|
||||
virtual int ioctl(Process&, unsigned request, unsigned arg) override final;
|
||||
@ -33,7 +33,7 @@ public:
|
||||
void hang_up();
|
||||
|
||||
protected:
|
||||
virtual ssize_t on_tty_write(const byte*, size_t) = 0;
|
||||
virtual ssize_t on_tty_write(const byte*, ssize_t) = 0;
|
||||
void set_size(unsigned short columns, unsigned short rows);
|
||||
|
||||
TTY(unsigned major, unsigned minor);
|
||||
|
@ -499,10 +499,10 @@ void VirtualConsole::on_sysconsole_receive(byte ch)
|
||||
m_current_attribute = old_attribute;
|
||||
}
|
||||
|
||||
ssize_t VirtualConsole::on_tty_write(const byte* data, size_t size)
|
||||
ssize_t VirtualConsole::on_tty_write(const byte* data, ssize_t size)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
for (ssize_t i = 0; i < size; ++i)
|
||||
on_char(data[i]);
|
||||
return size;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ private:
|
||||
virtual void on_sysconsole_receive(byte) override;
|
||||
|
||||
// ^TTY
|
||||
virtual ssize_t on_tty_write(const byte*, size_t) override;
|
||||
virtual ssize_t on_tty_write(const byte*, ssize_t) override;
|
||||
virtual String tty_name() const override;
|
||||
|
||||
// ^CharacterDevice
|
||||
|
@ -17,15 +17,15 @@ bool ZeroDevice::can_read(Process&) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t ZeroDevice::read(Process&, byte* buffer, size_t bufferSize)
|
||||
ssize_t ZeroDevice::read(Process&, byte* buffer, ssize_t size)
|
||||
{
|
||||
size_t count = min(GoodBufferSize, bufferSize);
|
||||
memset(buffer, 0, count);
|
||||
ssize_t count = min(GoodBufferSize, size);
|
||||
memset(buffer, 0, (size_t)count);
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t ZeroDevice::write(Process&, const byte*, size_t bufferSize)
|
||||
ssize_t ZeroDevice::write(Process&, const byte*, ssize_t size)
|
||||
{
|
||||
return min(GoodBufferSize, bufferSize);
|
||||
return min(GoodBufferSize, size);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ public:
|
||||
|
||||
private:
|
||||
// ^CharacterDevice
|
||||
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override;
|
||||
virtual ssize_t read(Process&, byte*, ssize_t) override;
|
||||
virtual ssize_t write(Process&, const byte*, ssize_t) override;
|
||||
virtual bool can_read(Process&) const override;
|
||||
virtual bool can_write(Process&) const override { return true; }
|
||||
virtual const char* class_name() const override { return "ZeroDevice"; }
|
||||
|
Loading…
Reference in New Issue
Block a user