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

Kernel+LibC: Turn errno codes into a strongly typed enum

..and allow implicit creation of KResult and KResultOr from ErrnoCode.
This means that kernel functions that return those types can finally
do "return EINVAL;" and it will just work.

There's a handful of functions that still deal with signed integers
that should be converted to return KResults.
This commit is contained in:
Andreas Kling 2021-01-20 23:11:17 +01:00
parent e279b45aed
commit 19d3f8cab7
48 changed files with 591 additions and 506 deletions

View file

@ -83,7 +83,7 @@ Kernel::KResultOr<size_t> Console::write(Kernel::FileDescription&, size_t, const
return (ssize_t)bytes_count; return (ssize_t)bytes_count;
}); });
if (nread < 0) if (nread < 0)
return Kernel::KResult(nread); return Kernel::KResult((ErrnoCode)-nread);
return (size_t)nread; return (size_t)nread;
} }

View file

@ -179,12 +179,12 @@ KResultOr<Region*> BXVGADevice::mmap(Process& process, FileDescription&, Virtual
{ {
REQUIRE_PROMISE(video); REQUIRE_PROMISE(video);
if (!shared) if (!shared)
return KResult(-ENODEV); return ENODEV;
ASSERT(offset == 0); ASSERT(offset == 0);
ASSERT(size == framebuffer_size_in_bytes()); ASSERT(size == framebuffer_size_in_bytes());
auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes());
if (!vmobject) if (!vmobject)
return KResult(-ENOMEM); return ENOMEM;
return process.allocate_region_with_vmobject( return process.allocate_region_with_vmobject(
preferred_vaddr, preferred_vaddr,
framebuffer_size_in_bytes(), framebuffer_size_in_bytes(),

View file

@ -50,7 +50,7 @@ KResultOr<size_t> FullDevice::read(FileDescription&, size_t, UserOrKernelBuffer&
{ {
ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size); ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
if (!buffer.memset(0, count)) if (!buffer.memset(0, count))
return KResult(-EFAULT); return EFAULT;
return count; return count;
} }
@ -58,7 +58,7 @@ KResultOr<size_t> FullDevice::write(FileDescription&, size_t, const UserOrKernel
{ {
if (size == 0) if (size == 0)
return 0; return 0;
return KResult(-ENOSPC); return ENOSPC;
} }
} }

View file

@ -386,7 +386,7 @@ KResultOr<size_t> KeyboardDevice::read(FileDescription&, size_t, UserOrKernelBuf
return (ssize_t)data_bytes; return (ssize_t)data_bytes;
}); });
if (n < 0) if (n < 0)
return KResult(n); return KResult((ErrnoCode)-n);
ASSERT((size_t)n == sizeof(Event)); ASSERT((size_t)n == sizeof(Event));
nread += sizeof(Event); nread += sizeof(Event);

View file

@ -55,12 +55,12 @@ KResultOr<Region*> MBVGADevice::mmap(Process& process, FileDescription&, Virtual
{ {
REQUIRE_PROMISE(video); REQUIRE_PROMISE(video);
if (!shared) if (!shared)
return KResult(-ENODEV); return ENODEV;
ASSERT(offset == 0); ASSERT(offset == 0);
ASSERT(size == framebuffer_size_in_bytes()); ASSERT(size == framebuffer_size_in_bytes());
auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes());
if (!vmobject) if (!vmobject)
return KResult(-ENOMEM); return ENOMEM;
return process.allocate_region_with_vmobject( return process.allocate_region_with_vmobject(
preferred_vaddr, preferred_vaddr,
framebuffer_size_in_bytes(), framebuffer_size_in_bytes(),

View file

@ -288,7 +288,7 @@ KResultOr<size_t> PS2MouseDevice::read(FileDescription&, size_t, UserOrKernelBuf
#endif #endif
size_t bytes_read_from_packet = min(remaining_space_in_buffer, sizeof(MousePacket)); size_t bytes_read_from_packet = min(remaining_space_in_buffer, sizeof(MousePacket));
if (!buffer.write(&packet, nread, bytes_read_from_packet)) if (!buffer.write(&packet, nread, bytes_read_from_packet))
return KResult(-EFAULT); return EFAULT;
nread += bytes_read_from_packet; nread += bytes_read_from_packet;
remaining_space_in_buffer -= bytes_read_from_packet; remaining_space_in_buffer -= bytes_read_from_packet;

View file

@ -50,7 +50,7 @@ KResultOr<size_t> RandomDevice::read(FileDescription&, size_t, UserOrKernelBuffe
return (ssize_t)data_size; return (ssize_t)data_size;
}); });
if (!success) if (!success)
return KResult(-EFAULT); return EFAULT;
return size; return size;
} }

View file

@ -236,11 +236,11 @@ KResultOr<size_t> SB16::write(FileDescription&, size_t, const UserOrKernelBuffer
if (!m_dma_region) { if (!m_dma_region) {
auto page = MM.allocate_supervisor_physical_page(); auto page = MM.allocate_supervisor_physical_page();
if (!page) if (!page)
return KResult(-ENOMEM); return ENOMEM;
auto vmobject = AnonymousVMObject::create_with_physical_page(*page); auto vmobject = AnonymousVMObject::create_with_physical_page(*page);
m_dma_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_SIZE, "SB16 DMA buffer", Region::Access::Write); m_dma_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_SIZE, "SB16 DMA buffer", Region::Access::Write);
if (!m_dma_region) if (!m_dma_region)
return KResult(-ENOMEM); return ENOMEM;
} }
#ifdef SB16_DEBUG #ifdef SB16_DEBUG
@ -249,7 +249,7 @@ KResultOr<size_t> SB16::write(FileDescription&, size_t, const UserOrKernelBuffer
ASSERT(length <= PAGE_SIZE); ASSERT(length <= PAGE_SIZE);
const int BLOCK_SIZE = 32 * 1024; const int BLOCK_SIZE = 32 * 1024;
if (length > BLOCK_SIZE) { if (length > BLOCK_SIZE) {
return KResult(-ENOSPC); return ENOSPC;
} }
u8 mode = (u8)SampleFormat::Signed | (u8)SampleFormat::Stereo; u8 mode = (u8)SampleFormat::Signed | (u8)SampleFormat::Stereo;
@ -257,7 +257,7 @@ KResultOr<size_t> SB16::write(FileDescription&, size_t, const UserOrKernelBuffer
const int sample_rate = 44100; const int sample_rate = 44100;
set_sample_rate(sample_rate); set_sample_rate(sample_rate);
if (!data.read(m_dma_region->vaddr().as_ptr(), length)) if (!data.read(m_dma_region->vaddr().as_ptr(), length))
return KResult(-EFAULT); return EFAULT;
dma_start(length); dma_start(length);
// 16-bit single-cycle output. // 16-bit single-cycle output.

View file

@ -59,7 +59,7 @@ KResultOr<size_t> SerialDevice::read(FileDescription&, size_t, UserOrKernelBuffe
return (ssize_t)data_size; return (ssize_t)data_size;
}); });
if (nwritten < 0) if (nwritten < 0)
return KResult(nwritten); return KResult((ErrnoCode)-nwritten);
return size; return size;
} }
@ -83,7 +83,7 @@ KResultOr<size_t> SerialDevice::write(FileDescription&, size_t, const UserOrKern
return (ssize_t)data_size; return (ssize_t)data_size;
}); });
if (nread < 0) if (nread < 0)
return KResult(nread); return KResult((ErrnoCode)-nread);
return (size_t)nread; return (size_t)nread;
} }

View file

@ -48,7 +48,7 @@ KResultOr<size_t> ZeroDevice::read(FileDescription&, size_t, UserOrKernelBuffer&
{ {
ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size); ssize_t count = min(static_cast<size_t>(PAGE_SIZE), size);
if (!buffer.memset(0, count)) if (!buffer.memset(0, count))
return KResult(-EFAULT); return EFAULT;
return count; return count;
} }

View file

@ -42,10 +42,10 @@ AnonymousFile::~AnonymousFile()
KResultOr<Region*> AnonymousFile::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) KResultOr<Region*> AnonymousFile::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared)
{ {
if (offset != 0) if (offset != 0)
return KResult(-EINVAL); return EINVAL;
if (size != m_vmobject->size()) if (size != m_vmobject->size())
return KResult(-EINVAL); return EINVAL;
return process.allocate_region_with_vmobject(preferred_vaddr, size, m_vmobject, offset, {}, prot, shared); return process.allocate_region_with_vmobject(preferred_vaddr, size, m_vmobject, offset, {}, prot, shared);
} }

View file

@ -46,8 +46,8 @@ private:
virtual String absolute_path(const FileDescription&) const override { return ":anonymous-file:"; } virtual String absolute_path(const FileDescription&) const override { return ":anonymous-file:"; }
virtual bool can_read(const FileDescription&, size_t) const override { return false; } virtual bool can_read(const FileDescription&, size_t) const override { return false; }
virtual bool can_write(const FileDescription&, size_t) const override { return false; } virtual bool can_write(const FileDescription&, size_t) const override { return false; }
virtual KResultOr<size_t> read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override { return KResult(-ENOTSUP); } virtual KResultOr<size_t> read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override { return KResult(-ENOTSUP); } virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
explicit AnonymousFile(NonnullRefPtr<AnonymousVMObject>); explicit AnonymousFile(NonnullRefPtr<AnonymousVMObject>);

View file

@ -169,7 +169,7 @@ KResult BlockBasedFS::write_block(unsigned index, const UserOrKernelBuffer& data
return result; return result;
} }
if (!data.read(entry.data + offset, count)) if (!data.read(entry.data + offset, count))
return KResult(-EFAULT); return EFAULT;
cache().mark_dirty(entry); cache().mark_dirty(entry);
entry.has_data = true; entry.has_data = true;
@ -261,7 +261,7 @@ KResult BlockBasedFS::read_block(unsigned index, UserOrKernelBuffer* buffer, siz
entry.has_data = true; entry.has_data = true;
} }
if (buffer && !buffer->write(entry.data + offset, count)) if (buffer && !buffer->write(entry.data + offset, count))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
} }
@ -269,7 +269,7 @@ KResult BlockBasedFS::read_blocks(unsigned index, unsigned count, UserOrKernelBu
{ {
ASSERT(m_logical_block_size); ASSERT(m_logical_block_size);
if (!count) if (!count)
return KResult(-EINVAL); return EINVAL;
if (count == 1) if (count == 1)
return read_block(index, &buffer, block_size(), 0, allow_cache); return read_block(index, &buffer, block_size(), 0, allow_cache);
auto out = buffer; auto out = buffer;

View file

@ -124,17 +124,17 @@ ssize_t DevFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileD
KResultOr<NonnullRefPtr<Inode>> DevFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t) KResultOr<NonnullRefPtr<Inode>> DevFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
{ {
return KResult(-EROFS); return EROFS;
} }
KResult DevFSInode::add_child(Inode&, const StringView&, mode_t) KResult DevFSInode::add_child(Inode&, const StringView&, mode_t)
{ {
return KResult(-EROFS); return EROFS;
} }
KResult DevFSInode::remove_child(const StringView&) KResult DevFSInode::remove_child(const StringView&)
{ {
return KResult(-EROFS); return EROFS;
} }
KResultOr<size_t> DevFSInode::directory_entry_count() const KResultOr<size_t> DevFSInode::directory_entry_count() const
@ -144,17 +144,17 @@ KResultOr<size_t> DevFSInode::directory_entry_count() const
KResult DevFSInode::chmod(mode_t) KResult DevFSInode::chmod(mode_t)
{ {
return KResult(-EPERM); return EPERM;
} }
KResult DevFSInode::chown(uid_t, gid_t) KResult DevFSInode::chown(uid_t, gid_t)
{ {
return KResult(-EPERM); return EPERM;
} }
KResult DevFSInode::truncate(u64) KResult DevFSInode::truncate(u64)
{ {
return KResult(-EPERM); return EPERM;
} }
String DevFSLinkInode::name() const String DevFSLinkInode::name() const
@ -221,7 +221,7 @@ InodeMetadata DevFSDirectoryInode::metadata() const
KResult DevFSDirectoryInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const KResult DevFSDirectoryInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const
{ {
LOCKER(m_lock); LOCKER(m_lock);
return KResult(-EINVAL); return EINVAL;
} }
RefPtr<Inode> DevFSDirectoryInode::lookup(StringView) RefPtr<Inode> DevFSDirectoryInode::lookup(StringView)
{ {
@ -288,10 +288,10 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
if (metadata.is_directory()) { if (metadata.is_directory()) {
for (auto& folder : m_subfolders) { for (auto& folder : m_subfolders) {
if (folder.name() == name) if (folder.name() == name)
return KResult(-EEXIST); return EEXIST;
} }
if (name != "pts") if (name != "pts")
return KResult(-EROFS); return EROFS;
auto new_directory_inode = adopt(*new DevFSPtsDirectoryInode(m_parent_fs)); auto new_directory_inode = adopt(*new DevFSPtsDirectoryInode(m_parent_fs));
m_subfolders.append(new_directory_inode); m_subfolders.append(new_directory_inode);
m_parent_fs.m_nodes.append(new_directory_inode); m_parent_fs.m_nodes.append(new_directory_inode);
@ -300,7 +300,7 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
if (metadata.is_symlink()) { if (metadata.is_symlink()) {
for (auto& link : m_links) { for (auto& link : m_links) {
if (link.name() == name) if (link.name() == name)
return KResult(-EEXIST); return EEXIST;
} }
dbgln("DevFS: Success on create new symlink"); dbgln("DevFS: Success on create new symlink");
auto new_link_inode = adopt(*new DevFSLinkInode(m_parent_fs, name)); auto new_link_inode = adopt(*new DevFSLinkInode(m_parent_fs, name));
@ -308,7 +308,7 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
m_parent_fs.m_nodes.append(new_link_inode); m_parent_fs.m_nodes.append(new_link_inode);
return new_link_inode; return new_link_inode;
} }
return KResult(-EROFS); return EROFS;
} }
DevFSRootDirectoryInode::~DevFSRootDirectoryInode() DevFSRootDirectoryInode::~DevFSRootDirectoryInode()

View file

@ -143,7 +143,7 @@ InodeMetadata DevPtsFSInode::metadata() const
KResult DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)> callback) const KResult DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)> callback) const
{ {
if (identifier().index() > 1) if (identifier().index() > 1)
return KResult(-ENOTDIR); return ENOTDIR;
callback({ ".", identifier(), 0 }); callback({ ".", identifier(), 0 });
callback({ "..", identifier(), 0 }); callback({ "..", identifier(), 0 });
@ -187,27 +187,27 @@ void DevPtsFSInode::flush_metadata()
KResult DevPtsFSInode::add_child(Inode&, const StringView&, mode_t) KResult DevPtsFSInode::add_child(Inode&, const StringView&, mode_t)
{ {
return KResult(-EROFS); return EROFS;
} }
KResultOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t) KResultOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
{ {
return KResult(-EROFS); return EROFS;
} }
KResult DevPtsFSInode::remove_child(const StringView&) KResult DevPtsFSInode::remove_child(const StringView&)
{ {
return KResult(-EROFS); return EROFS;
} }
KResult DevPtsFSInode::chmod(mode_t) KResult DevPtsFSInode::chmod(mode_t)
{ {
return KResult(-EPERM); return EPERM;
} }
KResult DevPtsFSInode::chown(uid_t, gid_t) KResult DevPtsFSInode::chown(uid_t, gid_t)
{ {
return KResult(-EPERM); return EPERM;
} }
} }

View file

@ -233,7 +233,7 @@ Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks) const
return {}; return {};
} }
bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, const Vector<BlockIndex>& blocks) KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, const Vector<BlockIndex>& blocks)
{ {
LOCKER(m_lock); LOCKER(m_lock);
@ -241,7 +241,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
e2inode.i_blocks = 0; e2inode.i_blocks = 0;
memset(e2inode.i_block, 0, sizeof(e2inode.i_block)); memset(e2inode.i_block, 0, sizeof(e2inode.i_block));
write_ext2_inode(inode_index, e2inode); write_ext2_inode(inode_index, e2inode);
return true; return KSuccess;
} }
// NOTE: There is a mismatch between i_blocks and blocks.size() since i_blocks includes meta blocks and blocks.size() does not. // NOTE: There is a mismatch between i_blocks and blocks.size() since i_blocks includes meta blocks and blocks.size() does not.
@ -279,7 +279,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
} }
if (!remaining_blocks) if (!remaining_blocks)
return true; return KSuccess;
const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&super_block()); const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&super_block());
@ -315,12 +315,13 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
stream.fill_to_end(0); stream.fill_to_end(0);
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
int err = write_block(e2inode.i_block[EXT2_IND_BLOCK], buffer, stream.size()); auto result = write_block(e2inode.i_block[EXT2_IND_BLOCK], buffer, stream.size());
ASSERT(err >= 0); if (result.is_error())
return result;
} }
if (!remaining_blocks) if (!remaining_blocks)
return true; return KSuccess;
bool dind_block_dirty = false; bool dind_block_dirty = false;
@ -356,9 +357,8 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
auto buffer = UserOrKernelBuffer::for_kernel_buffer(dind_block_contents.data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(dind_block_contents.data());
auto result = read_block(e2inode.i_block[EXT2_DIND_BLOCK], &buffer, block_size()); auto result = read_block(e2inode.i_block[EXT2_DIND_BLOCK], &buffer, block_size());
if (result.is_error()) { if (result.is_error()) {
// FIXME: Propagate the error
dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error()); dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error());
return false; return result;
} }
} }
auto* dind_block_as_pointers = (unsigned*)dind_block_contents.data(); auto* dind_block_as_pointers = (unsigned*)dind_block_contents.data();
@ -384,9 +384,8 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
auto buffer = UserOrKernelBuffer::for_kernel_buffer(ind_block_contents.data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(ind_block_contents.data());
auto result = read_block(indirect_block_index, &buffer, block_size()); auto result = read_block(indirect_block_index, &buffer, block_size());
if (result.is_error()) { if (result.is_error()) {
// FIXME: Propagate the error
dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error()); dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error());
return false; return result;
} }
} }
auto* ind_block_as_pointers = (unsigned*)ind_block_contents.data(); auto* ind_block_as_pointers = (unsigned*)ind_block_contents.data();
@ -432,7 +431,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
} }
if (!remaining_blocks) if (!remaining_blocks)
return true; return KSuccess;
// FIXME: Implement! // FIXME: Implement!
dbgln("we don't know how to write tind ext2fs blocks yet!"); dbgln("we don't know how to write tind ext2fs blocks yet!");
@ -799,7 +798,7 @@ KResult Ext2FSInode::resize(u64 new_size)
if (blocks_needed_after > blocks_needed_before) { if (blocks_needed_after > blocks_needed_before) {
u32 additional_blocks_needed = blocks_needed_after - blocks_needed_before; u32 additional_blocks_needed = blocks_needed_after - blocks_needed_before;
if (additional_blocks_needed > fs().super_block().s_free_blocks_count) if (additional_blocks_needed > fs().super_block().s_free_blocks_count)
return KResult(-ENOSPC); return ENOSPC;
} }
Vector<Ext2FS::BlockIndex> block_list; Vector<Ext2FS::BlockIndex> block_list;
@ -825,9 +824,9 @@ KResult Ext2FSInode::resize(u64 new_size)
} }
} }
int err = fs().write_block_list_for_inode(index(), m_raw_inode, block_list); auto result = fs().write_block_list_for_inode(index(), m_raw_inode, block_list);
if (err < 0) if (result.is_error())
return KResult(err); return result;
m_raw_inode.i_size = new_size; m_raw_inode.i_size = new_size;
set_metadata_dirty(true); set_metadata_dirty(true);
@ -844,7 +843,7 @@ KResult Ext2FSInode::resize(u64 new_size)
while (bytes_to_clear) { while (bytes_to_clear) {
auto nwritten = write_bytes(clear_from, min(sizeof(zero_buffer), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr); auto nwritten = write_bytes(clear_from, min(sizeof(zero_buffer), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr);
if (nwritten < 0) if (nwritten < 0)
return KResult(-nwritten); return KResult((ErrnoCode)-nwritten);
ASSERT(nwritten != 0); ASSERT(nwritten != 0);
bytes_to_clear -= nwritten; bytes_to_clear -= nwritten;
clear_from += nwritten; clear_from += nwritten;
@ -1056,7 +1055,7 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
ASSERT(is_directory()); ASSERT(is_directory());
if (name.length() > EXT2_NAME_LEN) if (name.length() > EXT2_NAME_LEN)
return KResult(-ENAMETOOLONG); return ENAMETOOLONG;
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
dbgln("Ext2FSInode::add_child: Adding inode {} with name '{}' and mode {:o} to directory {}", child.index(), name, mode, index()); dbgln("Ext2FSInode::add_child: Adding inode {} with name '{}' and mode {:o} to directory {}", child.index(), name, mode, index());
@ -1078,7 +1077,7 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
if (name_already_exists) { if (name_already_exists) {
dbgln("Ext2FSInode::add_child: Name '{}' already exists in inode {}", name, index()); dbgln("Ext2FSInode::add_child: Name '{}' already exists in inode {}", name, index());
return KResult(-EEXIST); return EEXIST;
} }
result = child.increment_link_count(); result = child.increment_link_count();
@ -1104,7 +1103,7 @@ KResult Ext2FSInode::remove_child(const StringView& name)
auto it = m_lookup_cache.find(name); auto it = m_lookup_cache.find(name);
if (it == m_lookup_cache.end()) if (it == m_lookup_cache.end())
return KResult(-ENOENT); return ENOENT;
auto child_inode_index = (*it).value; auto child_inode_index = (*it).value;
InodeIdentifier child_id { fsid(), child_inode_index }; InodeIdentifier child_id { fsid(), child_inode_index };
@ -1125,7 +1124,7 @@ KResult Ext2FSInode::remove_child(const StringView& name)
bool success = write_directory(entries); bool success = write_directory(entries);
if (!success) { if (!success) {
// FIXME: Plumb error from write_directory(). // FIXME: Plumb error from write_directory().
return KResult(-EIO); return EIO;
} }
m_lookup_cache.remove(name); m_lookup_cache.remove(name);
@ -1487,10 +1486,10 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
ASSERT(parent_inode); ASSERT(parent_inode);
if (static_cast<const Ext2FSInode&>(*parent_inode).m_raw_inode.i_links_count == 0) if (static_cast<const Ext2FSInode&>(*parent_inode).m_raw_inode.i_links_count == 0)
return KResult(-ENOENT); return ENOENT;
if (name.length() > EXT2_NAME_LEN) if (name.length() > EXT2_NAME_LEN)
return KResult(-ENAMETOOLONG); return ENAMETOOLONG;
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
dbgln("Ext2FS: Adding inode '{}' (mode {:o}) to parent directory {}", name, mode, parent_inode->index()); dbgln("Ext2FS: Adding inode '{}' (mode {:o}) to parent directory {}", name, mode, parent_inode->index());
@ -1499,14 +1498,14 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
size_t needed_blocks = ceil_div(static_cast<size_t>(size), block_size()); size_t needed_blocks = ceil_div(static_cast<size_t>(size), block_size());
if ((size_t)needed_blocks > super_block().s_free_blocks_count) { if ((size_t)needed_blocks > super_block().s_free_blocks_count) {
dbgln("Ext2FS: create_inode: not enough free blocks"); dbgln("Ext2FS: create_inode: not enough free blocks");
return KResult(-ENOSPC); return ENOSPC;
} }
// NOTE: This doesn't commit the inode allocation just yet! // NOTE: This doesn't commit the inode allocation just yet!
auto inode_id = find_a_free_inode(0, size); auto inode_id = find_a_free_inode(0, size);
if (!inode_id) { if (!inode_id) {
klog() << "Ext2FS: create_inode: allocate_inode failed"; klog() << "Ext2FS: create_inode: allocate_inode failed";
return KResult(-ENOSPC); return ENOSPC;
} }
auto blocks = allocate_blocks(group_index_from_inode(inode_id), needed_blocks); auto blocks = allocate_blocks(group_index_from_inode(inode_id), needed_blocks);
@ -1537,8 +1536,9 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
else if (is_block_device(mode)) else if (is_block_device(mode))
e2inode.i_block[1] = dev; e2inode.i_block[1] = dev;
success = write_block_list_for_inode(inode_id, e2inode, blocks); auto result = write_block_list_for_inode(inode_id, e2inode, blocks);
ASSERT(success); if (result.is_error())
return result;
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
dbgln("Ext2FS: writing initial metadata for inode {}", inode_id); dbgln("Ext2FS: writing initial metadata for inode {}", inode_id);
@ -1554,8 +1554,9 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
// If we've already computed a block list, no sense in throwing it away. // If we've already computed a block list, no sense in throwing it away.
static_cast<Ext2FSInode&>(*inode).m_block_list = move(blocks); static_cast<Ext2FSInode&>(*inode).m_block_list = move(blocks);
auto result = parent_inode->add_child(*inode, name, mode); result = parent_inode->add_child(*inode, name, mode);
ASSERT(result.is_success()); if (result.is_error())
return result;
return inode.release_nonnull(); return inode.release_nonnull();
} }
@ -1632,9 +1633,9 @@ KResult Ext2FSInode::increment_link_count()
{ {
LOCKER(m_lock); LOCKER(m_lock);
if (fs().is_readonly()) if (fs().is_readonly())
return KResult(-EROFS); return EROFS;
if (m_raw_inode.i_links_count == max_link_count) if (m_raw_inode.i_links_count == max_link_count)
return KResult(-EMLINK); return EMLINK;
++m_raw_inode.i_links_count; ++m_raw_inode.i_links_count;
set_metadata_dirty(true); set_metadata_dirty(true);
return KSuccess; return KSuccess;
@ -1644,7 +1645,7 @@ KResult Ext2FSInode::decrement_link_count()
{ {
LOCKER(m_lock); LOCKER(m_lock);
if (fs().is_readonly()) if (fs().is_readonly())
return KResult(-EROFS); return EROFS;
ASSERT(m_raw_inode.i_links_count); ASSERT(m_raw_inode.i_links_count);
--m_raw_inode.i_links_count; --m_raw_inode.i_links_count;
if (ref_count() == 1 && m_raw_inode.i_links_count == 0) if (ref_count() == 1 && m_raw_inode.i_links_count == 0)
@ -1730,7 +1731,7 @@ KResult Ext2FS::prepare_to_unmount() const
for (auto& it : m_inode_cache) { for (auto& it : m_inode_cache) {
if (it.value->ref_count() > 1) if (it.value->ref_count() > 1)
return KResult(-EBUSY); return EBUSY;
} }
m_inode_cache.clear(); m_inode_cache.clear();

View file

@ -148,7 +148,7 @@ private:
Vector<BlockIndex> block_list_for_inode_impl(const ext2_inode&, bool include_block_list_blocks = false) const; Vector<BlockIndex> block_list_for_inode_impl(const ext2_inode&, bool include_block_list_blocks = false) const;
Vector<BlockIndex> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const; Vector<BlockIndex> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const;
bool write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&); KResult write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&);
bool get_inode_allocation_state(InodeIndex) const; bool get_inode_allocation_state(InodeIndex) const;
bool set_inode_allocation_state(InodeIndex, bool); bool set_inode_allocation_state(InodeIndex, bool);

View file

@ -61,7 +61,7 @@ int File::ioctl(FileDescription&, unsigned, FlatPtr)
KResultOr<Region*> File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int, bool) KResultOr<Region*> File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int, bool)
{ {
return KResult(-ENODEV); return ENODEV;
} }
} }

View file

@ -115,13 +115,13 @@ public:
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) = 0; virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, 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);
virtual KResult stat(::stat&) const { return KResult(-EBADF); } virtual KResult stat(::stat&) const { return EBADF; }
virtual String absolute_path(const FileDescription&) const = 0; virtual String absolute_path(const FileDescription&) const = 0;
virtual KResult truncate(u64) { return KResult(-EINVAL); } virtual KResult truncate(u64) { return EINVAL; }
virtual KResult chown(FileDescription&, uid_t, gid_t) { return KResult(-EBADF); } virtual KResult chown(FileDescription&, uid_t, gid_t) { return EBADF; }
virtual KResult chmod(FileDescription&, mode_t) { return KResult(-EBADF); } virtual KResult chmod(FileDescription&, mode_t) { return EBADF; }
virtual const char* class_name() const = 0; virtual const char* class_name() const = 0;

View file

@ -82,7 +82,7 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer); auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer);
nread = read_bytes(offset, sizeof(buffer), buf, description); nread = read_bytes(offset, sizeof(buffer), buf, description);
if (nread < 0) if (nread < 0)
return KResult(nread); return KResult((ErrnoCode)-nread);
ASSERT(nread <= (ssize_t)sizeof(buffer)); ASSERT(nread <= (ssize_t)sizeof(buffer));
if (nread <= 0) if (nread <= 0)
break; break;
@ -93,12 +93,12 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
} }
if (nread < 0) { if (nread < 0) {
klog() << "Inode::read_entire: ERROR: " << nread; klog() << "Inode::read_entire: ERROR: " << nread;
return KResult(nread); return KResult((ErrnoCode)-nread);
} }
auto entire_file = builder.build(); auto entire_file = builder.build();
if (!entire_file) if (!entire_file)
return KResult(-ENOMEM); return ENOMEM;
return entire_file.release_nonnull(); return entire_file.release_nonnull();
} }
@ -168,12 +168,12 @@ int Inode::set_mtime(time_t)
KResult Inode::increment_link_count() KResult Inode::increment_link_count()
{ {
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Inode::decrement_link_count() KResult Inode::decrement_link_count()
{ {
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
void Inode::set_shared_vmobject(SharedInodeVMObject& vmobject) void Inode::set_shared_vmobject(SharedInodeVMObject& vmobject)
@ -271,7 +271,7 @@ KResult Inode::prepare_to_write_data()
// We should funnel everything through an interface at the VFS layer so this can happen from a single place. // We should funnel everything through an interface at the VFS layer so this can happen from a single place.
LOCKER(m_lock); LOCKER(m_lock);
if (fs().is_readonly()) if (fs().is_readonly())
return KResult(-EROFS); return EROFS;
auto metadata = this->metadata(); auto metadata = this->metadata();
if (metadata.is_setuid() || metadata.is_setgid()) { if (metadata.is_setuid() || metadata.is_setgid()) {
dbgln("Inode::prepare_to_write_data(): Stripping SUID/SGID bits from {}", identifier()); dbgln("Inode::prepare_to_write_data(): Stripping SUID/SGID bits from {}", identifier());

View file

@ -52,7 +52,7 @@ KResultOr<size_t> InodeFile::read(FileDescription& description, size_t offset, U
evaluate_block_conditions(); evaluate_block_conditions();
} }
if (nread < 0) if (nread < 0)
return KResult(nread); return KResult((ErrnoCode)-nread);
return nread; return nread;
} }
@ -65,7 +65,7 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, size_t offset,
evaluate_block_conditions(); evaluate_block_conditions();
} }
if (nwritten < 0) if (nwritten < 0)
return KResult(nwritten); return KResult((ErrnoCode)-nwritten);
return nwritten; return nwritten;
} }
@ -78,7 +78,7 @@ KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& descriptio
else else
vmobject = PrivateInodeVMObject::create_with_inode(inode()); vmobject = PrivateInodeVMObject::create_with_inode(inode());
if (!vmobject) if (!vmobject)
return KResult(-ENOMEM); return ENOMEM;
return process.allocate_region_with_vmobject(preferred_vaddr, size, *vmobject, offset, description.absolute_path(), prot, shared); return process.allocate_region_with_vmobject(preferred_vaddr, size, *vmobject, offset, description.absolute_path(), prot, shared);
} }
@ -95,8 +95,8 @@ KResult InodeFile::truncate(u64 size)
if (truncate_result.is_error()) if (truncate_result.is_error())
return truncate_result; return truncate_result;
int mtime_result = m_inode->set_mtime(kgettimeofday().tv_sec); int mtime_result = m_inode->set_mtime(kgettimeofday().tv_sec);
if (mtime_result != 0) if (mtime_result < 0)
return KResult(mtime_result); return KResult((ErrnoCode)-mtime_result);
return KSuccess; return KSuccess;
} }

View file

@ -106,7 +106,7 @@ struct InodeMetadata {
KResult stat(stat& buffer) const KResult stat(stat& buffer) const
{ {
if (!is_valid()) if (!is_valid())
return KResult(-EIO); return EIO;
buffer.st_rdev = encoded_device(major_device, minor_device); buffer.st_rdev = encoded_device(major_device, minor_device);
buffer.st_ino = inode.index(); buffer.st_ino = inode.index();
buffer.st_mode = mode; buffer.st_mode = mode;

View file

@ -77,14 +77,14 @@ KResultOr<size_t> InodeWatcher::read(FileDescription&, size_t, UserOrKernelBuffe
return (ssize_t)data_bytes; return (ssize_t)data_bytes;
}); });
if (nwritten < 0) if (nwritten < 0)
return KResult(nwritten); return KResult((ErrnoCode)-nwritten);
evaluate_block_conditions(); evaluate_block_conditions();
return bytes_to_write; return bytes_to_write;
} }
KResultOr<size_t> InodeWatcher::write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) KResultOr<size_t> InodeWatcher::write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t)
{ {
return KResult(-EIO); return EIO;
} }
String InodeWatcher::absolute_path(const FileDescription&) const String InodeWatcher::absolute_path(const FileDescription&) const

View file

