mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 01:38:10 +00: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
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;
|
msghdr mmu_msg;
|
||||||
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
||||||
|
|
||||||
if (mmu_msg.msg_iovlen != 1)
|
Vector<iovec, 1> mmu_iovs;
|
||||||
return -ENOTSUP; // FIXME: Support this :)
|
mmu_iovs.resize(mmu_msg.msg_iovlen);
|
||||||
iovec mmu_iov;
|
mmu().copy_from_vm(mmu_iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
|
||||||
mmu().copy_from_vm(&mmu_iov, (FlatPtr)mmu_msg.msg_iov, sizeof(mmu_iov));
|
Vector<ByteBuffer, 1> buffers;
|
||||||
auto buffer = ByteBuffer::create_uninitialized(mmu_iov.iov_len);
|
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;
|
ByteBuffer control_buffer;
|
||||||
if (mmu_msg.msg_control)
|
if (mmu_msg.msg_control)
|
||||||
control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
|
control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
|
||||||
|
|
||||||
sockaddr_storage addr;
|
sockaddr_storage addr;
|
||||||
iovec iov = { buffer.data(), buffer.size() };
|
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 };
|
||||||
msghdr msg = { &addr, sizeof(addr), &iov, 1, mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
|
||||||
int rc = recvmsg(sockfd, &msg, flags);
|
int rc = recvmsg(sockfd, &msg, flags);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -errno;
|
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)
|
if (mmu_msg.msg_name)
|
||||||
mmu().copy_to_vm((FlatPtr)mmu_msg.msg_name, &addr, min(sizeof(addr), (size_t)mmu_msg.msg_namelen));
|
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;
|
msghdr mmu_msg;
|
||||||
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
|
||||||
|
|
||||||
if (mmu_msg.msg_iovlen != 1)
|
Vector<iovec, 1> iovs;
|
||||||
return -ENOTSUP; // FIXME: Support this :)
|
iovs.resize(mmu_msg.msg_iovlen);
|
||||||
iovec mmu_iov;
|
mmu().copy_from_vm(iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
|
||||||
mmu().copy_from_vm(&mmu_iov, (FlatPtr)mmu_msg.msg_iov, sizeof(mmu_iov));
|
Vector<ByteBuffer, 1> buffers;
|
||||||
auto buffer = mmu().copy_buffer_from_vm((FlatPtr)mmu_iov.iov_base, mmu_iov.iov_len);
|
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;
|
ByteBuffer control_buffer;
|
||||||
if (mmu_msg.msg_control)
|
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);
|
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, iovs.data(), (int)iovs.size(), 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, &iov, 1, mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
|
|
||||||
return sendmsg(sockfd, &msg, flags);
|
return sendmsg(sockfd, &msg, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue