| 837 | } |
| 838 | |
| 839 | U32 KUnixSocketObject::recvmsg(KThread* thread, const KFileDescriptorPtr& fd, U32 address, U32 flags) { |
| 840 | MsgHdr hdr = {}; |
| 841 | U32 result = 0; |
| 842 | KMemory* memory = thread->memory; |
| 843 | |
| 844 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(this->lockCond); |
| 845 | while (!this->msgs.size()) { |
| 846 | if (this->recvBuffer.size_used()) { |
| 847 | readMsgHdr(thread, address, &hdr); |
| 848 | for (U32 i = 0; i < hdr.msg_iovlen; i++) { |
| 849 | U32 p = memory->readd(hdr.msg_iov + 8 * i); |
| 850 | U32 len = memory->readd(hdr.msg_iov + 8 * i + 4); |
| 851 | |
| 852 | U32 count = std::min(len, (U32)this->recvBuffer.size_used()); |
| 853 | memory->performOnMemory(p, count, false, [this](U8* ram, U32 len) { |
| 854 | this->recvBuffer.get(ram, len); |
| 855 | return true; |
| 856 | }); |
| 857 | result += count; |
| 858 | } |
| 859 | if (this->type==K_SOCK_STREAM) |
| 860 | memory->writed(address + 4, 0); // msg_namelen, set to 0 for connected sockets |
| 861 | memory->writed(address + 20, 0); // msg_controllen |
| 862 | return result; |
| 863 | } |
| 864 | if (this->inClosed) { |
| 865 | return 0; |
| 866 | } |
| 867 | if (!this->blocking) { |
| 868 | return -K_EWOULDBLOCK; |
| 869 | } |
| 870 | // :TODO: what about a time out |
| 871 | BOXEDWINE_CONDITION_WAIT(this->lockCond); |
| 872 | #ifdef BOXEDWINE_MULTI_THREADED |
| 873 | if (thread->terminating) { |
| 874 | return -K_EINTR; |
| 875 | } |
| 876 | if (thread->startSignal) { |
| 877 | thread->startSignal = false; |
| 878 | return -K_CONTINUE; |
| 879 | } |
| 880 | #endif |
| 881 | } |
| 882 | |
| 883 | readMsgHdr(thread, address, &hdr); |
| 884 | std::shared_ptr<KSocketMsg> msg = this->msgs.front(); |
| 885 | this->msgs.pop(); |
| 886 | |
| 887 | if (hdr.msg_control) { |
| 888 | U32 i=0; |
| 889 | |
| 890 | for (;i<hdr.msg_controllen/16 && i<msg->objects.size();i++) { |
| 891 | KFileDescriptorPtr recvFd = thread->process->allocFileDescriptor(msg->objects[i].object, msg->objects[i].accessFlags, 0, -1, 0); |
| 892 | writeCMsgHdr(thread, hdr.msg_control + i * 16, 16, K_SOL_SOCKET, K_SCM_RIGHTS); |
| 893 | memory->writed(hdr.msg_control + i * 16 + 12, recvFd->handle); |
| 894 | } |
| 895 | memory->writed(address + 20, i * 20); |
| 896 | } |
nothing calls this directly
no test coverage detected