[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] linux-user: Implement sendmmsg syscall
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH] linux-user: Implement sendmmsg syscall |
Date: |
Thu, 5 Sep 2013 15:31:15 +0100 |
On 5 September 2013 14:37, Alexander Graf <address@hidden> wrote:
> Glibc when built for newer kernels assumes that the sendmmsg syscall is
> available.
> Without it, dns resolution simply fails to work.
>
> Wrap the syscall with existing infrastructure so that we don't have a host
> dependency
> on sendmmsg.
>
> Signed-off-by: Alexander Graf <address@hidden>
> ---
> linux-user/syscall.c | 29 +++++++++++++++++++++++++++++
> linux-user/syscall_defs.h | 4 ++++
> 2 files changed, 33 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0272990..59cfdf4 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1863,6 +1863,30 @@ out2:
> return ret;
> }
>
> +#ifdef TARGET_NR_sendmmsg
> +static abi_long do_sendmmsg(int fd, abi_ulong target_msgvec,
> + unsigned int vlen, unsigned int flags)
> +{
> + struct target_mmsghdr *mmsgp;
> + abi_ulong arg2 = target_msgvec;
> + int i;
If we're doing this in terms of sendmsg, we need to
implement the kernel's "if CMSG_COMPAT fail EINVAL"
logic ourselves. Compare
http://lxr.linux.no/#linux+v3.11/net/socket.c#L2175
> +
> + if (!(mmsgp = lock_user(VERIFY_WRITE, target_msgvec,
> + sizeof(*mmsgp) * vlen, 1))) {
> + return -TARGET_EFAULT;
> + }
> +
> + for (i = 0; i < vlen; i++) {
> + mmsgp[i].msg_len = tswap32(do_sendrecvmsg(fd, arg2, flags, 1));
If do_sendrecvmsg reports an errno we should stop
processing the array and return it, not just
stuff it into msg_len. Compare:
http://lxr.linux.no/#linux+v3.11/net/socket.c#L2155
> + arg2 += sizeof(struct target_mmsghdr);
> + }
> +
> + unlock_user(mmsgp, target_msgvec, 0);
> + /* XXX need to handle nonblocking case too */
> + return vlen;
> +}
> +#endif
thanks
-- PMM