* SysSend (sockfd, msg, flags) - Send data through a socket * sockfd - Socket file descriptor * msg - Message Header * flags - flags * * On Success - return amount of data sent * On Failure - return -1 */
| 1634 | * On Failure - return -1 |
| 1635 | */ |
| 1636 | long SysSendMsg(regs64_t* r){ |
| 1637 | process_t* proc = Scheduler::GetCurrentProcess(); |
| 1638 | |
| 1639 | if(SC_ARG0(r) >= proc->fileDescriptors.get_length()){ |
| 1640 | Log::Warning("sys_sendmsg: Invalid File Descriptor: %d", SC_ARG0(r)); |
| 1641 | return -1; |
| 1642 | } |
| 1643 | |
| 1644 | fs_fd_t* handle = proc->fileDescriptors.get_at(SC_ARG0(r)); |
| 1645 | |
| 1646 | msghdr* msg = (msghdr*)SC_ARG1(r); |
| 1647 | uint64_t flags = SC_ARG3(r); |
| 1648 | |
| 1649 | if(!handle){ |
| 1650 | Log::Warning("sys_sendmsg: Invalid file descriptor: ", SC_ARG0(r)); |
| 1651 | return -1; |
| 1652 | } |
| 1653 | |
| 1654 | if((handle->node->flags & FS_NODE_TYPE) != FS_NODE_SOCKET){ |
| 1655 | Log::Warning("sys_sendmsg: File (Descriptor: %d) is not a socket", SC_ARG0(r)); |
| 1656 | return -2; |
| 1657 | } |
| 1658 | |
| 1659 | if(!Memory::CheckUsermodePointer(SC_ARG1(r), sizeof(msghdr), proc->addressSpace)){ |
| 1660 | Log::Warning("sys_sendmsg: Invalid msg ptr"); |
| 1661 | return -EFAULT; |
| 1662 | } |
| 1663 | |
| 1664 | if(!Memory::CheckUsermodePointer((uintptr_t)msg->iov, sizeof(iovec) * msg->iovlen, proc->addressSpace)){ |
| 1665 | Log::Warning("sys_sendmsg: msg: Invalid iovec ptr"); |
| 1666 | return -EFAULT; |
| 1667 | } |
| 1668 | |
| 1669 | if(msg->name && !Memory::CheckUsermodePointer((uintptr_t)msg->name, msg->namelen, proc->addressSpace)){ |
| 1670 | Log::Warning("sys_sendmsg: msg: Invalid name ptr and name not null"); |
| 1671 | return -EFAULT; |
| 1672 | } |
| 1673 | |
| 1674 | long sent = 0; |
| 1675 | Socket* sock = (Socket*)handle->node; |
| 1676 | |
| 1677 | for(unsigned i = 0; i < msg->iovlen; i++){ |
| 1678 | if(!Memory::CheckUsermodePointer((uintptr_t)msg->iov[i].base, msg->iov[i].len, proc->addressSpace)){ |
| 1679 | Log::Warning("sys_sendmsg: msg: Invalid iovec entry base"); |
| 1680 | return -EFAULT; |
| 1681 | } |
| 1682 | |
| 1683 | long ret = sock->SendTo(msg->iov[i].base, msg->iov[i].len, flags, (sockaddr*)msg->name, msg->namelen); |
| 1684 | |
| 1685 | if(ret < 0) return ret; |
| 1686 | |
| 1687 | sent += ret; |
| 1688 | } |
| 1689 | |
| 1690 | return sent; |
| 1691 | } |
| 1692 | |
| 1693 | /* |
nothing calls this directly
no test coverage detected