@ -532,7 +532,7 @@ KResult Plan9FS::post_message(Message& message, RefPtr<ReceiveCompletion> comple
if (!description.can_write()) { if (!description.can_write()) {
auto unblock_flags = Thread::FileBlocker::BlockFlags::None; auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::WriteBlocker>({}, description, unblock_flags).was_interrupted()) if (Thread::current()->block<Thread::WriteBlocker>({}, description, unblock_flags).was_interrupted())
return KResult(-EINTR); return EINTR;
} }
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>(data)); auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>(data));
auto nwritten_or_error = description.write(data_buffer, size); auto nwritten_or_error = description.write(data_buffer, size);
@ -553,7 +553,7 @@ KResult Plan9FS::do_read(u8* data, size_t size)
if (!description.can_read()) { if (!description.can_read()) {
auto unblock_flags = Thread::FileBlocker::BlockFlags::None; auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted()) if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted())
return KResult(-EINTR); return EINTR;
} }
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data); auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data);
auto nread_or_error = description.read(data_buffer, size); auto nread_or_error = description.read(data_buffer, size);
@ -561,7 +561,7 @@ KResult Plan9FS::do_read(u8* data, size_t size)
return nread_or_error.error(); return nread_or_error.error();
auto nread = nread_or_error.value(); auto nread = nread_or_error.value();
if (nread == 0) if (nread == 0)
return KResult(-EIO); return EIO;
data += nread; data += nread;
size -= nread; size -= nread;
} }
@ -582,7 +582,7 @@ KResult Plan9FS::read_and_dispatch_one_message()
auto buffer = KBuffer::try_create_with_size(header.size, Region::Access::Read | Region::Access::Write); auto buffer = KBuffer::try_create_with_size(header.size, Region::Access::Read | Region::Access::Write);
if (!buffer) if (!buffer)
return KResult(-ENOMEM); return ENOMEM;
// Copy the already read header into the buffer. // Copy the already read header into the buffer.
memcpy(buffer->data(), &header, sizeof(header)); memcpy(buffer->data(), &header, sizeof(header));
result = do_read(buffer->data() + sizeof(header), header.size - sizeof(header)); result = do_read(buffer->data() + sizeof(header), header.size - sizeof(header));
@ -622,11 +622,11 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
if (result.is_error()) if (result.is_error())
return result; return result;
if (Thread::current()->block<Plan9FS::Blocker>({}, *this, message, completion).was_interrupted()) if (Thread::current()->block<Plan9FS::Blocker>({}, *this, message, completion).was_interrupted())
return KResult(-EINTR); return EINTR;
if (completion->result.is_error()) { if (completion->result.is_error()) {
dbgln("Plan9FS: Message was aborted with error {}", completion->result.error()); dbgln("Plan9FS: Message was aborted with error {}", completion->result.error());
return KResult(-EIO); return EIO;
} }
auto reply_type = message.type(); auto reply_type = message.type();
@ -635,7 +635,7 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
// Contains a numerical Linux errno; hopefully our errno numbers match. // Contains a numerical Linux errno; hopefully our errno numbers match.
u32 error_code; u32 error_code;
message >> error_code; message >> error_code;
return KResult(-error_code); return KResult((ErrnoCode)error_code);
} else if (reply_type == Message::Type::Rerror) { } else if (reply_type == Message::Type::Rerror) {
// Contains an error message. We could attempt to parse it, but for now // Contains an error message. We could attempt to parse it, but for now
// we simply return -EIO instead. In 9P200.u, it can also contain a // we simply return -EIO instead. In 9P200.u, it can also contain a
@ -643,12 +643,12 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
StringView error_name; StringView error_name;
message >> error_name; message >> error_name;
dbgln("Plan9FS: Received error name {}", error_name); dbgln("Plan9FS: Received error name {}", error_name);
return KResult(-EIO); return EIO;
} else if ((u8)reply_type != (u8)request_type + 1) { } else if ((u8)reply_type != (u8)request_type + 1) {
// Other than those error messages. we only expect the matching reply // Other than those error messages. we only expect the matching reply
// message type. // message type.
dbgln("Plan9FS: Received unexpected message type {} in response to {}", (u8)reply_type, (u8)request_type); dbgln("Plan9FS: Received unexpected message type {} in response to {}", (u8)reply_type, (u8)request_type);
return KResult(-EIO); return EIO;
} else { } else {
return KSuccess; return KSuccess;
} }
@ -944,7 +944,7 @@ KResult Plan9FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEnt
return result; return result;
} else { } else {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
} }
@ -964,31 +964,31 @@ RefPtr<Inode> Plan9FSInode::lookup(StringView name)
KResultOr<NonnullRefPtr<Inode>> Plan9FSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t) KResultOr<NonnullRefPtr<Inode>> Plan9FSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
{ {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Plan9FSInode::add_child(Inode&, const StringView&, mode_t) KResult Plan9FSInode::add_child(Inode&, const StringView&, mode_t)
{ {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Plan9FSInode::remove_child(const StringView&) KResult Plan9FSInode::remove_child(const StringView&)
{ {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Plan9FSInode::chmod(mode_t) KResult Plan9FSInode::chmod(mode_t)
{ {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Plan9FSInode::chown(uid_t, gid_t) KResult Plan9FSInode::chown(uid_t, gid_t)
{ {
// TODO // TODO
return KResult(-ENOTIMPL); return ENOTIMPL;
} }
KResult Plan9FSInode::truncate(u64 new_size) KResult Plan9FSInode::truncate(u64 new_size)

View file

@ -1073,14 +1073,14 @@ KResult ProcFSInode::refresh_data(FileDescription& description) const
} }
KBufferBuilder builder(buffer, true); KBufferBuilder builder(buffer, true);
if (!read_callback(identifier(), builder)) if (!read_callback(identifier(), builder))
return KResult(-ENOENT); return ENOENT;
// We don't use builder.build() here, which would steal our buffer // We don't use builder.build() here, which would steal our buffer
// and turn it into an OwnPtr. Instead, just flush to the buffer so // and turn it into an OwnPtr. Instead, just flush to the buffer so
// that we can read all the data that was written. // that we can read all the data that was written.
if (!builder.flush()) if (!builder.flush())
return KResult(-ENOMEM); return ENOMEM;
if (!buffer) if (!buffer)
return KResult(-ENOMEM); return ENOMEM;
return KSuccess; return KSuccess;
} }
@ -1220,7 +1220,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
#endif #endif
if (!Kernel::is_directory(identifier())) if (!Kernel::is_directory(identifier()))
return KResult(-ENOTDIR); return ENOTDIR;
auto proc_file_type = to_proc_file_type(identifier()); auto proc_file_type = to_proc_file_type(identifier());
auto parent_id = to_parent_id(identifier()); auto parent_id = to_parent_id(identifier());
@ -1263,7 +1263,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
auto pid = to_pid(identifier()); auto pid = to_pid(identifier());
auto process = Process::from_pid(pid); auto process = Process::from_pid(pid);
if (!process) if (!process)
return KResult(-ENOENT); return ENOENT;
for (auto& entry : fs().m_entries) { for (auto& entry : fs().m_entries) {
if (entry.proc_file_type > __FI_PID_Start && entry.proc_file_type < __FI_PID_End) { if (entry.proc_file_type > __FI_PID_Start && entry.proc_file_type < __FI_PID_End) {
if (entry.proc_file_type == FI_PID_exe && !process->executable()) if (entry.proc_file_type == FI_PID_exe && !process->executable())
@ -1278,7 +1278,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
auto pid = to_pid(identifier()); auto pid = to_pid(identifier());
auto process = Process::from_pid(pid); auto process = Process::from_pid(pid);
if (!process) if (!process)
return KResult(-ENOENT); return ENOENT;
for (int i = 0; i < process->max_open_file_descriptors(); ++i) { for (int i = 0; i < process->max_open_file_descriptors(); ++i) {
auto description = process->file_description(i); auto description = process->file_description(i);
if (!description) if (!description)
@ -1293,7 +1293,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
auto pid = to_pid(identifier()); auto pid = to_pid(identifier());
auto process = Process::from_pid(pid); auto process = Process::from_pid(pid);
if (!process) if (!process)
return KResult(-ENOENT); return ENOENT;
process->for_each_thread([&](Thread& thread) -> IterationDecision { process->for_each_thread([&](Thread& thread) -> IterationDecision {
int tid = thread.tid().value(); int tid = thread.tid().value();
char name[16]; char name[16];
@ -1478,7 +1478,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
auto proc_file_type = to_proc_file_type(identifier()); auto proc_file_type = to_proc_file_type(identifier());
auto process = Process::from_pid(pid); auto process = Process::from_pid(pid);
if (!process) if (!process)
return KResult(-ENOENT); return ENOENT;
if (to_proc_parent_directory(identifier()) == PDI_PID_fd) { if (to_proc_parent_directory(identifier()) == PDI_PID_fd) {
if (out_parent) if (out_parent)
@ -1486,7 +1486,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
int fd = to_fd(identifier()); int fd = to_fd(identifier());
auto description = process->file_description(fd); auto description = process->file_description(fd);
if (!description) if (!description)
return KResult(-ENOENT); return ENOENT;
auto proxy_inode = ProcFSProxyInode::create(const_cast<ProcFS&>(fs()), *description); auto proxy_inode = ProcFSProxyInode::create(const_cast<ProcFS&>(fs()), *description);
return Custody::create(&base, "", proxy_inode, base.mount_flags()); return Custody::create(&base, "", proxy_inode, base.mount_flags());
} }
@ -1511,7 +1511,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
} }
if (!res) if (!res)
return KResult(-ENOENT); return ENOENT;
return *res; return *res;
} }
@ -1559,21 +1559,21 @@ InodeMetadata ProcFSProxyInode::metadata() const
KResultOr<NonnullRefPtr<Inode>> ProcFSProxyInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid) KResultOr<NonnullRefPtr<Inode>> ProcFSProxyInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid)
{ {
if (!m_fd->inode()) if (!m_fd->inode())
return KResult(-EINVAL); return EINVAL;
return m_fd->inode()->create_child(name, mode, dev, uid, gid); return m_fd->inode()->create_child(name, mode, dev, uid, gid);
} }
KResult ProcFSProxyInode::add_child(Inode& child, const StringView& name, mode_t mode) KResult ProcFSProxyInode::add_child(Inode& child, const StringView& name, mode_t mode)
{ {
if (!m_fd->inode()) if (!m_fd->inode())
return KResult(-EINVAL); return EINVAL;
return m_fd->inode()->add_child(child, name, mode); return m_fd->inode()->add_child(child, name, mode);
} }
KResult ProcFSProxyInode::remove_child(const StringView& name) KResult ProcFSProxyInode::remove_child(const StringView& name)
{ {
if (!m_fd->inode()) if (!m_fd->inode())
return KResult(-EINVAL); return EINVAL;
return m_fd->inode()->remove_child(name); return m_fd->inode()->remove_child(name);
} }
@ -1587,23 +1587,23 @@ RefPtr<Inode> ProcFSProxyInode::lookup(StringView name)
KResultOr<size_t> ProcFSProxyInode::directory_entry_count() const KResultOr<size_t> ProcFSProxyInode::directory_entry_count() const
{ {
if (!m_fd->inode()) if (!m_fd->inode())
return KResult(-EINVAL); return EINVAL;
return m_fd->inode()->directory_entry_count(); return m_fd->inode()->directory_entry_count();
} }
KResultOr<NonnullRefPtr<Inode>> ProcFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t) KResultOr<NonnullRefPtr<Inode>> ProcFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
{ {
return KResult(-EPERM); return EPERM;
} }
KResult ProcFSInode::add_child(Inode&, const StringView&, mode_t) KResult ProcFSInode::add_child(Inode&, const StringView&, mode_t)
{ {
return KResult(-EPERM); return EPERM;
} }
KResult ProcFSInode::remove_child([[maybe_unused]] const StringView& name) KResult ProcFSInode::remove_child([[maybe_unused]] const StringView& name)
{ {
return KResult(-EPERM); return EPERM;
} }
KResultOr<size_t> ProcFSInode::directory_entry_count() const KResultOr<size_t> ProcFSInode::directory_entry_count() const
@ -1623,7 +1623,7 @@ KResultOr<size_t> ProcFSInode::directory_entry_count() const
KResult ProcFSInode::chmod(mode_t) KResult ProcFSInode::chmod(mode_t)
{ {
return KResult(-EPERM); return EPERM;
} }
ProcFS::ProcFS() ProcFS::ProcFS()
@ -1673,6 +1673,6 @@ ProcFS::ProcFSDirectoryEntry* ProcFS::get_directory_entry(InodeIdentifier identi
KResult ProcFSInode::chown(uid_t, gid_t) KResult ProcFSInode::chown(uid_t, gid_t)
{ {
return KResult(-EPERM); return EPERM;
} }
} }

View file

@ -139,8 +139,8 @@ private:
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;
virtual KResultOr<size_t> directory_entry_count() const override; virtual KResultOr<size_t> directory_entry_count() const override;
virtual KResult chmod(mode_t) override { return KResult(-EINVAL); } virtual KResult chmod(mode_t) override { return EINVAL; }
virtual KResult chown(uid_t, gid_t) override { return KResult(-EINVAL); } virtual KResult chown(uid_t, gid_t) override { return EINVAL; }
virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody&, RefPtr<Custody>*, int, int) const override { ASSERT_NOT_REACHED(); } virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody&, RefPtr<Custody>*, int, int) const override { ASSERT_NOT_REACHED(); }
virtual FileDescription* preopen_fd() override { return m_fd; } virtual FileDescription* preopen_fd() override { return m_fd; }

View file

@ -134,7 +134,7 @@ KResult TmpFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry
LOCKER(m_lock, Lock::Mode::Shared); LOCKER(m_lock, Lock::Mode::Shared);
if (!is_directory()) if (!is_directory())
return KResult(-ENOTDIR); return ENOTDIR;
callback({ ".", identifier(), 0 }); callback({ ".", identifier(), 0 });
callback({ "..", m_parent, 0 }); callback({ "..", m_parent, 0 });
@ -278,7 +278,7 @@ KResultOr<NonnullRefPtr<Inode>> TmpFSInode::create_child(const String& name, mod
// TODO: Support creating devices on TmpFS. // TODO: Support creating devices on TmpFS.
if (dev != 0) if (dev != 0)
return KResult(-ENOTSUP); return ENOTSUP;
struct timeval now; struct timeval now;
kgettimeofday(now); kgettimeofday(now);
@ -305,7 +305,7 @@ KResult TmpFSInode::add_child(Inode& child, const StringView& name, mode_t)
ASSERT(child.fsid() == fsid()); ASSERT(child.fsid() == fsid());
if (name.length() > NAME_MAX) if (name.length() > NAME_MAX)
return KResult(-ENAMETOOLONG); return ENAMETOOLONG;
m_children.set(name, { name, static_cast<TmpFSInode&>(child) }); m_children.set(name, { name, static_cast<TmpFSInode&>(child) });
did_add_child(child.identifier()); did_add_child(child.identifier());
@ -322,7 +322,7 @@ KResult TmpFSInode::remove_child(const StringView& name)
auto it = m_children.find(name); auto it = m_children.find(name);
if (it == m_children.end()) if (it == m_children.end())
return KResult(-ENOENT); return ENOENT;
auto child_id = it->value.inode->identifier(); auto child_id = it->value.inode->identifier();
m_children.remove(it); m_children.remove(it);
did_remove_child(child_id); did_remove_child(child_id);
@ -339,7 +339,7 @@ KResult TmpFSInode::truncate(u64 size)
else if (!m_content) { else if (!m_content) {
m_content = KBuffer::try_create_with_size(size); m_content = KBuffer::try_create_with_size(size);
if (!m_content) if (!m_content)
return KResult(-ENOMEM); return ENOMEM;
} else if (static_cast<size_t>(size) < m_content->capacity()) { } else if (static_cast<size_t>(size) < m_content->capacity()) {
size_t prev_size = m_metadata.size; size_t prev_size = m_metadata.size;
m_content->set_size(size); m_content->set_size(size);
@ -349,7 +349,7 @@ KResult TmpFSInode::truncate(u64 size)
size_t prev_size = m_metadata.size; size_t prev_size = m_metadata.size;
auto tmp = KBuffer::try_create_with_size(size); auto tmp = KBuffer::try_create_with_size(size);
if (!tmp) if (!tmp)
return KResult(-ENOMEM); return ENOMEM;
memcpy(tmp->data(), m_content->data(), prev_size); memcpy(tmp->data(), m_content->data(), prev_size);
m_content = move(tmp); m_content = move(tmp);
} }

View file

@ -107,7 +107,7 @@ KResult VFS::remount(Custody& mount_point, int new_flags)
Mount* mount = find_mount_for_guest(mount_point.inode()); Mount* mount = find_mount_for_guest(mount_point.inode());
if (!mount) if (!mount)
return KResult(-ENODEV); return ENODEV;
mount->set_flags(new_flags); mount->set_flags(new_flags);
return KSuccess; return KSuccess;
@ -133,7 +133,7 @@ KResult VFS::unmount(Inode& guest_inode)
} }
dbg() << "VFS: Nothing mounted on inode " << guest_inode.identifier(); dbg() << "VFS: Nothing mounted on inode " << guest_inode.identifier();
return KResult(-ENODEV); return ENODEV;
} }
bool VFS::mount_root(FS& file_system) bool VFS::mount_root(FS& file_system)
@ -230,16 +230,16 @@ KResult VFS::utime(StringView path, Custody& base, time_t atime, time_t mtime)
auto& inode = custody.inode(); auto& inode = custody.inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid()) if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid())
return KResult(-EACCES); return EACCES;
if (custody.is_readonly()) if (custody.is_readonly())
return KResult(-EROFS); return EROFS;
int error = inode.set_atime(atime); int error = inode.set_atime(atime);
if (error) if (error < 0)
return KResult(error); return KResult((ErrnoCode)-error);
error = inode.set_mtime(mtime); error = inode.set_mtime(mtime);
if (error) if (error < 0)
return KResult(error); return KResult((ErrnoCode)-error);
return KSuccess; return KSuccess;
} }
@ -254,20 +254,20 @@ KResultOr<InodeMetadata> VFS::lookup_metadata(StringView path, Custody& base, in
KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner) KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner)
{ {
if ((options & O_CREAT) && (options & O_DIRECTORY)) if ((options & O_CREAT) && (options & O_DIRECTORY))
return KResult(-EINVAL); return EINVAL;
RefPtr<Custody> parent_custody; RefPtr<Custody> parent_custody;
auto custody_or_error = resolve_path(path, base, &parent_custody, options); auto custody_or_error = resolve_path(path, base, &parent_custody, options);
if (options & O_CREAT) { if (options & O_CREAT) {
if (!parent_custody) if (!parent_custody)
return KResult(-ENOENT); return ENOENT;
if (custody_or_error.is_error()) { if (custody_or_error.is_error()) {
if (custody_or_error.error() != -ENOENT) if (custody_or_error.error() != -ENOENT)
return custody_or_error.error(); return custody_or_error.error();
return create(path, options, mode, *parent_custody, move(owner)); return create(path, options, mode, *parent_custody, move(owner));
} }
if (options & O_EXCL) if (options & O_EXCL)
return KResult(-EEXIST); return EEXIST;
} }
if (custody_or_error.is_error()) if (custody_or_error.is_error())
return custody_or_error.error(); return custody_or_error.error();
@ -277,24 +277,24 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
auto metadata = inode.metadata(); auto metadata = inode.metadata();
if ((options & O_DIRECTORY) && !metadata.is_directory()) if ((options & O_DIRECTORY) && !metadata.is_directory())
return KResult(-ENOTDIR); return ENOTDIR;
bool should_truncate_file = false; bool should_truncate_file = false;
auto current_process = Process::current(); auto current_process = Process::current();
if ((options & O_RDONLY) && !metadata.may_read(*current_process)) if ((options & O_RDONLY) && !metadata.may_read(*current_process))
return KResult(-EACCES); return EACCES;
if (options & O_WRONLY) { if (options & O_WRONLY) {
if (!metadata.may_write(*current_process)) if (!metadata.may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (metadata.is_directory()) if (metadata.is_directory())
return KResult(-EISDIR); return EISDIR;
should_truncate_file = options & O_TRUNC; should_truncate_file = options & O_TRUNC;
} }
if (options & O_EXEC) { if (options & O_EXEC) {
if (!metadata.may_execute(*current_process) || (custody.mount_flags() & MS_NOEXEC)) if (!metadata.may_execute(*current_process) || (custody.mount_flags() & MS_NOEXEC))
return KResult(-EACCES); return EACCES;
} }
if (auto preopen_fd = inode.preopen_fd()) if (auto preopen_fd = inode.preopen_fd())
@ -321,15 +321,15 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
description->set_original_inode({}, inode); description->set_original_inode({}, inode);
return description; return description;
} }
return KResult(-EINVAL); return EINVAL;
} }
if (metadata.is_device()) { if (metadata.is_device()) {
if (custody.mount_flags() & MS_NODEV) if (custody.mount_flags() & MS_NODEV)
return KResult(-EACCES); return EACCES;
auto device = Device::get_device(metadata.major_device, metadata.minor_device); auto device = Device::get_device(metadata.major_device, metadata.minor_device);
if (device == nullptr) { if (device == nullptr) {
return KResult(-ENODEV); return ENODEV;
} }
auto descriptor_or_error = device->open(options); auto descriptor_or_error = device->open(options);
if (descriptor_or_error.is_error()) if (descriptor_or_error.is_error())
@ -341,7 +341,7 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
// Check for read-only FS. Do this after handling preopen FD and devices, // Check for read-only FS. Do this after handling preopen FD and devices,
// but before modifying the inode in any way. // but before modifying the inode in any way.
if ((options & O_WRONLY) && custody.is_readonly()) if ((options & O_WRONLY) && custody.is_readonly())
return KResult(-EROFS); return EROFS;
if (should_truncate_file) { if (should_truncate_file) {
KResult result = inode.truncate(0); KResult result = inode.truncate(0);
@ -360,22 +360,22 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base) KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base)
{ {
if (!is_regular_file(mode) && !is_block_device(mode) && !is_character_device(mode) && !is_fifo(mode) && !is_socket(mode)) if (!is_regular_file(mode) && !is_block_device(mode) && !is_character_device(mode) && !is_fifo(mode) && !is_socket(mode))
return KResult(-EINVAL); return EINVAL;
RefPtr<Custody> parent_custody; RefPtr<Custody> parent_custody;
auto existing_file_or_error = resolve_path(path, base, &parent_custody); auto existing_file_or_error = resolve_path(path, base, &parent_custody);
if (!existing_file_or_error.is_error()) if (!existing_file_or_error.is_error())
return KResult(-EEXIST); return EEXIST;
if (!parent_custody) if (!parent_custody)
return KResult(-ENOENT); return ENOENT;
if (existing_file_or_error.error() != -ENOENT) if (existing_file_or_error.error() != -ENOENT)
return existing_file_or_error.error(); return existing_file_or_error.error();
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!parent_inode.metadata().may_write(*current_process)) if (!parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (parent_custody->is_readonly()) if (parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
LexicalPath p(path); LexicalPath p(path);
dbgln("VFS::mknod: '{}' mode={} dev={} in {}", p.basename(), mode, dev, parent_inode.identifier()); dbgln("VFS::mknod: '{}' mode={} dev={} in {}", p.basename(), mode, dev, parent_inode.identifier());
@ -396,9 +396,9 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int optio
auto& parent_inode = parent_custody.inode(); auto& parent_inode = parent_custody.inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!parent_inode.metadata().may_write(*current_process)) if (!parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (parent_custody.is_readonly()) if (parent_custody.is_readonly())
return KResult(-EROFS); return EROFS;
LexicalPath p(path); LexicalPath p(path);
#ifdef VFS_DEBUG #ifdef VFS_DEBUG
@ -431,18 +431,18 @@ KResult VFS::mkdir(StringView path, mode_t mode, Custody& base)
RefPtr<Custody> parent_custody; RefPtr<Custody> parent_custody;
auto result = resolve_path(path, base, &parent_custody); auto result = resolve_path(path, base, &parent_custody);
if (!result.is_error()) if (!result.is_error())
return KResult(-EEXIST); return EEXIST;
if (!parent_custody) if (!parent_custody)
return KResult(-ENOENT); return ENOENT;
if (result.error() != -ENOENT) if (result.error() != -ENOENT)
return result.error(); return result.error();
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!parent_inode.metadata().may_write(*current_process)) if (!parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (parent_custody->is_readonly()) if (parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
LexicalPath p(path); LexicalPath p(path);
#ifdef VFS_DEBUG #ifdef VFS_DEBUG
@ -462,17 +462,17 @@ KResult VFS::access(StringView path, int mode, Custody& base)
auto current_process = Process::current(); auto current_process = Process::current();
if (mode & R_OK) { if (mode & R_OK) {
if (!metadata.may_read(*current_process)) if (!metadata.may_read(*current_process))
return KResult(-EACCES); return EACCES;
} }
if (mode & W_OK) { if (mode & W_OK) {
if (!metadata.may_write(*current_process)) if (!metadata.may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (custody.is_readonly()) if (custody.is_readonly())
return KResult(-EROFS); return EROFS;
} }
if (mode & X_OK) { if (mode & X_OK) {
if (!metadata.may_execute(*current_process)) if (!metadata.may_execute(*current_process))
return KResult(-EACCES); return EACCES;
} }
return KSuccess; return KSuccess;
} }
@ -485,9 +485,9 @@ KResultOr<NonnullRefPtr<Custody>> VFS::open_directory(StringView path, Custody&
auto& custody = *inode_or_error.value(); auto& custody = *inode_or_error.value();
auto& inode = custody.inode(); auto& inode = custody.inode();
if (!inode.is_directory()) if (!inode.is_directory())
return KResult(-ENOTDIR); return ENOTDIR;
if (!inode.metadata().may_execute(*Process::current())) if (!inode.metadata().may_execute(*Process::current()))
return KResult(-EACCES); return EACCES;
return custody; return custody;
} }
@ -497,9 +497,9 @@ KResult VFS::chmod(Custody& custody, mode_t mode)
auto current_process = Process::current(); auto current_process = Process::current();
if (current_process->euid() != inode.metadata().uid && !current_process->is_superuser()) if (current_process->euid() != inode.metadata().uid && !current_process->is_superuser())
return KResult(-EPERM); return EPERM;
if (custody.is_readonly()) if (custody.is_readonly())
return KResult(-EROFS); return EROFS;
// Only change the permission bits. // Only change the permission bits.
mode = (inode.mode() & ~07777u) | (mode & 07777u); mode = (inode.mode() & ~07777u) | (mode & 07777u);
@ -535,27 +535,27 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base)
auto& new_parent_inode = new_parent_custody->inode(); auto& new_parent_inode = new_parent_custody->inode();
if (&old_parent_inode.fs() != &new_parent_inode.fs()) if (&old_parent_inode.fs() != &new_parent_inode.fs())
return KResult(-EXDEV); return EXDEV;
for (auto* new_ancestor = new_parent_custody.ptr(); new_ancestor; new_ancestor = new_ancestor->parent()) { for (auto* new_ancestor = new_parent_custody.ptr(); new_ancestor; new_ancestor = new_ancestor->parent()) {
if (&old_inode == &new_ancestor->inode()) if (&old_inode == &new_ancestor->inode())
return KResult(-EDIRINTOSELF); return EDIRINTOSELF;
} }
auto current_process = Process::current(); auto current_process = Process::current();
if (!new_parent_inode.metadata().may_write(*current_process)) if (!new_parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (!old_parent_inode.metadata().may_write(*current_process)) if (!old_parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (old_parent_inode.metadata().is_sticky()) { if (old_parent_inode.metadata().is_sticky()) {
if (!current_process->is_superuser() && old_inode.metadata().uid != current_process->euid()) if (!current_process->is_superuser() && old_inode.metadata().uid != current_process->euid())
return KResult(-EACCES); return EACCES;
} }
if (old_parent_custody->is_readonly() || new_parent_custody->is_readonly()) if (old_parent_custody->is_readonly() || new_parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
auto new_basename = LexicalPath(new_path).basename(); auto new_basename = LexicalPath(new_path).basename();
@ -567,10 +567,10 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base)
return KSuccess; return KSuccess;
if (new_parent_inode.metadata().is_sticky()) { if (new_parent_inode.metadata().is_sticky()) {
if (!current_process->is_superuser() && new_inode.metadata().uid != current_process->euid()) if (!current_process->is_superuser() && new_inode.metadata().uid != current_process->euid())
return KResult(-EACCES); return EACCES;
} }
if (new_inode.is_directory() && !old_inode.is_directory()) if (new_inode.is_directory() && !old_inode.is_directory())
return KResult(-EISDIR); return EISDIR;
auto result = new_parent_inode.remove_child(new_basename); auto result = new_parent_inode.remove_child(new_basename);
if (result.is_error()) if (result.is_error())
return result; return result;
@ -594,24 +594,24 @@ KResult VFS::chown(Custody& custody, uid_t a_uid, gid_t a_gid)
auto current_process = Process::current(); auto current_process = Process::current();
if (current_process->euid() != metadata.uid && !current_process->is_superuser()) if (current_process->euid() != metadata.uid && !current_process->is_superuser())
return KResult(-EPERM); return EPERM;
uid_t new_uid = metadata.uid; uid_t new_uid = metadata.uid;
gid_t new_gid = metadata.gid; gid_t new_gid = metadata.gid;
if (a_uid != (uid_t)-1) { if (a_uid != (uid_t)-1) {
if (current_process->euid() != a_uid && !current_process->is_superuser()) if (current_process->euid() != a_uid && !current_process->is_superuser())
return KResult(-EPERM); return EPERM;
new_uid = a_uid; new_uid = a_uid;
} }
if (a_gid != (gid_t)-1) { if (a_gid != (gid_t)-1) {
if (!current_process->in_group(a_gid) && !current_process->is_superuser()) if (!current_process->in_group(a_gid) && !current_process->is_superuser())
return KResult(-EPERM); return EPERM;
new_gid = a_gid; new_gid = a_gid;
} }
if (custody.is_readonly()) if (custody.is_readonly())
return KResult(-EROFS); return EROFS;
dbgln("VFS::chown(): inode {} <- uid={} gid={}", inode.identifier(), new_uid, new_gid); dbgln("VFS::chown(): inode {} <- uid={} gid={}", inode.identifier(), new_uid, new_gid);
@ -662,27 +662,27 @@ KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
RefPtr<Custody> parent_custody; RefPtr<Custody> parent_custody;
auto new_custody_or_error = resolve_path(new_path, base, &parent_custody); auto new_custody_or_error = resolve_path(new_path, base, &parent_custody);
if (!new_custody_or_error.is_error()) if (!new_custody_or_error.is_error())
return KResult(-EEXIST); return EEXIST;
if (!parent_custody) if (!parent_custody)
return KResult(-ENOENT); return ENOENT;
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
if (parent_inode.fsid() != old_inode.fsid()) if (parent_inode.fsid() != old_inode.fsid())
return KResult(-EXDEV); return EXDEV;
if (!parent_inode.metadata().may_write(*Process::current())) if (!parent_inode.metadata().may_write(*Process::current()))
return KResult(-EACCES); return EACCES;
if (old_inode.is_directory()) if (old_inode.is_directory())
return KResult(-EPERM); return EPERM;
if (parent_custody->is_readonly()) if (parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
if (!hard_link_allowed(old_inode)) if (!hard_link_allowed(old_inode))
return KResult(-EPERM); return EPERM;
return parent_inode.add_child(old_inode, LexicalPath(new_path).basename(), old_inode.mode()); return parent_inode.add_child(old_inode, LexicalPath(new_path).basename(), old_inode.mode());
} }
@ -697,7 +697,7 @@ KResult VFS::unlink(StringView path, Custody& base)
auto& inode = custody.inode(); auto& inode = custody.inode();
if (inode.is_directory()) if (inode.is_directory())
return KResult(-EISDIR); return EISDIR;
// We have just checked that the inode is not a directory, and thus it's not // We have just checked that the inode is not a directory, and thus it's not
// the root. So it should have a parent. Note that this would be invalidated // the root. So it should have a parent. Note that this would be invalidated
@ -707,15 +707,15 @@ KResult VFS::unlink(StringView path, Custody& base)
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!parent_inode.metadata().may_write(*current_process)) if (!parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (parent_inode.metadata().is_sticky()) { if (parent_inode.metadata().is_sticky()) {
if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid()) if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid())
return KResult(-EACCES); return EACCES;
} }
if (parent_custody->is_readonly()) if (parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
auto result = parent_inode.remove_child(LexicalPath(path).basename()); auto result = parent_inode.remove_child(LexicalPath(path).basename());
if (result.is_error()) if (result.is_error())
@ -729,17 +729,17 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
RefPtr<Custody> parent_custody; RefPtr<Custody> parent_custody;
auto existing_custody_or_error = resolve_path(linkpath, base, &parent_custody); auto existing_custody_or_error = resolve_path(linkpath, base, &parent_custody);
if (!existing_custody_or_error.is_error()) if (!existing_custody_or_error.is_error())
return KResult(-EEXIST); return EEXIST;
if (!parent_custody) if (!parent_custody)
return KResult(-ENOENT); return ENOENT;
if (existing_custody_or_error.error() != -ENOENT) if (existing_custody_or_error.error() != -ENOENT)
return existing_custody_or_error.error(); return existing_custody_or_error.error();
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
auto current_process = Process::current(); auto current_process = Process::current();
if (!parent_inode.metadata().may_write(*current_process)) if (!parent_inode.metadata().may_write(*current_process))
return KResult(-EACCES); return EACCES;
if (parent_custody->is_readonly()) if (parent_custody->is_readonly())
return KResult(-EROFS); return EROFS;
LexicalPath p(linkpath); LexicalPath p(linkpath);
dbgln("VFS::symlink: '{}' (-> '{}') in {}", p.basename(), target, parent_inode.identifier()); dbgln("VFS::symlink: '{}' (-> '{}') in {}", p.basename(), target, parent_inode.identifier());
@ -750,7 +750,7 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((const u8*)target.characters_without_null_termination())); auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((const u8*)target.characters_without_null_termination()));
ssize_t nwritten = inode->write_bytes(0, target.length(), target_buffer, nullptr); ssize_t nwritten = inode->write_bytes(0, target.length(), target_buffer, nullptr);
if (nwritten < 0) if (nwritten < 0)
return KResult(nwritten); return KResult((ErrnoCode)-nwritten);
return KSuccess; return KSuccess;
} }
@ -768,20 +768,20 @@ KResult VFS::rmdir(StringView path, Custody& base)
// FIXME: We should return ENOTEMPTY if the last component of the path is ".." // FIXME: We should return ENOTEMPTY if the last component of the path is ".."
if (!inode.is_directory()) if (!inode.is_directory())
return KResult(-ENOTDIR); return ENOTDIR;
if (!parent_custody) if (!parent_custody)
return KResult(-EBUSY); return EBUSY;
auto& parent_inode = parent_custody->inode(); auto& parent_inode = parent_custody->inode();
auto parent_metadata = parent_inode.metadata(); auto parent_metadata = parent_inode.metadata();
if (!parent_metadata.may_write(*Process::current())) if (!parent_metadata.may_write(*Process::current()))
return KResult(-EACCES); return EACCES;
if (parent_metadata.is_sticky()) { if (parent_metadata.is_sticky()) {
if (!Process::current()->is_superuser() && inode.metadata().uid != Process::current()->euid()) if (!Process::current()->is_superuser() && inode.metadata().uid != Process::current()->euid())
return KResult(-EACCES); return EACCES;
} }
KResultOr<size_t> dir_count_result = inode.directory_entry_count(); KResultOr<size_t> dir_count_result = inode.directory_entry_count();
@ -789,10 +789,10 @@ KResult VFS::rmdir(StringView path, Custody& base)
return dir_count_result.result(); return dir_count_result.result();
if (dir_count_result.value() != 2) if (dir_count_result.value() != 2)
return KResult(-ENOTEMPTY); return ENOTEMPTY;
if (custody.is_readonly()) if (custody.is_readonly())
return KResult(-EROFS); return EROFS;
auto result = inode.remove_child("."); auto result = inode.remove_child(".");
if (result.is_error()) if (result.is_error())
@ -882,27 +882,27 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
// FIXME: Figure out a nicer way to do this. // FIXME: Figure out a nicer way to do this.
if (String(path).contains("/..")) if (String(path).contains("/.."))
return KResult(-EINVAL); return EINVAL;
auto* unveiled_path = find_matching_unveiled_path(path); auto* unveiled_path = find_matching_unveiled_path(path);
if (!unveiled_path) { if (!unveiled_path) {
dbgln("Rejecting path '{}' since it hasn't been unveiled.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled.", path);
dump_backtrace(); dump_backtrace();
return KResult(-ENOENT); return ENOENT;
} }
if (options & O_CREAT) { if (options & O_CREAT) {
if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) { if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) {
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'c' permission.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled with 'c' permission.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
} }
if (options & O_UNLINK_INTERNAL) { if (options & O_UNLINK_INTERNAL) {
if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) { if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) {
dbgln("Rejecting path '{}' for unlink since it hasn't been unveiled with 'c' permission.", path); dbgln("Rejecting path '{}' for unlink since it hasn't been unveiled with 'c' permission.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
return KSuccess; return KSuccess;
} }
@ -911,13 +911,13 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
if (!(unveiled_path->permissions() & (UnveilAccess::Read | UnveilAccess::Browse))) { if (!(unveiled_path->permissions() & (UnveilAccess::Read | UnveilAccess::Browse))) {
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' or 'b' permissions.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' or 'b' permissions.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
} else { } else {
if (!(unveiled_path->permissions() & UnveilAccess::Read)) { if (!(unveiled_path->permissions() & UnveilAccess::Read)) {
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' permission.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' permission.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
} }
} }
@ -925,14 +925,14 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
if (!(unveiled_path->permissions() & UnveilAccess::Write)) { if (!(unveiled_path->permissions() & UnveilAccess::Write)) {
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'w' permission.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled with 'w' permission.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
} }
if (options & O_EXEC) { if (options & O_EXEC) {
if (!(unveiled_path->permissions() & UnveilAccess::Execute)) { if (!(unveiled_path->permissions() & UnveilAccess::Execute)) {
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'x' permission.", path); dbgln("Rejecting path '{}' since it hasn't been unveiled with 'x' permission.", path);
dump_backtrace(); dump_backtrace();
return KResult(-EACCES); return EACCES;
} }
} }
return KSuccess; return KSuccess;
@ -970,10 +970,10 @@ static bool safe_to_follow_symlink(const Inode& inode, const InodeMetadata& pare
KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level) KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
{ {
if (symlink_recursion_level >= symlink_recursion_limit) if (symlink_recursion_level >= symlink_recursion_limit)
return KResult(-ELOOP); return ELOOP;
if (path.is_empty()) if (path.is_empty())
return KResult(-EINVAL); return EINVAL;
auto parts = path.split_view('/', true); auto parts = path.split_view('/', true);
auto current_process = Process::current(); auto current_process = Process::current();
@ -985,10 +985,10 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
Custody& parent = custody; Custody& parent = custody;
auto parent_metadata = parent.inode().metadata(); auto parent_metadata = parent.inode().metadata();
if (!parent_metadata.is_directory()) if (!parent_metadata.is_directory())
return KResult(-ENOTDIR); return ENOTDIR;
// Ensure the current user is allowed to resolve paths inside this directory. // Ensure the current user is allowed to resolve paths inside this directory.
if (!parent_metadata.may_execute(*current_process)) if (!parent_metadata.may_execute(*current_process))
return KResult(-EACCES); return EACCES;
auto& part = parts[i]; auto& part = parts[i];
bool have_more_parts = i + 1 < parts.size(); bool have_more_parts = i + 1 < parts.size();
@ -1011,7 +1011,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
// does not exist yet. // does not exist yet.
*out_parent = have_more_parts ? nullptr : &parent; *out_parent = have_more_parts ? nullptr : &parent;
} }
return KResult(-ENOENT); return ENOENT;
} }
int mount_flags_for_child = parent.mount_flags(); int mount_flags_for_child = parent.mount_flags();
@ -1028,13 +1028,13 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
if (child_inode->metadata().is_symlink()) { if (child_inode->metadata().is_symlink()) {
if (!have_more_parts) { if (!have_more_parts) {
if (options & O_NOFOLLOW) if (options & O_NOFOLLOW)
return KResult(-ELOOP); return ELOOP;
if (options & O_NOFOLLOW_NOERROR) if (options & O_NOFOLLOW_NOERROR)
break; break;
} }
if (!safe_to_follow_symlink(*child_inode, parent_metadata)) if (!safe_to_follow_symlink(*child_inode, parent_metadata))
return KResult(-EACCES); return EACCES;
auto symlink_target = child_inode->resolve_as_link(parent, out_parent, options, symlink_recursion_level + 1); auto symlink_target = child_inode->resolve_as_link(parent, out_parent, options, symlink_recursion_level + 1);
if (symlink_target.is_error() || !have_more_parts) if (symlink_target.is_error() || !have_more_parts)

View file

@ -27,6 +27,8 @@
#pragma once #pragma once
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
#include <LibC/errno_numbers.h> #include <LibC/errno_numbers.h>
namespace Kernel { namespace Kernel {
@ -37,10 +39,9 @@ enum KSuccessTag {
class [[nodiscard]] KResult { class [[nodiscard]] KResult {
public: public:
ALWAYS_INLINE explicit KResult(int negative_e) KResult(ErrnoCode error)
: m_error(negative_e) : m_error(-error)
{ {
ASSERT(negative_e <= 0);
} }
KResult(KSuccessTag) KResult(KSuccessTag)
: m_error(0) : m_error(0)
@ -69,6 +70,12 @@ public:
{ {
} }
KResultOr(ErrnoCode error)
: m_error(error)
, m_is_error(true)
{
}
ALWAYS_INLINE KResultOr(T&& value) ALWAYS_INLINE KResultOr(T&& value)
{ {
new (&m_storage) T(move(value)); new (&m_storage) T(move(value));

View file

@ -61,7 +61,7 @@ KResultOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol)
return UDPSocket::create(protocol); return UDPSocket::create(protocol);
if (type == SOCK_RAW) if (type == SOCK_RAW)
return adopt(*new IPv4Socket(type, protocol)); return adopt(*new IPv4Socket(type, protocol));
return KResult(-EINVAL); return EINVAL;
} }
IPv4Socket::IPv4Socket(int type, int protocol) IPv4Socket::IPv4Socket(int type, int protocol)
@ -102,20 +102,20 @@ KResult IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t addr
{ {
ASSERT(setup_state() == SetupState::Unstarted); ASSERT(setup_state() == SetupState::Unstarted);
if (address_size != sizeof(sockaddr_in)) if (address_size != sizeof(sockaddr_in))
return KResult(-EINVAL); return EINVAL;
sockaddr_in address; sockaddr_in address;
if (!copy_from_user(&address, user_address, sizeof(sockaddr_in))) if (!copy_from_user(&address, user_address, sizeof(sockaddr_in)))
return KResult(-EFAULT); return EFAULT;
if (address.sin_family != AF_INET) if (address.sin_family != AF_INET)
return KResult(-EINVAL); return EINVAL;
auto requested_local_port = ntohs(address.sin_port); auto requested_local_port = ntohs(address.sin_port);
if (!Process::current()->is_superuser()) { if (!Process::current()->is_superuser()) {
if (requested_local_port < 1024) { if (requested_local_port < 1024) {
dbgln("UID {} attempted to bind {} to port {}", Process::current()->uid(), class_name(), requested_local_port); dbgln("UID {} attempted to bind {} to port {}", Process::current()->uid(), class_name(), requested_local_port);
return KResult(-EACCES); return EACCES;
} }
} }
@ -134,7 +134,7 @@ KResult IPv4Socket::listen(size_t backlog)
LOCKER(lock()); LOCKER(lock());
int rc = allocate_local_port_if_needed(); int rc = allocate_local_port_if_needed();
if (rc < 0) if (rc < 0)
return KResult(-EADDRINUSE); return EADDRINUSE;
set_backlog(backlog); set_backlog(backlog);
m_role = Role::Listener; m_role = Role::Listener;
@ -150,19 +150,19 @@ KResult IPv4Socket::listen(size_t backlog)
KResult IPv4Socket::connect(FileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock should_block) KResult IPv4Socket::connect(FileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock should_block)
{ {
if (address_size != sizeof(sockaddr_in)) if (address_size != sizeof(sockaddr_in))
return KResult(-EINVAL); return EINVAL;
u16 sa_family_copy; u16 sa_family_copy;
auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr()); auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr());
if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))) if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)))
return KResult(-EFAULT); return EFAULT;
if (sa_family_copy != AF_INET) if (sa_family_copy != AF_INET)
return KResult(-EINVAL); return EINVAL;
if (m_role == Role::Connected) if (m_role == Role::Connected)
return KResult(-EISCONN); return EISCONN;
sockaddr_in safe_address; sockaddr_in safe_address;
if (!copy_from_user(&safe_address, (const sockaddr_in*)user_address, sizeof(sockaddr_in))) if (!copy_from_user(&safe_address, (const sockaddr_in*)user_address, sizeof(sockaddr_in)))
return KResult(-EFAULT); return EFAULT;
m_peer_address = IPv4Address((const u8*)&safe_address.sin_addr.s_addr); m_peer_address = IPv4Address((const u8*)&safe_address.sin_addr.s_addr);
m_peer_port = ntohs(safe_address.sin_port); m_peer_port = ntohs(safe_address.sin_port);
@ -200,16 +200,16 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer&
LOCKER(lock()); LOCKER(lock());
if (addr && addr_length != sizeof(sockaddr_in)) if (addr && addr_length != sizeof(sockaddr_in))
return KResult(-EINVAL); return EINVAL;
if (addr) { if (addr) {
sockaddr_in ia; sockaddr_in ia;
if (!copy_from_user(&ia, Userspace<const sockaddr_in*>(addr.ptr()))) if (!copy_from_user(&ia, Userspace<const sockaddr_in*>(addr.ptr())))
return KResult(-EFAULT); return EFAULT;
if (ia.sin_family != AF_INET) { if (ia.sin_family != AF_INET) {
klog() << "sendto: Bad address family: " << ia.sin_family << " is not AF_INET!"; klog() << "sendto: Bad address family: " << ia.sin_family << " is not AF_INET!";
return KResult(-EAFNOSUPPORT); return EAFNOSUPPORT;
} }
m_peer_address = IPv4Address((const u8*)&ia.sin_addr.s_addr); m_peer_address = IPv4Address((const u8*)&ia.sin_addr.s_addr);
@ -218,7 +218,7 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer&
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 KResult(-EHOSTUNREACH); return 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();
@ -234,7 +234,7 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer&
if (type() == SOCK_RAW) { if (type() == SOCK_RAW) {
int err = routing_decision.adapter->send_ipv4(routing_decision.next_hop, m_peer_address, (IPv4Protocol)protocol(), data, data_length, m_ttl); int err = routing_decision.adapter->send_ipv4(routing_decision.next_hop, m_peer_address, (IPv4Protocol)protocol(), data, data_length, m_ttl);
if (err < 0) if (err < 0)
return KResult(err); return KResult((ErrnoCode)-err);
return data_length; return data_length;
} }
@ -251,7 +251,7 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description
if (protocol_is_disconnected()) if (protocol_is_disconnected())
return 0; return 0;
if (!description.is_blocking()) if (!description.is_blocking())
return KResult(-EAGAIN); return EAGAIN;
locker.unlock(); locker.unlock();
auto unblocked_flags = Thread::FileDescriptionBlocker::BlockFlags::None; auto unblocked_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
@ -260,10 +260,10 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description
if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) { if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) {
if (res.was_interrupted()) if (res.was_interrupted())
return KResult(-EINTR); return EINTR;
// Unblocked due to timeout. // Unblocked due to timeout.
return KResult(-EAGAIN); return EAGAIN;
} }
} }
@ -287,7 +287,7 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti
if (protocol_is_disconnected()) if (protocol_is_disconnected())
return 0; return 0;
if (!description.is_blocking()) if (!description.is_blocking())
return KResult(-EAGAIN); return EAGAIN;
} }
if (!m_receive_queue.is_empty()) { if (!m_receive_queue.is_empty()) {
@ -311,10 +311,10 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti
if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) { if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) {
if (res.was_interrupted()) if (res.was_interrupted())
return KResult(-EINTR); return EINTR;
// Unblocked due to timeout. // Unblocked due to timeout.
return KResult(-EAGAIN); return EAGAIN;
} }
ASSERT(m_can_read); ASSERT(m_can_read);
ASSERT(!m_receive_queue.is_empty()); ASSERT(!m_receive_queue.is_empty());
@ -339,18 +339,18 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti
out_addr.sin_family = AF_INET; out_addr.sin_family = AF_INET;
Userspace<sockaddr_in*> dest_addr = addr.ptr(); Userspace<sockaddr_in*> dest_addr = addr.ptr();
if (!copy_to_user(dest_addr, &out_addr)) if (!copy_to_user(dest_addr, &out_addr))
return KResult(-EFAULT); return EFAULT;
socklen_t out_length = sizeof(sockaddr_in); socklen_t out_length = sizeof(sockaddr_in);
ASSERT(addr_length); ASSERT(addr_length);
if (!copy_to_user(addr_length, &out_length)) if (!copy_to_user(addr_length, &out_length))
return KResult(-EFAULT); return EFAULT;
} }
if (type() == SOCK_RAW) { if (type() == SOCK_RAW) {
size_t bytes_written = min(packet.data.value().size(), buffer_length); size_t bytes_written = min(packet.data.value().size(), buffer_length);
if (!buffer.write(packet.data.value().data(), bytes_written)) if (!buffer.write(packet.data.value().data(), bytes_written))
return KResult(-EFAULT); return EFAULT;
return bytes_written; return bytes_written;
} }
@ -362,9 +362,9 @@ KResultOr<size_t> IPv4Socket::recvfrom(FileDescription& description, UserOrKerne
if (user_addr_length) { if (user_addr_length) {
socklen_t addr_length; socklen_t addr_length;
if (!copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr())) if (!copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr()))
return KResult(-EFAULT); return EFAULT;
if (addr_length < sizeof(sockaddr_in)) if (addr_length < sizeof(sockaddr_in))
return KResult(-EINVAL); return EINVAL;
} }
#ifdef IPV4_SOCKET_DEBUG #ifdef IPV4_SOCKET_DEBUG
@ -464,17 +464,17 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
switch (option) { switch (option) {
case IP_TTL: { case IP_TTL: {
if (user_value_size < sizeof(int)) if (user_value_size < sizeof(int))
return KResult(-EINVAL); return EINVAL;
int value; int value;
if (!copy_from_user(&value, static_ptr_cast<const int*>(user_value))) if (!copy_from_user(&value, static_ptr_cast<const int*>(user_value)))
return KResult(-EFAULT); return EFAULT;
if (value < 0 || value > 255) if (value < 0 || value > 255)
return KResult(-EINVAL); return EINVAL;
m_ttl = value; m_ttl = value;
return KSuccess; return KSuccess;
} }
default: default:
return KResult(-ENOPROTOOPT); return ENOPROTOOPT;
} }
} }
@ -485,20 +485,20 @@ KResult IPv4Socket::getsockopt(FileDescription& description, int level, int opti
socklen_t size; socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr())) if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return KResult(-EFAULT); return EFAULT;
switch (option) { switch (option) {
case IP_TTL: case IP_TTL:
if (size < sizeof(int)) if (size < sizeof(int))
return KResult(-EINVAL); return EINVAL;
if (!copy_to_user(static_ptr_cast<int*>(value), (int*)&m_ttl)) if (!copy_to_user(static_ptr_cast<int*>(value), (int*)&m_ttl))
return KResult(-EFAULT); return EFAULT;
size = sizeof(int); size = sizeof(int);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
default: default:
return KResult(-ENOPROTOOPT); return ENOPROTOOPT;
} }
} }

