1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 07:38:10 +00:00

Kernel: Ensure socket is suitable for writing in sys$sendmsg

Previously we would return a bytes written value of 0 if the writing end
of the socket was full. Now we either exit with EAGAIN if the socket
description is non-blocking, or block until the description can be
written to.

This is mostly a copy of the conditions in sys$write but with the "total
nwritten" parts removed as sys$sendmsg does not have that.
This commit is contained in:
sin-ack 2022-02-07 11:03:34 +00:00 committed by Andreas Kling
parent 2f646f4284
commit 24fd8fb16f

View file

@ -196,12 +196,29 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
auto description = TRY(open_file_description(sockfd));
if (!description->is_socket())
return ENOTSOCK;
auto& socket = *description->socket();
if (socket.is_shut_down_for_writing())
return EPIPE;
auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len));
auto bytes_sent = TRY(socket.sendto(*description, data_buffer, iovs[0].iov_len, flags, user_addr, addr_length));
return bytes_sent;
while (true) {
while (!description->can_write()) {
if (!description->is_blocking()) {
return EAGAIN;
}
auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
if (Thread::current()->block<Thread::WriteBlocker>({}, *description, unblock_flags).was_interrupted()) {
return EINTR;
}
// TODO: handle exceptions in unblock_flags
}
auto bytes_sent = TRY(socket.sendto(*description, data_buffer, iovs[0].iov_len, flags, user_addr, addr_length));
if (bytes_sent > 0)
return bytes_sent;
}
}
ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int flags)