* @brief Sends a message from a socket using scatter-gather I/O. * * This system call sends data from multiple buffers specified in the `msghdr` structure. It is particularly * useful for advanced socket operations requiring ancillary data or scatter-gather I/O. * * @param[in] socket The socket descriptor through which the data will be sent. The socket must be * valid a
| 5968 | * @see sys_send(), sys_sendto(), sys_recvmsg() |
| 5969 | */ |
| 5970 | sysret_t sys_sendmsg(int socket, const struct msghdr *msg, int flags) |
| 5971 | { |
| 5972 | int flgs, ret = -1; |
| 5973 | struct msghdr kmsg; |
| 5974 | #ifdef ARCH_MM_MMU |
| 5975 | void *msg_control; |
| 5976 | struct iovec *uiov, *kiov; |
| 5977 | #endif |
| 5978 | if (!msg) |
| 5979 | { |
| 5980 | return -EPERM; |
| 5981 | } |
| 5982 | |
| 5983 | flgs = netflags_muslc_2_lwip(flags); |
| 5984 | |
| 5985 | #ifdef ARCH_MM_MMU |
| 5986 | ret = copy_msghdr_from_user(&kmsg, (struct msghdr *)msg, &uiov, &msg_control); |
| 5987 | |
| 5988 | if (!ret) |
| 5989 | { |
| 5990 | kiov = kmsg.msg_iov; |
| 5991 | |
| 5992 | for (int i = 0; i < kmsg.msg_iovlen; ++i) |
| 5993 | { |
| 5994 | lwp_get_from_user(kiov->iov_base, uiov->iov_base, kiov->iov_len); |
| 5995 | |
| 5996 | ++kiov; |
| 5997 | ++uiov; |
| 5998 | } |
| 5999 | |
| 6000 | lwp_get_from_user(kmsg.msg_control, msg_control, kmsg.msg_controllen); |
| 6001 | |
| 6002 | ret = sendmsg(socket, &kmsg, flgs); |
| 6003 | |
| 6004 | kmem_put(kmsg.msg_iov->iov_base); |
| 6005 | kmem_put(kmsg.msg_iov); |
| 6006 | } |
| 6007 | #else |
| 6008 | rt_memcpy(&kmsg, msg, sizeof(kmsg)); |
| 6009 | |
| 6010 | ret = sendmsg(socket, &kmsg, flgs); |
| 6011 | |
| 6012 | if (!ret) |
| 6013 | { |
| 6014 | msg->msg_flags = kmsg.msg_flags; |
| 6015 | } |
| 6016 | #endif /* ARCH_MM_MMU */ |
| 6017 | |
| 6018 | return (ret < 0 ? GET_ERRNO() : ret); |
| 6019 | } |
| 6020 | |
| 6021 | /** |
| 6022 | * @brief Sends data to a specific address using a socket. |
nothing calls this directly
no test coverage detected