View file

@ -102,14 +102,14 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
{ {
ASSERT(setup_state() == SetupState::Unstarted); ASSERT(setup_state() == SetupState::Unstarted);
if (address_size != sizeof(sockaddr_un)) if (address_size != sizeof(sockaddr_un))
return KResult(-EINVAL); return EINVAL;
sockaddr_un address; sockaddr_un address;
if (!copy_from_user(&address, user_address, sizeof(sockaddr_un))) if (!copy_from_user(&address, user_address, sizeof(sockaddr_un)))
return KResult(-EFAULT); return EFAULT;
if (address.sun_family != AF_LOCAL) if (address.sun_family != AF_LOCAL)
return KResult(-EINVAL); return EINVAL;
auto path = String(address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path))); auto path = String(address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path)));
@ -122,7 +122,7 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
auto result = VFS::the().open(path, O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current()->current_directory(), owner); auto result = VFS::the().open(path, O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current()->current_directory(), owner);
if (result.is_error()) { if (result.is_error()) {
if (result.error() == -EEXIST) if (result.error() == -EEXIST)
return KResult(-EADDRINUSE); return EADDRINUSE;
return result.error(); return result.error();
} }
@ -130,7 +130,7 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
ASSERT(file->inode()); ASSERT(file->inode());
if (!file->inode()->bind_socket(*this)) if (!file->inode()->bind_socket(*this))
return KResult(-EADDRINUSE); return EADDRINUSE;
m_file = move(file); m_file = move(file);
@ -143,20 +143,20 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
{ {
ASSERT(!m_bound); ASSERT(!m_bound);
if (address_size != sizeof(sockaddr_un)) if (address_size != sizeof(sockaddr_un))
return KResult(-EINVAL); return EINVAL;
u16 sa_family_copy; u16 sa_family_copy;
auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr()); auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr());
if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))) if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)))
return KResult(-EFAULT); return EFAULT;
if (sa_family_copy != AF_LOCAL) if (sa_family_copy != AF_LOCAL)
return KResult(-EINVAL); return EINVAL;
if (is_connected()) if (is_connected())
return KResult(-EISCONN); return EISCONN;
const auto& local_address = *reinterpret_cast<const sockaddr_un*>(user_address); const auto& local_address = *reinterpret_cast<const sockaddr_un*>(user_address);
char safe_address[sizeof(local_address.sun_path) + 1] = { 0 }; char safe_address[sizeof(local_address.sun_path) + 1] = { 0 };
if (!copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1)) if (!copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1))
return KResult(-EFAULT); return EFAULT;
safe_address[sizeof(safe_address) - 1] = '\0'; safe_address[sizeof(safe_address) - 1] = '\0';
#ifdef DEBUG_LOCAL_SOCKET #ifdef DEBUG_LOCAL_SOCKET
@ -165,13 +165,13 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
auto description_or_error = VFS::the().open(safe_address, O_RDWR, 0, Process::current()->current_directory()); auto description_or_error = VFS::the().open(safe_address, O_RDWR, 0, Process::current()->current_directory());
if (description_or_error.is_error()) if (description_or_error.is_error())
return KResult(-ECONNREFUSED); return ECONNREFUSED;
m_file = move(description_or_error.value()); m_file = move(description_or_error.value());
ASSERT(m_file->inode()); ASSERT(m_file->inode());
if (!m_file->inode()->socket()) if (!m_file->inode()->socket())
return KResult(-ECONNREFUSED); return ECONNREFUSED;
m_address.sun_family = sa_family_copy; m_address.sun_family = sa_family_copy;
memcpy(m_address.sun_path, safe_address, sizeof(m_address.sun_path)); memcpy(m_address.sun_path, safe_address, sizeof(m_address.sun_path));
@ -194,7 +194,7 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None; auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted()) { if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted()) {
set_connect_side_role(Role::None); set_connect_side_role(Role::None);
return KResult(-EINTR); return EINTR;
} }
#ifdef DEBUG_LOCAL_SOCKET #ifdef DEBUG_LOCAL_SOCKET
@ -203,7 +203,7 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
if (!((u32)unblock_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Connect)) { if (!((u32)unblock_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Connect)) {
set_connect_side_role(Role::None); set_connect_side_role(Role::None);
return KResult(-ECONNREFUSED); return ECONNREFUSED;
} }
set_connect_side_role(Role::Connected); set_connect_side_role(Role::Connected);
return KSuccess; return KSuccess;
@ -213,7 +213,7 @@ KResult LocalSocket::listen(size_t backlog)
{ {
LOCKER(lock()); LOCKER(lock());
if (type() != SOCK_STREAM) if (type() != SOCK_STREAM)
return KResult(-EOPNOTSUPP); return EOPNOTSUPP;
set_backlog(backlog); set_backlog(backlog);
auto previous_role = m_role; auto previous_role = m_role;
m_role = Role::Listener; m_role = Role::Listener;
@ -286,10 +286,10 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const
KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const UserOrKernelBuffer& data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t) KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const UserOrKernelBuffer& data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t)
{ {
if (!has_attached_peer(description)) if (!has_attached_peer(description))
return KResult(-EPIPE); return EPIPE;
auto* socket_buffer = send_buffer_for(description); auto* socket_buffer = send_buffer_for(description);
if (!socket_buffer) if (!socket_buffer)
return KResult(-EINVAL); return EINVAL;
ssize_t nwritten = socket_buffer->write(data, data_size); ssize_t nwritten = socket_buffer->write(data, data_size);
if (nwritten > 0) if (nwritten > 0)
Thread::current()->did_unix_socket_write(nwritten); Thread::current()->did_unix_socket_write(nwritten);
@ -320,17 +320,17 @@ KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKern
{ {
auto* socket_buffer = receive_buffer_for(description); auto* socket_buffer = receive_buffer_for(description);
if (!socket_buffer) if (!socket_buffer)
return KResult(-EINVAL); return EINVAL;
if (!description.is_blocking()) { if (!description.is_blocking()) {
if (socket_buffer->is_empty()) { if (socket_buffer->is_empty()) {
if (!has_attached_peer(description)) if (!has_attached_peer(description))
return 0; return 0;
return KResult(-EAGAIN); return EAGAIN;
} }
} else if (!can_read(description, 0)) { } else if (!can_read(description, 0)) {
auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None; auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted()) if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted())
return KResult(-EINTR); return EINTR;
} }
if (!has_attached_peer(description) && socket_buffer->is_empty()) if (!has_attached_peer(description) && socket_buffer->is_empty())
return 0; return 0;
@ -380,31 +380,31 @@ KResult LocalSocket::getsockopt(FileDescription& description, int level, int opt
socklen_t size; socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr())) if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return KResult(-EFAULT); return EFAULT;
switch (option) { switch (option) {
case SO_PEERCRED: { case SO_PEERCRED: {
if (size < sizeof(ucred)) if (size < sizeof(ucred))
return KResult(-EINVAL); return EINVAL;
switch (role(description)) { switch (role(description)) {
case Role::Accepted: case Role::Accepted:
if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_origin)) if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_origin))
return KResult(-EFAULT); return EFAULT;
size = sizeof(ucred); size = sizeof(ucred);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case Role::Connected: case Role::Connected:
if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_acceptor)) if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_acceptor))
return KResult(-EFAULT); return EFAULT;
size = sizeof(ucred); size = sizeof(ucred);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case Role::Connecting: case Role::Connecting:
return KResult(-ENOTCONN); return ENOTCONN;
default: default:
return KResult(-EINVAL); return EINVAL;
} }
break; break;
} }
@ -429,7 +429,7 @@ KResult LocalSocket::chown(FileDescription&, uid_t uid, gid_t gid)
auto current_process = Process::current(); auto current_process = Process::current();
if (!current_process->is_superuser() && (current_process->euid() != uid || !current_process->in_group(gid))) if (!current_process->is_superuser() && (current_process->euid() != uid || !current_process->in_group(gid)))
return KResult(-EPERM); return EPERM;
m_prebind_uid = uid; m_prebind_uid = uid;
m_prebind_gid = gid; m_prebind_gid = gid;
@ -461,11 +461,11 @@ KResult LocalSocket::sendfd(const FileDescription& socket_description, FileDescr
LOCKER(lock()); LOCKER(lock());
auto role = this->role(socket_description); auto role = this->role(socket_description);
if (role != Role::Connected && role != Role::Accepted) if (role != Role::Connected && role != Role::Accepted)
return KResult(-EINVAL); return EINVAL;
auto& queue = sendfd_queue_for(socket_description); auto& queue = sendfd_queue_for(socket_description);
// FIXME: Figure out how we should limit this properly. // FIXME: Figure out how we should limit this properly.
if (queue.size() > 16) if (queue.size() > 16)
return KResult(-EBUSY); return EBUSY;
queue.append(move(passing_description)); queue.append(move(passing_description));
return KSuccess; return KSuccess;
} }
@ -475,11 +475,11 @@ KResultOr<NonnullRefPtr<FileDescription>> LocalSocket::recvfd(const FileDescript
LOCKER(lock()); LOCKER(lock());
auto role = this->role(socket_description); auto role = this->role(socket_description);
if (role != Role::Connected && role != Role::Accepted) if (role != Role::Connected && role != Role::Accepted)
return KResult(-EINVAL); return EINVAL;
auto& queue = recvfd_queue_for(socket_description); auto& queue = recvfd_queue_for(socket_description);
if (queue.is_empty()) { if (queue.is_empty()) {
// FIXME: Figure out the perfect error code for this. // FIXME: Figure out the perfect error code for this.
return KResult(-EAGAIN); return EAGAIN;
} }
return queue.take_first(); return queue.take_first();
} }

