* @brief Receives data from a socket, optionally capturing the source address. * * This system call is used to receive data from a socket. For connectionless sockets, it also * retrieves the address of the sender. It supports both blocking and non-blocking operations * depending on the socket configuration and the specified flags. * * @param[in] socket The socket descriptor from which the
| 5812 | * @see sys_sendto(), sys_recv() |
| 5813 | */ |
| 5814 | sysret_t sys_recvfrom(int socket, void *mem, size_t len, int flags, |
| 5815 | struct musl_sockaddr *from, socklen_t *fromlen) |
| 5816 | { |
| 5817 | int flgs = 0; |
| 5818 | #ifdef ARCH_MM_MMU |
| 5819 | int ret = -1; |
| 5820 | void *kmem = RT_NULL; |
| 5821 | #endif |
| 5822 | |
| 5823 | flgs = netflags_muslc_2_lwip(flags); |
| 5824 | #ifdef ARCH_MM_MMU |
| 5825 | if (!len) |
| 5826 | { |
| 5827 | return -EINVAL; |
| 5828 | } |
| 5829 | |
| 5830 | if (!lwp_user_accessable((void *)mem, len)) |
| 5831 | { |
| 5832 | return -EFAULT; |
| 5833 | } |
| 5834 | |
| 5835 | kmem = kmem_get(len); |
| 5836 | if (!kmem) |
| 5837 | { |
| 5838 | return -ENOMEM; |
| 5839 | } |
| 5840 | |
| 5841 | if (flags == 0x2) |
| 5842 | { |
| 5843 | flags = 0x1; |
| 5844 | } |
| 5845 | |
| 5846 | if (from) |
| 5847 | { |
| 5848 | struct sockaddr sa; |
| 5849 | |
| 5850 | ret = recvfrom(socket, kmem, len, flgs, &sa, fromlen); |
| 5851 | sockaddr_tomusl(&sa, from); |
| 5852 | } |
| 5853 | else |
| 5854 | { |
| 5855 | ret = recvfrom(socket, kmem, len, flgs, NULL, NULL); |
| 5856 | } |
| 5857 | |
| 5858 | if (ret > 0) |
| 5859 | { |
| 5860 | lwp_put_to_user(mem, kmem, len); |
| 5861 | } |
| 5862 | |
| 5863 | if (ret < 0) |
| 5864 | { |
| 5865 | ret = GET_ERRNO(); |
| 5866 | } |
| 5867 | |
| 5868 | kmem_put(kmem); |
| 5869 | |
| 5870 | return ret; |
| 5871 | #else |
nothing calls this directly
no test coverage detected