Kernel: Don't block in send until full message is sent

Only block until some data was sent. This allows select + send to be
actually non blocking if used correctly.

Also fixes a bug with non blocking sockets that could not send the full
message is one try.
This commit is contained in:
Bananymous 2025-06-27 20:51:33 +03:00
parent 850b3284ac
commit 5b0e5512a8
1 changed files with 6 additions and 25 deletions

View File

@ -544,33 +544,14 @@ namespace Kernel
} }
LockGuard _(inode->m_mutex); LockGuard _(inode->m_mutex);
if (inode->has_hungup())
const auto check_errors =
[&inode, is_nonblock]() -> BAN::ErrorOr<void>
{
if (inode->has_hungup())
{
Thread::current().add_signal(SIGPIPE);
return BAN::Error::from_errno(EPIPE);
}
if (is_nonblock && !inode->can_write())
return BAN::Error::from_errno(EWOULDBLOCK);
return {};
};
TRY(check_errors());
size_t total_sent = 0;
while (total_sent < buffer.size())
{ {
TRY(check_errors()); Thread::current().add_signal(SIGPIPE);
const size_t nsend = TRY(inode->sendto(buffer.slice(total_sent), address, address_len)); return BAN::Error::from_errno(EPIPE);
if (nsend == 0)
return 0;
total_sent += nsend;
} }
if (is_nonblock && !inode->can_write())
return total_sent; return BAN::Error::from_errno(EWOULDBLOCK);
return inode->sendto(buffer, address, address_len);
} }
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const