View file

@ -46,7 +46,7 @@ KResultOr<NonnullRefPtr<Socket>> Socket::create(int domain, int type, int protoc
case AF_INET: case AF_INET:
return IPv4Socket::create(type & SOCK_TYPE_MASK, protocol); return IPv4Socket::create(type & SOCK_TYPE_MASK, protocol);
default: default:
return KResult(-EAFNOSUPPORT); return EAFNOSUPPORT;
} }
} }
@ -99,7 +99,7 @@ KResult Socket::queue_connection_from(NonnullRefPtr<Socket> peer)
#endif #endif
LOCKER(m_lock); LOCKER(m_lock);
if (m_pending.size() >= m_backlog) if (m_pending.size() >= m_backlog)
return KResult(-ECONNREFUSED); return ECONNREFUSED;
m_pending.append(peer); m_pending.append(peer);
evaluate_block_conditions(); evaluate_block_conditions();
return KSuccess; return KSuccess;
@ -111,26 +111,26 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
switch (option) { switch (option) {
case SO_SNDTIMEO: case SO_SNDTIMEO:
if (user_value_size != sizeof(timeval)) if (user_value_size != sizeof(timeval))
return KResult(-EINVAL); return EINVAL;
if (!copy_from_user(&m_send_timeout, static_ptr_cast<const timeval*>(user_value))) if (!copy_from_user(&m_send_timeout, static_ptr_cast<const timeval*>(user_value)))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case SO_RCVTIMEO: case SO_RCVTIMEO:
if (user_value_size != sizeof(timeval)) if (user_value_size != sizeof(timeval))
return KResult(-EINVAL); return EINVAL;
if (!copy_from_user(&m_receive_timeout, static_ptr_cast<const timeval*>(user_value))) if (!copy_from_user(&m_receive_timeout, static_ptr_cast<const timeval*>(user_value)))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case SO_BINDTODEVICE: { case SO_BINDTODEVICE: {
if (user_value_size != IFNAMSIZ) if (user_value_size != IFNAMSIZ)
return KResult(-EINVAL); return EINVAL;
auto user_string = static_ptr_cast<const char*>(user_value); auto user_string = static_ptr_cast<const char*>(user_value);
auto ifname = copy_string_from_user(user_string, user_value_size); auto ifname = copy_string_from_user(user_string, user_value_size);
if (ifname.is_null()) if (ifname.is_null())
return KResult(-EFAULT); return EFAULT;
auto device = NetworkAdapter::lookup_by_name(ifname); auto device = NetworkAdapter::lookup_by_name(ifname);
if (!device) if (!device)
return KResult(-ENODEV); return ENODEV;
m_bound_interface = device; m_bound_interface = device;
return KSuccess; return KSuccess;
} }
@ -139,18 +139,18 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
return KSuccess; return KSuccess;
case SO_TIMESTAMP: case SO_TIMESTAMP:
if (user_value_size != sizeof(int)) if (user_value_size != sizeof(int))
return KResult(-EINVAL); return EINVAL;
if (!copy_from_user(&m_timestamp, static_ptr_cast<const int*>(user_value))) if (!copy_from_user(&m_timestamp, static_ptr_cast<const int*>(user_value)))
return KResult(-EFAULT); return EFAULT;
if (m_timestamp && (domain() != AF_INET || type() == SOCK_STREAM)) { if (m_timestamp && (domain() != AF_INET || type() == SOCK_STREAM)) {
// FIXME: Support SO_TIMESTAMP for more protocols? // FIXME: Support SO_TIMESTAMP for more protocols?
m_timestamp = 0; m_timestamp = 0;
return KResult(-ENOTSUP); return ENOTSUP;
} }
return KSuccess; return KSuccess;
default: default:
dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option); dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option);
return KResult(-ENOPROTOOPT); return ENOPROTOOPT;
} }
} }
@ -158,76 +158,76 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, Userspace<vo
{ {
socklen_t size; socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr())) if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return KResult(-EFAULT); return EFAULT;
// FIXME: Add TCP_NODELAY, IPPROTO_TCP and IPPROTO_IP (used in OpenSSH) // FIXME: Add TCP_NODELAY, IPPROTO_TCP and IPPROTO_IP (used in OpenSSH)
if (level != SOL_SOCKET) { if (level != SOL_SOCKET) {
// Not sure if this is the correct error code, but it's only temporary until other levels are implemented. // Not sure if this is the correct error code, but it's only temporary until other levels are implemented.
return KResult(-ENOPROTOOPT); return ENOPROTOOPT;
} }
switch (option) { switch (option) {
case SO_SNDTIMEO: case SO_SNDTIMEO:
if (size < sizeof(timeval)) if (size < sizeof(timeval))
return KResult(-EINVAL); return EINVAL;
if (!copy_to_user(static_ptr_cast<timeval*>(value), &m_send_timeout)) if (!copy_to_user(static_ptr_cast<timeval*>(value), &m_send_timeout))
return KResult(-EFAULT); return EFAULT;
size = sizeof(timeval); size = sizeof(timeval);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case SO_RCVTIMEO: case SO_RCVTIMEO:
if (size < sizeof(timeval)) if (size < sizeof(timeval))
return KResult(-EINVAL); return EINVAL;
if (!copy_to_user(static_ptr_cast<timeval*>(value), &m_receive_timeout)) if (!copy_to_user(static_ptr_cast<timeval*>(value), &m_receive_timeout))
return KResult(-EFAULT); return EFAULT;
size = sizeof(timeval); size = sizeof(timeval);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
case SO_ERROR: { case SO_ERROR: {
if (size < sizeof(int)) if (size < sizeof(int))
return KResult(-EINVAL); return EINVAL;
dbgln("getsockopt(SO_ERROR): FIXME!"); dbgln("getsockopt(SO_ERROR): FIXME!");
int errno = 0; int errno = 0;
if (!copy_to_user(static_ptr_cast<int*>(value), &errno)) if (!copy_to_user(static_ptr_cast<int*>(value), &errno))
return KResult(-EFAULT); return EFAULT;
size = sizeof(int); size = sizeof(int);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
} }
case SO_BINDTODEVICE: case SO_BINDTODEVICE:
if (size < IFNAMSIZ) if (size < IFNAMSIZ)
return KResult(-EINVAL); return EINVAL;
if (m_bound_interface) { if (m_bound_interface) {
const auto& name = m_bound_interface->name(); const auto& name = m_bound_interface->name();
auto length = name.length() + 1; auto length = name.length() + 1;
if (!copy_to_user(static_ptr_cast<char*>(value), name.characters(), length)) if (!copy_to_user(static_ptr_cast<char*>(value), name.characters(), length))
return KResult(-EFAULT); return EFAULT;
size = length; size = length;
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
} else { } else {
size = 0; size = 0;
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KResult(-EFAULT); return EFAULT;
} }
case SO_TIMESTAMP: case SO_TIMESTAMP:
if (size < sizeof(int)) if (size < sizeof(int))
return KResult(-EINVAL); return EINVAL;
if (!copy_to_user(static_ptr_cast<int*>(value), &m_timestamp)) if (!copy_to_user(static_ptr_cast<int*>(value), &m_timestamp))
return KResult(-EFAULT); return EFAULT;
size = sizeof(int); size = sizeof(int);
if (!copy_to_user(value_size, &size)) if (!copy_to_user(value_size, &size))
return KResult(-EFAULT); return EFAULT;
return KSuccess; return KSuccess;
default: default:
dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option); dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option);
return KResult(-ENOPROTOOPT); return ENOPROTOOPT;
} }
} }
@ -250,9 +250,9 @@ KResult Socket::shutdown(int how)
{ {
LOCKER(lock()); LOCKER(lock());
if (type() == SOCK_STREAM && !is_connected()) if (type() == SOCK_STREAM && !is_connected())
return KResult(-ENOTCONN); return ENOTCONN;
if (m_role == Role::Listener) if (m_role == Role::Listener)
return KResult(-ENOTCONN); return ENOTCONN;
if (!m_shut_down_for_writing && (how & SHUT_WR)) if (!m_shut_down_for_writing && (how & SHUT_WR))
shut_down_for_writing(); shut_down_for_writing();
if (!m_shut_down_for_reading && (how & SHUT_RD)) if (!m_shut_down_for_reading && (how & SHUT_RD))

View file

@ -177,7 +177,7 @@ KResultOr<size_t> TCPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use
#endif #endif
ASSERT(buffer_size >= payload_size); ASSERT(buffer_size >= payload_size);
if (!buffer.write(tcp_packet.payload(), payload_size)) if (!buffer.write(tcp_packet.payload(), payload_size))
return KResult(-EFAULT); return EFAULT;
return payload_size; return payload_size;
} }
@ -185,7 +185,7 @@ KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_
{ {
int err = send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, &data, data_length); int err = send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, &data, data_length);
if (err < 0) if (err < 0)
return KResult(err); return KResult((ErrnoCode)-err);
return data_length; return data_length;
} }
@ -354,7 +354,7 @@ KResult TCPSocket::protocol_bind()
if (has_specific_local_address() && !m_adapter) { if (has_specific_local_address() && !m_adapter) {
m_adapter = NetworkAdapter::from_ipv4_address(local_address()); m_adapter = NetworkAdapter::from_ipv4_address(local_address());
if (!m_adapter) if (!m_adapter)
return KResult(-EADDRNOTAVAIL); return EADDRNOTAVAIL;
} }
return KSuccess; return KSuccess;
@ -364,7 +364,7 @@ KResult TCPSocket::protocol_listen()
{ {
LOCKER(sockets_by_tuple().lock()); LOCKER(sockets_by_tuple().lock());
if (sockets_by_tuple().resource().contains(tuple())) if (sockets_by_tuple().resource().contains(tuple()))
return KResult(-EADDRINUSE); return EADDRINUSE;
sockets_by_tuple().resource().set(tuple(), this); sockets_by_tuple().resource().set(tuple(), this);
set_direction(Direction::Passive); set_direction(Direction::Passive);
set_state(State::Listen); set_state(State::Listen);
@ -378,7 +378,7 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh
auto routing_decision = route_to(peer_address(), local_address()); auto routing_decision = route_to(peer_address(), local_address());
if (routing_decision.is_zero()) if (routing_decision.is_zero())
return KResult(-EHOSTUNREACH); return EHOSTUNREACH;
if (!has_specific_local_address()) if (!has_specific_local_address())
set_local_address(routing_decision.adapter->ipv4_address()); set_local_address(routing_decision.adapter->ipv4_address());
@ -390,7 +390,7 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh
set_setup_state(SetupState::InProgress); set_setup_state(SetupState::InProgress);
int err = send_tcp_packet(TCPFlags::SYN); int err = send_tcp_packet(TCPFlags::SYN);
if (err < 0) if (err < 0)
return KResult(err); return KResult((ErrnoCode)-err);
m_state = State::SynSent; m_state = State::SynSent;
m_role = Role::Connecting; m_role = Role::Connecting;
m_direction = Direction::Outgoing; m_direction = Direction::Outgoing;
@ -401,17 +401,17 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh
locker.unlock(); locker.unlock();
auto unblock_flags = Thread::FileBlocker::BlockFlags::None; auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted()) if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted())
return KResult(-EINTR); return EINTR;
locker.lock(); locker.lock();
ASSERT(setup_state() == SetupState::Completed); ASSERT(setup_state() == SetupState::Completed);
if (has_error()) { // TODO: check unblock_flags if (has_error()) { // TODO: check unblock_flags
m_role = Role::None; m_role = Role::None;
return KResult(-ECONNREFUSED); return ECONNREFUSED;
} }
return KSuccess; return KSuccess;
} }
return KResult(-EINPROGRESS); return EINPROGRESS;
} }
int TCPSocket::protocol_allocate_local_port() int TCPSocket::protocol_allocate_local_port()

