qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] linux-user: Implement sendmmsg syscall


From: Alexander Graf
Subject: [Qemu-devel] [PATCH] linux-user: Implement sendmmsg syscall
Date: Thu, 5 Sep 2013 15:37:22 +0200

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 (!(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));
+        arg2 += sizeof(struct target_mmsghdr);
+    }
+
+    unlock_user(mmsgp, target_msgvec, 0);
+    /* XXX need to handle nonblocking case too */
+    return vlen;
+}
+#endif
+
 /* If we don't have a system accept4() then just call accept.
  * The callsites to do_accept4() will ensure that they don't
  * pass a non-zero flags argument in this config.
@@ -6973,6 +6997,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_ulong 
arg1,
         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
         break;
 #endif
+#ifdef TARGET_NR_sendmmsg
+    case TARGET_NR_sendmmsg:
+        ret = do_sendmmsg(arg1, arg2, arg3, arg4);
+        break;
+#endif
 #ifdef TARGET_NR_sendto
     case TARGET_NR_sendto:
         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index e51ef31..37645de 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -222,6 +222,10 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct 
target_cmsghdr *__cms
   return __cmsg;
 }
 
+struct target_mmsghdr {
+    struct target_msghdr msg_hdr;              /* Message header */
+    unsigned int         msg_len;              /* Number of bytes transmitted 
*/
+};
 
 struct  target_rusage {
         struct target_timeval ru_utime;        /* user time used */
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]