@@ -3217,10 +3217,11 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec_addr,
unsigned int vlen, unsigned int flags,
- int send)
+ abi_long timeout, int send)
{
struct mmsghdr *host_msgvec;
struct target_mmsghdr *target_msgvec;
+ struct timespec ts;
abi_long ret = 0;
int num_sentrecv = 0;
int num_iovec = 0;
@@ -3275,7 +3276,14 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec_addr,
if (send) {
ret = get_errno(safe_sendmmsg(fd, host_msgvec, i, flags));
} else {
- ret = get_errno(safe_recvmmsg(fd, host_msgvec, i, flags, NULL));
+ if (timeout) {
+ if (target_to_host_timespec(&ts, timeout)) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(safe_recvmmsg(fd, host_msgvec, i, flags, &ts));
+ } else {
+ ret = get_errno(safe_recvmmsg(fd, host_msgvec, i, flags, NULL));
+ }
}
}
@@ -3611,10 +3619,10 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
return do_sendrecvmsg(a[0], a[1], a[2], 0);
case TARGET_SYS_ACCEPT4: /* sockfd, addr, addrlen, flags */
return do_accept4(a[0], a[1], a[2], a[3]);
- case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, flags */
- return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
+ case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, timeout, flags */
+ return do_sendrecvmmsg(a[0], a[1], a[2], a[3], a[4], 0);
case TARGET_SYS_SENDMMSG: /* sockfd, msgvec, vlen, flags */
- return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
+ return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0, 1);
default:
qemu_log_mask(LOG_UNIMP, "Unsupported socketcall: %d\n", num);
return -TARGET_EINVAL;
@@ -9418,11 +9426,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_sendmmsg
case TARGET_NR_sendmmsg:
- return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
+ return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0, 1);
#endif
#ifdef TARGET_NR_recvmmsg
case TARGET_NR_recvmmsg:
- return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
+ return do_sendrecvmmsg(arg1, arg2, arg3, arg4, arg5, 0);
#endif
#ifdef TARGET_NR_sendto
case TARGET_NR_sendto:
Syscall 'recvmmsg()' takes an argument which is of type 'struct timespec' that represents a timeout for the receive operation. Before changes from this patch, the timeout argument was ignored. This was probably due to the way 'recvmmsg()' was implemented with looping over 'recvmsg()' which doesn't have the timeout argument. This was changed with the previous patch in this series and which is why the timeout argument should be added accordingly. Implementation notes: Function 'do_sendrecvmmsg()' was changed with the addition of a new argument which represents the timeout. This argument is only passed in case of 'TARGET_NR_recvmmsg' and for 'TARGENT_NR_sendmmsg' 0 is passed. Function 'do_sendrecvmmsg()' was also updated accordingly in 'do_socketcall()' for 'TARGET_SYS_recvmmsg' and 'TARGET_SYS_sendmmsg'. Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> --- linux-user/syscall.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)