View file

@ -86,7 +86,7 @@ KResultOr<size_t> UDPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use
ASSERT(udp_packet.length() >= sizeof(UDPPacket)); // FIXME: This should be rejected earlier. ASSERT(udp_packet.length() >= sizeof(UDPPacket)); // FIXME: This should be rejected earlier.
ASSERT(buffer_size >= (udp_packet.length() - sizeof(UDPPacket))); ASSERT(buffer_size >= (udp_packet.length() - sizeof(UDPPacket)));
if (!buffer.write(udp_packet.payload(), udp_packet.length() - sizeof(UDPPacket))) if (!buffer.write(udp_packet.payload(), udp_packet.length() - sizeof(UDPPacket)))
return KResult(-EFAULT); return EFAULT;
return udp_packet.length() - sizeof(UDPPacket); return udp_packet.length() - sizeof(UDPPacket);
} }
@ -94,7 +94,7 @@ KResultOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_
{ {
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 KResult(-EHOSTUNREACH); return EHOSTUNREACH;
const size_t buffer_size = sizeof(UDPPacket) + data_length; const size_t buffer_size = sizeof(UDPPacket) + data_length;
alignas(UDPPacket) u8 buffer[buffer_size]; alignas(UDPPacket) u8 buffer[buffer_size];
@ -105,7 +105,7 @@ KResultOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_
udp_packet.set_destination_port(peer_port()); udp_packet.set_destination_port(peer_port());
udp_packet.set_length(buffer_size); udp_packet.set_length(buffer_size);
if (!data.read(udp_packet.payload(), data_length)) if (!data.read(udp_packet.payload(), data_length))
return KResult(-EFAULT); return EFAULT;
routing_decision.adapter->send_ipv4(routing_decision.next_hop, peer_address(), IPv4Protocol::UDP, UserOrKernelBuffer::for_kernel_buffer(buffer), buffer_size, ttl()); routing_decision.adapter->send_ipv4(routing_decision.next_hop, peer_address(), IPv4Protocol::UDP, UserOrKernelBuffer::for_kernel_buffer(buffer), buffer_size, ttl());
return data_length; return data_length;
@ -146,7 +146,7 @@ KResult UDPSocket::protocol_bind()
{ {
LOCKER(sockets_by_port().lock()); LOCKER(sockets_by_port().lock());
if (sockets_by_port().resource().contains(local_port())) if (sockets_by_port().resource().contains(local_port()))
return KResult(-EADDRINUSE); return EADDRINUSE;
sockets_by_port().resource().set(local_port(), this); sockets_by_port().resource().set(local_port(), this);
return KSuccess; return KSuccess;
} }

View file

@ -51,7 +51,7 @@ KResult PerformanceEventBuffer::append(int type, FlatPtr arg1, FlatPtr arg2)
KResult PerformanceEventBuffer::append_with_eip_and_ebp(u32 eip, u32 ebp, int type, FlatPtr arg1, FlatPtr arg2) KResult PerformanceEventBuffer::append_with_eip_and_ebp(u32 eip, u32 ebp, int type, FlatPtr arg1, FlatPtr arg2)
{ {
if (count() >= capacity()) if (count() >= capacity())
return KResult(-ENOBUFS); return ENOBUFS;
PerformanceEvent event; PerformanceEvent event;
event.type = type; event.type = type;
@ -67,7 +67,7 @@ KResult PerformanceEventBuffer::append_with_eip_and_ebp(u32 eip, u32 ebp, int ty
event.data.free.ptr = arg1; event.data.free.ptr = arg1;
break; break;
default: default:
return KResult(-EINVAL); return EINVAL;
} }
auto current_thread = Thread::current(); auto current_thread = Thread::current();

View file

@ -148,10 +148,10 @@ KResultOr<Region*> Process::allocate_region(const Range& range, const String& na
ASSERT(range.is_valid()); ASSERT(range.is_valid());
auto vmobject = AnonymousVMObject::create_with_size(range.size(), strategy); auto vmobject = AnonymousVMObject::create_with_size(range.size(), strategy);
if (!vmobject) if (!vmobject)
return KResult(-ENOMEM); return ENOMEM;
auto region = Region::create_user_accessible(this, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot)); auto region = Region::create_user_accessible(this, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot));
if (!region->map(page_directory())) if (!region->map(page_directory()))
return KResult(-ENOMEM); return ENOMEM;
return &add_region(move(region)); return &add_region(move(region));
} }
@ -159,7 +159,7 @@ KResultOr<Region*> Process::allocate_region(VirtualAddress vaddr, size_t size, c
{ {
auto range = allocate_range(vaddr, size); auto range = allocate_range(vaddr, size);
if (!range.is_valid()) if (!range.is_valid())
return KResult(-ENOMEM); return ENOMEM;
return allocate_region(range, name, prot, strategy); return allocate_region(range, name, prot, strategy);
} }
@ -169,21 +169,21 @@ KResultOr<Region*> Process::allocate_region_with_vmobject(const Range& range, No
size_t end_in_vmobject = offset_in_vmobject + range.size(); size_t end_in_vmobject = offset_in_vmobject + range.size();
if (end_in_vmobject <= offset_in_vmobject) { if (end_in_vmobject <= offset_in_vmobject) {
dbgln("allocate_region_with_vmobject: Overflow (offset + size)"); dbgln("allocate_region_with_vmobject: Overflow (offset + size)");
return KResult(-EINVAL); return EINVAL;
} }
if (offset_in_vmobject >= vmobject->size()) { if (offset_in_vmobject >= vmobject->size()) {
dbgln("allocate_region_with_vmobject: Attempt to allocate a region with an offset past the end of its VMObject."); dbgln("allocate_region_with_vmobject: Attempt to allocate a region with an offset past the end of its VMObject.");
return KResult(-EINVAL); return EINVAL;
} }
if (end_in_vmobject > vmobject->size()) { if (end_in_vmobject > vmobject->size()) {
dbgln("allocate_region_with_vmobject: Attempt to allocate a region with an end past the end of its VMObject."); dbgln("allocate_region_with_vmobject: Attempt to allocate a region with an end past the end of its VMObject.");
return KResult(-EINVAL); return EINVAL;
} }
offset_in_vmobject &= PAGE_MASK; offset_in_vmobject &= PAGE_MASK;
auto& region = add_region(Region::create_user_accessible(this, range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot), true, shared)); auto& region = add_region(Region::create_user_accessible(this, range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot), true, shared));
if (!region.map(page_directory())) { if (!region.map(page_directory())) {
// FIXME: What is an appropriate error code here, really? // FIXME: What is an appropriate error code here, really?
return KResult(-ENOMEM); return ENOMEM;
} }
return &region; return &region;
} }
@ -192,7 +192,7 @@ KResultOr<Region*> Process::allocate_region_with_vmobject(VirtualAddress vaddr,
{ {
auto range = allocate_range(vaddr, size); auto range = allocate_range(vaddr, size);
if (!range.is_valid()) if (!range.is_valid())
return KResult(-ENOMEM); return ENOMEM;
return allocate_region_with_vmobject(range, move(vmobject), offset_in_vmobject, name, prot, shared); return allocate_region_with_vmobject(range, move(vmobject), offset_in_vmobject, name, prot, shared);
} }
@ -573,12 +573,12 @@ Custody& Process::current_directory()
KResultOr<String> Process::get_syscall_path_argument(const char* user_path, size_t path_length) const KResultOr<String> Process::get_syscall_path_argument(const char* user_path, size_t path_length) const
{ {
if (path_length == 0) if (path_length == 0)
return KResult(-EINVAL); return EINVAL;
if (path_length > PATH_MAX) if (path_length > PATH_MAX)
return KResult(-ENAMETOOLONG); return ENAMETOOLONG;
auto copied_string = copy_string_from_user(user_path, path_length); auto copied_string = copy_string_from_user(user_path, path_length);
if (copied_string.is_null()) if (copied_string.is_null())
return KResult(-EFAULT); return EFAULT;
return copied_string; return copied_string;
} }
@ -819,7 +819,7 @@ KResult Process::send_signal(u8 signal, Process* sender)
receiver_thread->send_signal(signal, sender); receiver_thread->send_signal(signal, sender);
return KSuccess; return KSuccess;
} }
return KResult(-ESRCH); return ESRCH;
} }
RefPtr<Thread> Process::create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, const String& name, u32 affinity, bool joinable) RefPtr<Thread> Process::create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, const String& name, u32 affinity, bool joinable)

