mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 17:24:48 -05:00
UserspaceEmulator: Support all msg_iovlens in recvmsg and sendmsg
The kernel doesn't support msg_iovlens != 1 yet and nothing passes an amount != 1, but if anyone ever adds support for this they won't have to worry about ue at least.
This commit is contained in:
parent
29ef65c458
commit
31e7f73aae
Notes:
sideshowbarker
2024-07-19 02:20:27 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/31e7f73aaed Pull-request: https://github.com/SerenityOS/serenity/pull/3537
1 changed files with 21 additions and 15 deletions
|
@ -599,24 +599,28 @@ int Emulator::virt$recvmsg(int sockfd, FlatPtr msg_addr, int flags)
|
|||
msghdr mmu_msg;
|
||||
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
||||
|
||||
if (mmu_msg.msg_iovlen != 1)
|
||||
return -ENOTSUP; // FIXME: Support this :)
|
||||
iovec mmu_iov;
|
||||
mmu().copy_from_vm(&mmu_iov, (FlatPtr)mmu_msg.msg_iov, sizeof(mmu_iov));
|
||||
auto buffer = ByteBuffer::create_uninitialized(mmu_iov.iov_len);
|
||||
Vector<iovec, 1> mmu_iovs;
|
||||
mmu_iovs.resize(mmu_msg.msg_iovlen);
|
||||
mmu().copy_from_vm(mmu_iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
|
||||
Vector<ByteBuffer, 1> buffers;
|
||||
Vector<iovec, 1> iovs;
|
||||
for (const auto& iov : mmu_iovs) {
|
||||
buffers.append(ByteBuffer::create_uninitialized(iov.iov_len));
|
||||
iovs.append({ buffers.last().data(), buffers.last().size() });
|
||||
}
|
||||
|
||||
ByteBuffer control_buffer;
|
||||
if (mmu_msg.msg_control)
|
||||
control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
|
||||
|
||||
sockaddr_storage addr;
|
||||
iovec iov = { buffer.data(), buffer.size() };
|
||||
msghdr msg = { &addr, sizeof(addr), &iov, 1, mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
||||
msghdr msg = { &addr, sizeof(addr), iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
||||
int rc = recvmsg(sockfd, &msg, flags);
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
|
||||
mmu().copy_to_vm((FlatPtr)mmu_iov.iov_base, buffer.data(), mmu_iov.iov_len);
|
||||
for (size_t i = 0; i < buffers.size(); ++i)
|
||||
mmu().copy_to_vm((FlatPtr)mmu_iovs[i].iov_base, buffers[i].data(), mmu_iovs[i].iov_len);
|
||||
|
||||
if (mmu_msg.msg_name)
|
||||
mmu().copy_to_vm((FlatPtr)mmu_msg.msg_name, &addr, min(sizeof(addr), (size_t)mmu_msg.msg_namelen));
|
||||
|
@ -634,11 +638,14 @@ int Emulator::virt$sendmsg(int sockfd, FlatPtr msg_addr, int flags)
|
|||
msghdr mmu_msg;
|
||||
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
||||
|
||||
if (mmu_msg.msg_iovlen != 1)
|
||||
return -ENOTSUP; // FIXME: Support this :)
|
||||
iovec mmu_iov;
|
||||
mmu().copy_from_vm(&mmu_iov, (FlatPtr)mmu_msg.msg_iov, sizeof(mmu_iov));
|
||||
auto buffer = mmu().copy_buffer_from_vm((FlatPtr)mmu_iov.iov_base, mmu_iov.iov_len);
|
||||
Vector<iovec, 1> iovs;
|
||||
iovs.resize(mmu_msg.msg_iovlen);
|
||||
mmu().copy_from_vm(iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
|
||||
Vector<ByteBuffer, 1> buffers;
|
||||
for (auto& iov : iovs) {
|
||||
buffers.append(mmu().copy_buffer_from_vm((FlatPtr)iov.iov_base, iov.iov_len));
|
||||
iov = { buffers.last().data(), buffers.last().size() };
|
||||
}
|
||||
|
||||
ByteBuffer control_buffer;
|
||||
if (mmu_msg.msg_control)
|
||||
|
@ -651,8 +658,7 @@ int Emulator::virt$sendmsg(int sockfd, FlatPtr msg_addr, int flags)
|
|||
mmu().copy_from_vm(&address, (FlatPtr)mmu_msg.msg_name, address_length);
|
||||
}
|
||||
|
||||
iovec iov = { buffer.data(), buffer.size() };
|
||||
msghdr msg = { mmu_msg.msg_name ? &address : nullptr, address_length, &iov, 1, mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
||||
msghdr msg = { mmu_msg.msg_name ? &address : nullptr, address_length, iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
||||
return sendmsg(sockfd, &msg, flags);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue