| 1570 | } |
| 1571 | |
| 1572 | U32 KNativeSocketObject::recvfrom(KThread* thread, const KFileDescriptorPtr& fd, U32 buffer, U32 length, U32 flags, U32 address, U32 address_len) { |
| 1573 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(readingCond); |
| 1574 | U32 nativeFlags = 0; |
| 1575 | KMemory* memory = thread->memory; |
| 1576 | |
| 1577 | if (length && !thread->memory->canWrite(buffer, length)) { |
| 1578 | return -K_EFAULT; |
| 1579 | } |
| 1580 | if (flags & K_MSG_OOB) |
| 1581 | nativeFlags|=MSG_OOB; |
| 1582 | if (flags & K_MSG_PEEK) |
| 1583 | nativeFlags|=MSG_PEEK; |
| 1584 | if (flags & (~3)) { |
| 1585 | kwarn_fmt("krecvfrom unsupported flags: %d", flags); |
| 1586 | } |
| 1587 | int inLen=0; |
| 1588 | socklen_t outLen=0; |
| 1589 | struct sockaddr_in addr = {0}; |
| 1590 | |
| 1591 | if (address_len) { |
| 1592 | inLen = sizeof(struct sockaddr_in); |
| 1593 | readSockAddrIn(&addr, memory, address); |
| 1594 | } |
| 1595 | char* tmp = nullptr; |
| 1596 | |
| 1597 | if (length) { |
| 1598 | tmp = new char[length]; |
| 1599 | } |
| 1600 | outLen = inLen; |
| 1601 | U32 result = (U32)::recvfrom(this->nativeSocket, tmp, length, nativeFlags, address_len?(struct sockaddr*)&addr:nullptr, address_len?&outLen: nullptr); |
| 1602 | LOG_SOCK("%x native socket: %x recvfrom buffer=%x length=%d address=%x address_len=%x flags=%x result=%x", thread->id, nativeSocket, buffer, length, address, address_len, flags, result); |
| 1603 | if ((S32)result>=0) { |
| 1604 | memory->memcpy(buffer, tmp, result); |
| 1605 | if (address) { |
| 1606 | writeSockAddrIn(&addr, memory, address); |
| 1607 | } |
| 1608 | if (address_len) { |
| 1609 | memory->writed(address_len, 16); |
| 1610 | } |
| 1611 | this->error = 0; |
| 1612 | } else { |
| 1613 | std::shared_ptr< KNativeSocketObject> t = std::dynamic_pointer_cast<KNativeSocketObject>(shared_from_this()); |
| 1614 | result = handleNativeSocketError(t, false); |
| 1615 | if ((S32)result == -K_EMSGSIZE) { |
| 1616 | if (length && buffer) { |
| 1617 | memory->memcpy(buffer, tmp, length); |
| 1618 | } |
| 1619 | if (address) { |
| 1620 | writeSockAddrIn(&addr, memory, address); |
| 1621 | } |
| 1622 | if (address_len) { |
| 1623 | memory->writed(address_len, 16); |
| 1624 | } |
| 1625 | } |
| 1626 | } |
| 1627 | if (tmp) { |
| 1628 | delete[] tmp; |
| 1629 | } |
nothing calls this directly
no test coverage detected