View file

@ -38,7 +38,7 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
ScopedSpinLock scheduler_lock(g_scheduler_lock); ScopedSpinLock scheduler_lock(g_scheduler_lock);
if (params.request == PT_TRACE_ME) { if (params.request == PT_TRACE_ME) {
if (Process::current()->tracer()) if (Process::current()->tracer())
return KResult(-EBUSY); return EBUSY;
caller.set_wait_for_tracer_at_next_execve(true); caller.set_wait_for_tracer_at_next_execve(true);
return KSuccess; return KSuccess;
@ -49,23 +49,23 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
// long it is not the main thread. Alternatively, if this is desired, then the // long it is not the main thread. Alternatively, if this is desired, then the
// bug is that this prevents PT_ATTACH to the main thread from another thread. // bug is that this prevents PT_ATTACH to the main thread from another thread.
if (params.tid == caller.pid().value()) if (params.tid == caller.pid().value())
return KResult(-EINVAL); return EINVAL;
auto peer = Thread::from_tid(params.tid); auto peer = Thread::from_tid(params.tid);
if (!peer) if (!peer)
return KResult(-ESRCH); return ESRCH;
if ((peer->process().uid() != caller.euid()) if ((peer->process().uid() != caller.euid())
|| (peer->process().uid() != peer->process().euid())) // Disallow tracing setuid processes || (peer->process().uid() != peer->process().euid())) // Disallow tracing setuid processes
return KResult(-EACCES); return EACCES;
if (!peer->process().is_dumpable()) if (!peer->process().is_dumpable())
return KResult(-EACCES); return EACCES;
auto& peer_process = peer->process(); auto& peer_process = peer->process();
if (params.request == PT_ATTACH) { if (params.request == PT_ATTACH) {
if (peer_process.tracer()) { if (peer_process.tracer()) {
return KResult(-EBUSY); return EBUSY;
} }
peer_process.start_tracing_from(caller.pid()); peer_process.start_tracing_from(caller.pid());
ScopedSpinLock lock(peer->get_lock()); ScopedSpinLock lock(peer->get_lock());
@ -78,13 +78,13 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
auto* tracer = peer_process.tracer(); auto* tracer = peer_process.tracer();
if (!tracer) if (!tracer)
return KResult(-EPERM); return EPERM;
if (tracer->tracer_pid() != caller.pid()) if (tracer->tracer_pid() != caller.pid())
return KResult(-EBUSY); return EBUSY;
if (peer->state() == Thread::State::Running) if (peer->state() == Thread::State::Running)
return KResult(-EBUSY); return EBUSY;
scheduler_lock.unlock(); scheduler_lock.unlock();
@ -105,25 +105,25 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
case PT_GETREGS: { case PT_GETREGS: {
if (!tracer->has_regs()) if (!tracer->has_regs())
return KResult(-EINVAL); return EINVAL;
auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr); auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
if (!copy_to_user(regs, &tracer->regs())) if (!copy_to_user(regs, &tracer->regs()))
return KResult(-EFAULT); return EFAULT;
break; break;
} }
case PT_SETREGS: { case PT_SETREGS: {
if (!tracer->has_regs()) if (!tracer->has_regs())
return KResult(-EINVAL); return EINVAL;
PtraceRegisters regs; PtraceRegisters regs;
if (!copy_from_user(&regs, (const PtraceRegisters*)params.addr)) if (!copy_from_user(&regs, (const PtraceRegisters*)params.addr))
return KResult(-EFAULT); return EFAULT;
auto& peer_saved_registers = peer->get_register_dump_from_stack(); auto& peer_saved_registers = peer->get_register_dump_from_stack();
// Verify that the saved registers are in usermode context // Verify that the saved registers are in usermode context
if ((peer_saved_registers.cs & 0x03) != 3) if ((peer_saved_registers.cs & 0x03) != 3)
return KResult(-EFAULT); return EFAULT;
tracer->set_regs(regs); tracer->set_regs(regs);
copy_ptrace_registers_into_kernel_registers(peer_saved_registers, regs); copy_ptrace_registers_into_kernel_registers(peer_saved_registers, regs);
@ -133,24 +133,24 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
case PT_PEEK: { case PT_PEEK: {
Kernel::Syscall::SC_ptrace_peek_params peek_params; Kernel::Syscall::SC_ptrace_peek_params peek_params;
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr))) if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
return KResult(-EFAULT); return EFAULT;
if (!is_user_address(VirtualAddress { peek_params.address })) if (!is_user_address(VirtualAddress { peek_params.address }))
return KResult(-EFAULT); return EFAULT;
auto result = peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address }); auto result = peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address });
if (result.is_error()) if (result.is_error())
return result.error(); return result.error();
if (!copy_to_user(peek_params.out_data, &result.value())) if (!copy_to_user(peek_params.out_data, &result.value()))
return KResult(-EFAULT); return EFAULT;
break; break;
} }
case PT_POKE: case PT_POKE:
if (!is_user_address(VirtualAddress { params.addr })) if (!is_user_address(VirtualAddress { params.addr }))
return KResult(-EFAULT); return EFAULT;
return peer->process().poke_user_data(Userspace<u32*> { (FlatPtr)params.addr }, params.data); return peer->process().poke_user_data(Userspace<u32*> { (FlatPtr)params.addr }, params.data);
default: default:
return KResult(-EINVAL); return EINVAL;
} }
return KSuccess; return KSuccess;

View file

@ -73,13 +73,13 @@ KResultOr<size_t> StorageDevice::read(FileDescription&, size_t offset, UserOrKer
auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index, whole_blocks, outbuf, whole_blocks * block_size()); auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index, whole_blocks, outbuf, whole_blocks * block_size());
auto result = read_request->wait(); auto result = read_request->wait();
if (result.wait_result().was_interrupted()) if (result.wait_result().was_interrupted())
return KResult(-EINTR); return EINTR;
switch (result.request_result()) { switch (result.request_result()) {
case AsyncDeviceRequest::Failure: case AsyncDeviceRequest::Failure:
case AsyncDeviceRequest::Cancelled: case AsyncDeviceRequest::Cancelled:
return KResult(-EIO); return EIO;
case AsyncDeviceRequest::MemoryFault: case AsyncDeviceRequest::MemoryFault:
return KResult(-EFAULT); return EFAULT;
default: default:
break; break;
} }
@ -93,12 +93,12 @@ KResultOr<size_t> StorageDevice::read(FileDescription&, size_t offset, UserOrKer
auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size()); auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size());
auto result = read_request->wait(); auto result = read_request->wait();
if (result.wait_result().was_interrupted()) if (result.wait_result().was_interrupted())
return KResult(-EINTR); return EINTR;
switch (result.request_result()) { switch (result.request_result()) {
case AsyncDeviceRequest::Failure: case AsyncDeviceRequest::Failure:
return pos; return pos;
case AsyncDeviceRequest::Cancelled: case AsyncDeviceRequest::Cancelled:
return KResult(-EIO); return EIO;
case AsyncDeviceRequest::MemoryFault: case AsyncDeviceRequest::MemoryFault:
// This should never happen, we're writing to a kernel buffer! // This should never happen, we're writing to a kernel buffer!
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -106,7 +106,7 @@ KResultOr<size_t> StorageDevice::read(FileDescription&, size_t offset, UserOrKer
break; break;
} }
if (!outbuf.write(data.data(), pos, remaining)) if (!outbuf.write(data.data(), pos, remaining))
return KResult(-EFAULT); return EFAULT;
} }
return pos + remaining; return pos + remaining;
@ -140,13 +140,13 @@ KResultOr<size_t> StorageDevice::write(FileDescription&, size_t offset, const Us
auto write_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Write, index, whole_blocks, inbuf, whole_blocks * block_size()); auto write_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Write, index, whole_blocks, inbuf, whole_blocks * block_size());
auto result = write_request->wait(); auto result = write_request->wait();
if (result.wait_result().was_interrupted()) if (result.wait_result().was_interrupted())
return KResult(-EINTR); return EINTR;
switch (result.request_result()) { switch (result.request_result()) {
case AsyncDeviceRequest::Failure: case AsyncDeviceRequest::Failure:
case AsyncDeviceRequest::Cancelled: case AsyncDeviceRequest::Cancelled:
return KResult(-EIO); return EIO;
case AsyncDeviceRequest::MemoryFault: case AsyncDeviceRequest::MemoryFault:
return KResult(-EFAULT); return EFAULT;
default: default:
break; break;
} }
@ -165,12 +165,12 @@ KResultOr<size_t> StorageDevice::write(FileDescription&, size_t offset, const Us
auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size()); auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size());
auto result = read_request->wait(); auto result = read_request->wait();
if (result.wait_result().was_interrupted()) if (result.wait_result().was_interrupted())
return KResult(-EINTR); return EINTR;
switch (result.request_result()) { switch (result.request_result()) {
case AsyncDeviceRequest::Failure: case AsyncDeviceRequest::Failure:
return pos; return pos;
case AsyncDeviceRequest::Cancelled: case AsyncDeviceRequest::Cancelled:
return KResult(-EIO); return EIO;
case AsyncDeviceRequest::MemoryFault: case AsyncDeviceRequest::MemoryFault:
// This should never happen, we're writing to a kernel buffer! // This should never happen, we're writing to a kernel buffer!
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -180,18 +180,18 @@ KResultOr<size_t> StorageDevice::write(FileDescription&, size_t offset, const Us
} }
if (!inbuf.read(data.data(), pos, remaining)) if (!inbuf.read(data.data(), pos, remaining))
return KResult(-EFAULT); return EFAULT;
{ {
auto write_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Write, index + whole_blocks, 1, data_buffer, block_size()); auto write_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Write, index + whole_blocks, 1, data_buffer, block_size());
auto result = write_request->wait(); auto result = write_request->wait();
if (result.wait_result().was_interrupted()) if (result.wait_result().was_interrupted())
return KResult(-EINTR); return EINTR;
switch (result.request_result()) { switch (result.request_result()) {
case AsyncDeviceRequest::Failure: case AsyncDeviceRequest::Failure:
return pos; return pos;
case AsyncDeviceRequest::Cancelled: case AsyncDeviceRequest::Cancelled:
return KResult(-EIO); return EIO;
case AsyncDeviceRequest::MemoryFault: case AsyncDeviceRequest::MemoryFault:
// This should never happen, we're writing to a kernel buffer! // This should never happen, we're writing to a kernel buffer!
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();

View file

@ -149,7 +149,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
auto vmobject = SharedInodeVMObject::create_with_inode(inode); auto vmobject = SharedInodeVMObject::create_with_inode(inode);
if (vmobject->writable_mappings()) { if (vmobject->writable_mappings()) {
dbgln("Refusing to execute a write-mapped program"); dbgln("Refusing to execute a write-mapped program");
return KResult(-ETXTBSY); return ETXTBSY;
} }
size_t executable_size = inode.size(); size_t executable_size = inode.size();
@ -157,13 +157,13 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
auto executable_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_ROUND_UP(executable_size), "ELF loading", Region::Access::Read); auto executable_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_ROUND_UP(executable_size), "ELF loading", Region::Access::Read);
if (!executable_region) { if (!executable_region) {
dbgln("Could not allocate memory for ELF loading"); dbgln("Could not allocate memory for ELF loading");
return KResult(-ENOMEM); return ENOMEM;
} }
auto elf_image = ELF::Image(executable_region->vaddr().as_ptr(), executable_size); auto elf_image = ELF::Image(executable_region->vaddr().as_ptr(), executable_size);
if (!elf_image.is_valid()) if (!elf_image.is_valid())
return KResult(-ENOEXEC); return ENOEXEC;
Region* master_tls_region { nullptr }; Region* master_tls_region { nullptr };
size_t master_tls_size = 0; size_t master_tls_size = 0;
@ -181,7 +181,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
if (!elf_image.is_within_image(program_header.raw_data(), program_header.size_in_image())) { if (!elf_image.is_within_image(program_header.raw_data(), program_header.size_in_image())) {
dbgln("Shenanigans! ELF PT_TLS header sneaks outside of executable."); dbgln("Shenanigans! ELF PT_TLS header sneaks outside of executable.");
ph_load_result = KResult(-ENOEXEC); ph_load_result = ENOEXEC;
return IterationDecision::Break; return IterationDecision::Break;
} }
@ -195,7 +195,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
master_tls_alignment = program_header.alignment(); master_tls_alignment = program_header.alignment();
if (!copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image())) { if (!copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image())) {
ph_load_result = KResult(-EFAULT); ph_load_result = EFAULT;
return IterationDecision::Break; return IterationDecision::Break;
} }
return IterationDecision::Continue; return IterationDecision::Continue;
@ -210,7 +210,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
if (!elf_image.is_within_image(program_header.raw_data(), program_header.size_in_image())) { if (!elf_image.is_within_image(program_header.raw_data(), program_header.size_in_image())) {
dbgln("Shenanigans! Writable ELF PT_LOAD header sneaks outside of executable."); dbgln("Shenanigans! Writable ELF PT_LOAD header sneaks outside of executable.");
ph_load_result = KResult(-ENOEXEC); ph_load_result = ENOEXEC;
return IterationDecision::Break; return IterationDecision::Break;
} }
@ -236,7 +236,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
auto page_offset = program_header.vaddr(); auto page_offset = program_header.vaddr();
page_offset.mask(~PAGE_MASK); page_offset.mask(~PAGE_MASK);
if (!copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image())) { if (!copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image())) {
ph_load_result = KResult(-EFAULT); ph_load_result = EFAULT;
return IterationDecision::Break; return IterationDecision::Break;
} }
return IterationDecision::Continue; return IterationDecision::Continue;
@ -269,7 +269,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
if (!elf_image.entry().offset(load_offset).get()) { if (!elf_image.entry().offset(load_offset).get()) {
dbgln("do_exec: Failure loading program, entry pointer is invalid! {})", elf_image.entry().offset(load_offset)); dbgln("do_exec: Failure loading program, entry pointer is invalid! {})", elf_image.entry().offset(load_offset));
return KResult(-ENOEXEC); return ENOEXEC;
} }
auto stack_region_or_error = allocate_region(VirtualAddress(), Thread::default_userspace_stack_size, "Stack (Main thread)", PROT_READ | PROT_WRITE, AllocationStrategy::Reserve); auto stack_region_or_error = allocate_region(VirtualAddress(), Thread::default_userspace_stack_size, "Stack (Main thread)", PROT_READ | PROT_WRITE, AllocationStrategy::Reserve);
@ -299,7 +299,7 @@ KResultOr<Process::LoadResult> Process::load(NonnullRefPtr<FileDescription> main
{ {
auto page_directory = PageDirectory::create_for_userspace(*this); auto page_directory = PageDirectory::create_for_userspace(*this);
if (!page_directory) if (!page_directory)
return KResult(-ENOMEM); return ENOMEM;
// Need to make sure we don't swap contexts in the middle // Need to make sure we don't swap contexts in the middle
ScopedCritical critical; ScopedCritical critical;
@ -366,12 +366,12 @@ static KResultOr<RequiredLoadRange> get_required_load_range(FileDescription& pro
auto region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_ROUND_UP(executable_size), "ELF memory range calculation", Region::Access::Read); auto region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_ROUND_UP(executable_size), "ELF memory range calculation", Region::Access::Read);
if (!region) { if (!region) {
dbgln("Could not allocate memory for ELF"); dbgln("Could not allocate memory for ELF");
return KResult(-ENOMEM); return ENOMEM;
} }
auto elf_image = ELF::Image(region->vaddr().as_ptr(), executable_size); auto elf_image = ELF::Image(region->vaddr().as_ptr(), executable_size);
if (!elf_image.is_valid()) { if (!elf_image.is_valid()) {
return -EINVAL; return EINVAL;
} }
RequiredLoadRange range {}; RequiredLoadRange range {};
@ -688,7 +688,7 @@ static KResultOr<Vector<String>> find_shebang_interpreter_for_executable(const c
return interpreter_words; return interpreter_words;
} }
return KResult(-ENOEXEC); return ENOEXEC;
} }
KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(const String& path, const Elf32_Ehdr& main_program_header, int nread, size_t file_size) KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(const String& path, const Elf32_Ehdr& main_program_header, int nread, size_t file_size)
@ -698,7 +698,7 @@ KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(
String interpreter_path; String interpreter_path;
if (!ELF::validate_program_headers(main_program_header, file_size, (const u8*)&main_program_header, nread, &interpreter_path)) { if (!ELF::validate_program_headers(main_program_header, file_size, (const u8*)&main_program_header, nread, &interpreter_path)) {
dbgln("exec({}): File has invalid ELF Program headers", path); dbgln("exec({}): File has invalid ELF Program headers", path);
return KResult(-ENOEXEC); return ENOEXEC;
} }
if (!interpreter_path.is_empty()) { if (!interpreter_path.is_empty()) {
@ -719,34 +719,34 @@ KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(
// Validate the program interpreter as a valid elf binary. // Validate the program interpreter as a valid elf binary.
// If your program interpreter is a #! file or something, it's time to stop playing games :) // If your program interpreter is a #! file or something, it's time to stop playing games :)
if (interp_metadata.size < (int)sizeof(Elf32_Ehdr)) if (interp_metadata.size < (int)sizeof(Elf32_Ehdr))
return KResult(-ENOEXEC); return ENOEXEC;
char first_page[PAGE_SIZE] = {}; char first_page[PAGE_SIZE] = {};
auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page); auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page);
auto nread_or_error = interpreter_description->read(first_page_buffer, sizeof(first_page)); auto nread_or_error = interpreter_description->read(first_page_buffer, sizeof(first_page));
if (nread_or_error.is_error()) if (nread_or_error.is_error())
return KResult(-ENOEXEC); return ENOEXEC;
nread = nread_or_error.value(); nread = nread_or_error.value();
if (nread < (int)sizeof(Elf32_Ehdr)) if (nread < (int)sizeof(Elf32_Ehdr))
return KResult(-ENOEXEC); return ENOEXEC;
auto elf_header = (Elf32_Ehdr*)first_page; auto elf_header = (Elf32_Ehdr*)first_page;
if (!ELF::validate_elf_header(*elf_header, interp_metadata.size)) { if (!ELF::validate_elf_header(*elf_header, interp_metadata.size)) {
dbgln("exec({}): Interpreter ({}) has invalid ELF header", path, interpreter_description->absolute_path()); dbgln("exec({}): Interpreter ({}) has invalid ELF header", path, interpreter_description->absolute_path());
return KResult(-ENOEXEC); return ENOEXEC;
} }
// Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD // Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD
String interpreter_interpreter_path; String interpreter_interpreter_path;
if (!ELF::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, &interpreter_interpreter_path)) { if (!ELF::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, &interpreter_interpreter_path)) {
dbgln("exec({}): Interpreter ({}) has invalid ELF Program headers", path, interpreter_description->absolute_path()); dbgln("exec({}): Interpreter ({}) has invalid ELF Program headers", path, interpreter_description->absolute_path());
return KResult(-ENOEXEC); return ENOEXEC;
} }
if (!interpreter_interpreter_path.is_empty()) { if (!interpreter_interpreter_path.is_empty()) {
dbgln("exec({}): Interpreter ({}) has its own interpreter ({})! No thank you!", path, interpreter_description->absolute_path(), interpreter_interpreter_path); dbgln("exec({}): Interpreter ({}) has its own interpreter ({})! No thank you!", path, interpreter_description->absolute_path(), interpreter_interpreter_path);
return KResult(-ELOOP); return ELOOP;
} }
return interpreter_description; return interpreter_description;
@ -754,7 +754,7 @@ KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(
if (main_program_header.e_type == ET_REL) { if (main_program_header.e_type == ET_REL) {
// We can't exec an ET_REL, that's just an object file from the compiler // We can't exec an ET_REL, that's just an object file from the compiler
return KResult(-ENOEXEC); return ENOEXEC;
} }
if (main_program_header.e_type == ET_DYN) { if (main_program_header.e_type == ET_DYN) {
// If it's ET_DYN with no PT_INTERP, then it's a dynamic executable responsible // If it's ET_DYN with no PT_INTERP, then it's a dynamic executable responsible
@ -817,12 +817,12 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
// #2) ELF32 for i386 // #2) ELF32 for i386
if (nread_or_error.value() < (int)sizeof(Elf32_Ehdr)) if (nread_or_error.value() < (int)sizeof(Elf32_Ehdr))
return KResult(-ENOEXEC); return ENOEXEC;
auto main_program_header = (Elf32_Ehdr*)first_page; auto main_program_header = (Elf32_Ehdr*)first_page;
if (!ELF::validate_elf_header(*main_program_header, metadata.size)) { if (!ELF::validate_elf_header(*main_program_header, metadata.size)) {
dbgln("exec({}): File has invalid ELF header", path); dbgln("exec({}): File has invalid ELF header", path);
return KResult(-ENOEXEC); return ENOEXEC;
} }
auto elf_result = find_elf_interpreter_for_executable(path, *main_program_header, nread_or_error.value(), metadata.size); auto elf_result = find_elf_interpreter_for_executable(path, *main_program_header, nread_or_error.value(), metadata.size);

View file

@ -33,10 +33,10 @@ KResult Process::do_kill(Process& process, int signal)
// FIXME: Allow sending SIGCONT to everyone in the process group. // FIXME: Allow sending SIGCONT to everyone in the process group.
// FIXME: Should setuid processes have some special treatment here? // FIXME: Should setuid processes have some special treatment here?
if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid) if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid)
return KResult(-EPERM); return EPERM;
if (process.is_kernel_process() && signal == SIGKILL) { if (process.is_kernel_process() && signal == SIGKILL) {
klog() << "attempted to send SIGKILL to kernel process " << process.name().characters() << "(" << process.pid().value() << ")"; klog() << "attempted to send SIGKILL to kernel process " << process.name().characters() << "(" << process.pid().value() << ")";
return KResult(-EPERM); return EPERM;
} }
if (signal != 0) if (signal != 0)
return process.send_signal(signal, this); return process.send_signal(signal, this);
@ -72,7 +72,7 @@ KResult Process::do_killpg(ProcessGroupID pgrp, int signal)
}); });
if (group_was_empty) if (group_was_empty)
return KResult(-ESRCH); return ESRCH;
if (any_succeeded) if (any_succeeded)
return KSuccess; return KSuccess;
return error; return error;

View file

@ -42,7 +42,7 @@ int Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params)
if (!copy_from_user(&params, user_params)) if (!copy_from_user(&params, user_params))
return -EFAULT; return -EFAULT;
auto result = Ptrace::handle_syscall(params, *this); auto result = Ptrace::handle_syscall(params, *this);
return result.is_error() ? result.error() : result.value(); return result.is_error() ? result.error().error() : result.value();
} }
/** /**
@ -64,7 +64,7 @@ KResultOr<u32> Process::peek_user_data(Userspace<const u32*> address)
ProcessPagingScope scope(*this); ProcessPagingScope scope(*this);
if (!copy_from_user(&result, address)) { if (!copy_from_user(&result, address)) {
dbgln("Invalid address for peek_user_data: {}", address.ptr()); dbgln("Invalid address for peek_user_data: {}", address.ptr());
return KResult(-EFAULT); return EFAULT;
} }
return result; return result;
@ -75,7 +75,7 @@ KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
Range range = { VirtualAddress(address), sizeof(u32) }; Range range = { VirtualAddress(address), sizeof(u32) };
auto* region = find_region_containing(range); auto* region = find_region_containing(range);
if (!region) if (!region)
return KResult(-EFAULT); return EFAULT;
ProcessPagingScope scope(*this); ProcessPagingScope scope(*this);
if (region->is_shared()) { if (region->is_shared()) {
// If the region is shared, we change its vmobject to a PrivateInodeVMObject // If the region is shared, we change its vmobject to a PrivateInodeVMObject
@ -98,7 +98,7 @@ KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
if (!copy_to_user(address, &data)) { if (!copy_to_user(address, &data)) {
dbgln("poke_user_data: Bad address {:p}", address.ptr()); dbgln("poke_user_data: Bad address {:p}", address.ptr());
return KResult(-EFAULT); return EFAULT;
} }
return KSuccess; return KSuccess;

View file

@ -38,12 +38,12 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
case P_PGID: case P_PGID:
break; break;
default: default:
return KResult(-EINVAL); return EINVAL;
} }
KResultOr<siginfo_t> result = KResult(KSuccess); KResultOr<siginfo_t> result = KResult(KSuccess);
if (Thread::current()->block<Thread::WaitBlocker>({}, options, idtype, id, result).was_interrupted()) if (Thread::current()->block<Thread::WaitBlocker>({}, options, idtype, id, result).was_interrupted())
return KResult(-EINTR); return EINTR;
ASSERT(!result.is_error() || (options & WNOHANG) || result.error() != KSuccess); ASSERT(!result.is_error() || (options & WNOHANG) || result.error() != KSuccess);
return result; return result;
} }

View file

@ -75,7 +75,7 @@ KResultOr<size_t> MasterPTY::read(FileDescription&, size_t, UserOrKernelBuffer&
KResultOr<size_t> MasterPTY::write(FileDescription&, size_t, const UserOrKernelBuffer& buffer, size_t size) KResultOr<size_t> MasterPTY::write(FileDescription&, size_t, const UserOrKernelBuffer& buffer, size_t size)
{ {
if (!m_slave) if (!m_slave)
return KResult(-EIO); return EIO;
m_slave->on_master_write(buffer, size); m_slave->on_master_write(buffer, size);
return size; return size;
} }

View file

@ -59,7 +59,7 @@ KResultOr<NonnullRefPtr<FileDescription>> PTYMultiplexer::open(int options)
{ {
LOCKER(m_lock); LOCKER(m_lock);
if (m_freelist.is_empty()) if (m_freelist.is_empty())
return KResult(-EBUSY); return EBUSY;
auto master_index = m_freelist.take_last(); auto master_index = m_freelist.take_last();
auto master = adopt(*new MasterPTY(master_index)); auto master = adopt(*new MasterPTY(master_index));
#ifdef PTMX_DEBUG #ifdef PTMX_DEBUG

View file

@ -58,7 +58,7 @@ KResultOr<size_t> TTY::read(FileDescription&, size_t, UserOrKernelBuffer& buffer
if (Process::current()->pgid() != pgid()) { if (Process::current()->pgid() != pgid()) {
// FIXME: Should we propagate this error path somehow? // FIXME: Should we propagate this error path somehow?
[[maybe_unused]] auto rc = Process::current()->send_signal(SIGTTIN, nullptr); [[maybe_unused]] auto rc = Process::current()->send_signal(SIGTTIN, nullptr);
return KResult(-EINTR); return EINTR;
} }
if (m_input_buffer.size() < static_cast<size_t>(size)) if (m_input_buffer.size() < static_cast<size_t>(size))
@ -95,7 +95,7 @@ KResultOr<size_t> TTY::read(FileDescription&, size_t, UserOrKernelBuffer& buffer
}); });
} }
if (nwritten < 0) if (nwritten < 0)
return KResult(nwritten); return KResult((ErrnoCode)-nwritten);
if (nwritten > 0 || need_evaluate_block_conditions) if (nwritten > 0 || need_evaluate_block_conditions)
evaluate_block_conditions(); evaluate_block_conditions();
return (size_t)nwritten; return (size_t)nwritten;
@ -105,7 +105,7 @@ KResultOr<size_t> TTY::write(FileDescription&, size_t, const UserOrKernelBuffer&
{ {
if (m_termios.c_lflag & TOSTOP && Process::current()->pgid() != pgid()) { if (m_termios.c_lflag & TOSTOP && Process::current()->pgid() != pgid()) {
[[maybe_unused]] auto rc = Process::current()->send_signal(SIGTTOU, nullptr); [[maybe_unused]] auto rc = Process::current()->send_signal(SIGTTOU, nullptr);
return KResult(-EINTR); return EINTR;
} }
on_tty_write(buffer, size); on_tty_write(buffer, size);

View file

@ -748,11 +748,11 @@ public:
KResult try_join(AddBlockerHandler add_blocker) KResult try_join(AddBlockerHandler add_blocker)
{ {
if (Thread::current() == this) if (Thread::current() == this)
return KResult(-EDEADLK); return EDEADLK;
ScopedSpinLock lock(m_lock); ScopedSpinLock lock(m_lock);
if (!m_is_joinable || state() == Dead) if (!m_is_joinable || state() == Dead)
return KResult(-EINVAL); return EINVAL;
add_blocker(); add_blocker();

View file

@ -611,7 +611,7 @@ Thread::WaitBlocker::WaitBlocker(int wait_options, idtype_t id_type, pid_t id, K
case P_PID: { case P_PID: {
m_waitee = Process::from_pid(m_waitee_id); m_waitee = Process::from_pid(m_waitee_id);
if (!m_waitee || m_waitee->ppid() != Process::current()->pid()) { if (!m_waitee || m_waitee->ppid() != Process::current()->pid()) {
m_result = KResult(-ECHILD); m_result = ECHILD;
m_error = true; m_error = true;
return; return;
} }
@ -620,7 +620,7 @@ Thread::WaitBlocker::WaitBlocker(int wait_options, idtype_t id_type, pid_t id, K
case P_PGID: { case P_PGID: {
m_waitee_group = ProcessGroup::from_pgid(m_waitee_id); m_waitee_group = ProcessGroup::from_pgid(m_waitee_id);
if (!m_waitee_group) { if (!m_waitee_group) {
m_result = KResult(-ECHILD); m_result = ECHILD;
m_error = true; m_error = true;
return; return;
} }
@ -670,7 +670,7 @@ void Thread::WaitBlocker::do_was_disowned()
{ {
ASSERT(!m_did_unblock); ASSERT(!m_did_unblock);
m_did_unblock = true; m_did_unblock = true;
m_result = KResult(-ECHILD); m_result = ECHILD;
} }
void Thread::WaitBlocker::do_set_result(const siginfo_t& result) void Thread::WaitBlocker::do_set_result(const siginfo_t& result)

View file

@ -26,78 +26,155 @@
#pragma once #pragma once
#define EPERM 1 enum ErrnoCode {
#define ENOENT 2 EPERM = 1,
#define ESRCH 3 #define EPERM EPERM
#define EINTR 4 ENOENT,
#define EIO 5 #define ENOENT ENOENT
#define ENXIO 6 ESRCH,
#define E2BIG 7 #define ESRCH ESRCH
#define ENOEXEC 8 EINTR,
#define EBADF 9 #define EINTR EINTR
#define ECHILD 10 EIO,
#define EAGAIN 11 #define EIO EIO
#define ENOMEM 12 ENXIO,
#define EACCES 13 #define ENXIO ENXIO
#define EFAULT 14 E2BIG,
#define ENOTBLK 15 #define E2BIG E2BIG
#define EBUSY 16 ENOEXEC,
#define EEXIST 17 #define ENOEXEC ENOEXEC
#define EXDEV 18 EBADF,
#define ENODEV 19 #define EBADF EBADF
#define ENOTDIR 20 ECHILD,
#define EISDIR 21 #define ECHILD ECHILD
#define EINVAL 22 EAGAIN,
#define ENFILE 23 #define EAGAIN EAGAIN
#define EMFILE 24 ENOMEM,
#define ENOTTY 25 #define ENOMEM ENOMEM
#define ETXTBSY 26 EACCES,
#define EFBIG 27 #define EACCES EACCES
#define ENOSPC 28 EFAULT,
#define ESPIPE 29 #define EFAULT EFAULT
#define EROFS 30 ENOTBLK,
#define EMLINK 31 #define ENOTBLK ENOTBLK
#define EPIPE 32 EBUSY,
#define ERANGE 33 #define EBUSY EBUSY
#define ENAMETOOLONG 34 EEXIST,
#define ELOOP 35 #define EEXIST EEXIST
#define EOVERFLOW 36 EXDEV,
#define EOPNOTSUPP 37 #define EXDEV EXDEV
#define ENOSYS 38 ENODEV,
#define ENOTIMPL 39 #define ENODEV ENODEV
#define EAFNOSUPPORT 40 ENOTDIR,
#define ENOTSOCK 41 #define ENOTDIR ENOTDIR
#define EADDRINUSE 42 EISDIR,
#define EWHYTHO 43 #define EISDIR EISDIR
#define ENOTEMPTY 44 EINVAL,
#define EDOM 45 #define EINVAL EINVAL
#define ECONNREFUSED 46 ENFILE,
#define EADDRNOTAVAIL 47 #define ENFILE ENFILE
#define EISCONN 48 EMFILE,
#define ECONNABORTED 49 #define EMFILE EMFILE
#define EALREADY 50 ENOTTY,
#define ECONNRESET 51 #define ENOTTY ENOTTY
#define EDESTADDRREQ 52 ETXTBSY,
#define EHOSTUNREACH 53 #define ETXTBSY ETXTBSY
#define EILSEQ 54 EFBIG,
#define EMSGSIZE 55 #define EFBIG EFBIG
#define ENETDOWN 56 ENOSPC,
#define ENETUNREACH 57 #define ENOSPC ENOSPC
#define ENETRESET 58 ESPIPE,
#define ENOBUFS 59 #define ESPIPE ESPIPE
#define ENOLCK 60 EROFS,
#define ENOMSG 61 #define EROFS EROFS
#define ENOPROTOOPT 62 EMLINK,
#define ENOTCONN 63 #define EMLINK EMLINK
#define EWOULDBLOCK 64 EPIPE,
#define EPROTONOSUPPORT 65 #define EPIPE EPIPE
#define EDEADLK 66 ERANGE,
#define ETIMEDOUT 67 #define ERANGE ERANGE
#define EPROTOTYPE 68 ENAMETOOLONG,
#define EINPROGRESS 69 #define ENAMETOOLONG ENAMETOOLONG
#define ENOTHREAD 70 ELOOP,
#define EPROTO 71 #define ELOOP ELOOP
#define ENOTSUP 72 EOVERFLOW,
#define EPFNOSUPPORT 73 #define EOVERFLOW EOVERFLOW
#define EDIRINTOSELF 74 EOPNOTSUPP,
#define EMAXERRNO 75 #define EOPNOTSUPP EOPNOTSUPP
ENOSYS,
#define ENOSYS ENOSYS
ENOTIMPL,
#define ENOTIMPL ENOTIMPL
EAFNOSUPPORT,
#define EAFNOSUPPORT EAFNOSUPPORT
ENOTSOCK,
#define ENOTSOCK ENOTSOCK
EADDRINUSE,
#define EADDRINUSE EADDRINUSE
EWHYTHO,
#define EWHYTHO EWHYTHO
ENOTEMPTY,
#define ENOTEMPTY ENOTEMPTY
EDOM,
#define EDOM EDOM
ECONNREFUSED,
#define ECONNREFUSED ECONNREFUSED
EADDRNOTAVAIL,
#define EADDRNOTAVAIL EADDRNOTAVAIL
EISCONN,
#define EISCONN EISCONN
ECONNABORTED,
#define ECONNABORTED ECONNABORTED
EALREADY,
#define EALREADY EALREADY
ECONNRESET,
#define ECONNRESET ECONNRESET
EDESTADDRREQ,
#define EDESTADDRREQ EDESTADDRREQ
EHOSTUNREACH,
#define EHOSTUNREACH EHOSTUNREACH
EILSEQ,
#define EILSEQ EILSEQ
EMSGSIZE,
#define EMSGSIZE EMSGSIZE
ENETDOWN,
#define ENETDOWN ENETDOWN
ENETUNREACH,
#define ENETUNREACH ENETUNREACH
ENETRESET,
#define ENETRESET ENETRESET
ENOBUFS,
#define ENOBUFS ENOBUFS
ENOLCK,
#define ENOLCK ENOLCK
ENOMSG,
#define ENOMSG ENOMSG
ENOPROTOOPT,
#define ENOPROTOOPT ENOPROTOOPT
ENOTCONN,
#define ENOTCONN ENOTCONN
EWOULDBLOCK,
#define EWOULDBLOCK EWOULDBLOCK
EPROTONOSUPPORT,
#define EPROTONOSUPPORT EPROTONOSUPPORT
EDEADLK,
#define EDEADLK EDEADLK
ETIMEDOUT,
#define ETIMEDOUT ETIMEDOUT
EPROTOTYPE,
#define EPROTOTYPE EPROTOTYPE
EINPROGRESS,
#define EINPROGRESS EINPROGRESS
ENOTHREAD,
#define ENOTHREAD ENOTHREAD
EPROTO,
#define EPROTO EPROTO
ENOTSUP,
#define ENOTSUP ENOTSUP
EPFNOSUPPORT,
#define EPFNOSUPPORT EPFNOSUPPORT
EDIRINTOSELF,
#define EDIRINTOSELF EDIRINTOSELF
EMAXERRNO,
#define EMAXERRNO EMAXERRNO
};