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:
parent
2f646f4284
commit
24fd8fb16f
1 changed files with 19 additions and 2 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue