| 1481 | } |
| 1482 | |
| 1483 | U32 KNativeSocketObject::recvmsg(KThread* thread, const KFileDescriptorPtr& fd, U32 address, U32 flags) { |
| 1484 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(readingCond); |
| 1485 | KMemory* memory = thread->memory; |
| 1486 | char tmp[K_PAGE_SIZE] = { 0 }; |
| 1487 | MsgHdr hdr = { 0 }; |
| 1488 | U32 result = 0; |
| 1489 | U32 nativeFlags = 0; |
| 1490 | if (flags) { |
| 1491 | if (flags & K_MSG_PEEK) { |
| 1492 | nativeFlags |= MSG_PEEK; |
| 1493 | flags &= ~K_MSG_PEEK; |
| 1494 | } |
| 1495 | if (flags) { |
| 1496 | kwarn_fmt("KNativeSocketObject::recvmsg unhandled flag %x", flags); |
| 1497 | } |
| 1498 | } |
| 1499 | readMsgHdr(thread, address, &hdr); |
| 1500 | |
| 1501 | for (U32 i = 0; i < hdr.msg_iovlen; i++) { |
| 1502 | U32 p = memory->readd(hdr.msg_iov + 8 * i); |
| 1503 | U32 len = memory->readd(hdr.msg_iov + 8 * i + 4); |
| 1504 | |
| 1505 | struct sockaddr_in in = {0}; |
| 1506 | socklen_t inLen = sizeof(struct sockaddr_in); |
| 1507 | |
| 1508 | if (len>sizeof(tmp)) |
| 1509 | len = sizeof(tmp); |
| 1510 | S32 r = (S32)::recvfrom(this->nativeSocket, tmp, len, nativeFlags, hdr.msg_name?(struct sockaddr*)&in:nullptr, hdr.msg_name ? &inLen : nullptr); |
| 1511 | LOG_SOCK("%x native socket: %x recvmsg flags=%x msg_name=%x msg_namelen=%x result=%x", thread->id, nativeSocket, flags, hdr.msg_name, hdr.msg_namelen, r); |
| 1512 | //if (r < 0) { |
| 1513 | // Platform::nanoSleep(10000000); |
| 1514 | // r = (S32)::recvfrom(this->nativeSocket, tmp, len, nativeFlags, hdr.msg_name ? (struct sockaddr*)&in : nullptr, hdr.msg_name ? &inLen : nullptr); |
| 1515 | //} |
| 1516 | if (r>=0) { |
| 1517 | memory->memcpy(p, tmp, r); |
| 1518 | // :TODO: maybe copied fields to the expected location rather than assume the structures are the same |
| 1519 | if (hdr.msg_name && hdr.msg_namelen >= 16) { |
| 1520 | writeSockAddrIn(&in, memory, hdr.msg_name); |
| 1521 | } |
| 1522 | memory->writed(address + 4, inLen); |
| 1523 | result+=r; |
| 1524 | this->error = 0; |
| 1525 | } |
| 1526 | else if (result) { |
| 1527 | break; |
| 1528 | } else { |
| 1529 | std::shared_ptr< KNativeSocketObject> t = std::dynamic_pointer_cast<KNativeSocketObject>(shared_from_this()); |
| 1530 | result = handleNativeSocketError(t, false); |
| 1531 | } |
| 1532 | } |
| 1533 | if (this->type==K_SOCK_STREAM) |
| 1534 | memory->writed(address + 4, 0); // msg_namelen, set to 0 for connected sockets |
| 1535 | memory->writed(address + 20, 0); // msg_controllen |
| 1536 | return result; |
| 1537 | } |
| 1538 | |
| 1539 | U32 KNativeSocketObject::sendto(KThread* thread, const KFileDescriptorPtr& fd, U32 message, U32 length, U32 flags, U32 dest_addr, U32 dest_len) { |
| 1540 | KMemory* memory = thread->memory; |
nothing calls this directly
no test coverage detected