[vlc-devel] [PATCH v2 15/18] compat: Add custom implementation of recvmsg/sendmsg on NaCl

Dennis Hamester dhamester at jusst.de
Mon Mar 13 12:37:01 CET 2017


From: Dennis Hamester <dennis.hamester at startmail.com>

On Pepper 49, recvmsg and sendmsg are implemented as stubs, which always
return ENOTSUP. Proper implementations for these functions will become
available in later Pepper versions, which should make these compat
functions obsolete.
---
 compat/recvmsg.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 compat/sendmsg.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 configure.ac     |  2 ++
 3 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/compat/recvmsg.c b/compat/recvmsg.c
index 941249fef7..40ec935fc6 100644
--- a/compat/recvmsg.c
+++ b/compat/recvmsg.c
@@ -1,7 +1,10 @@
 /*****************************************************************************
  * recvmsg.c: POSIX recvmsg() replacement
  *****************************************************************************
- * Copyright © 2016 Rémi Denis-Courmont
+ * Copyright © 2016-2017 VLC authors and VideoLAN
+ *
+ * Authors: Rémi Denis-Courmont
+ *          Dennis Hamester <dhamester at jusst.de>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -79,3 +82,49 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
     return -1;
 }
 #endif
+
+#ifdef __native_client__
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+
+ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
+{
+    if (msg->msg_controllen != 0)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    if (msg->msg_iovlen > IOV_MAX)
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    size_t full_size = 0;
+    for (int i = 0; i < msg->msg_iovlen; ++i)
+        full_size += msg->msg_iov[i].iov_len;
+
+    char *data = malloc(full_size);
+    if (!data)
+        return -1;
+
+    ssize_t res;
+    if (msg->msg_name)
+        res = recvfrom(fd, data, full_size, flags, msg->msg_name, &msg->msg_namelen);
+    else
+        res = recv(fd, data, full_size, flags);
+
+    size_t tmp = 0;
+    for (int i = 0; i < msg->msg_iovlen; ++i) {
+        memcpy(msg->msg_iov[i].iov_base, data + tmp, msg->msg_iov[i].iov_len);
+        tmp += msg->msg_iov[i].iov_len;
+    }
+
+    msg->msg_flags = 0;
+    free(data);
+    return res;
+}
+#endif
diff --git a/compat/sendmsg.c b/compat/sendmsg.c
index 451ba298bf..5bbe8c413b 100644
--- a/compat/sendmsg.c
+++ b/compat/sendmsg.c
@@ -1,7 +1,10 @@
 /*****************************************************************************
  * sendmsg.c: POSIX sendmsg() replacement
  *****************************************************************************
- * Copyright © 2016 Rémi Denis-Courmont
+ * Copyright © 2016-2017 VLC authors and VideoLAN
+ *
+ * Authors: Rémi Denis-Courmont
+ *          Dennis Hamester <dhamester at jusst.de>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -69,3 +72,48 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
     return -1;
 }
 #endif
+
+#ifdef __native_client__
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+
+ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+    if (msg->msg_controllen != 0)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    if (msg->msg_iovlen > IOV_MAX)
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    size_t full_size = 0;
+    for (int i = 0; i < msg->msg_iovlen; ++i)
+        full_size += msg->msg_iov[i].iov_len;
+
+    char *data = malloc(full_size);
+    if (!data)
+        return -1;
+
+    size_t tmp = 0;
+    for (int i = 0; i < msg->msg_iovlen; ++i) {
+        memcpy(data + tmp, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
+        tmp += msg->msg_iov[i].iov_len;
+    }
+
+    ssize_t res;
+    if (msg->msg_name)
+        res = sendto(fd, data, full_size, flags, msg->msg_name, msg->msg_namelen);
+    else
+        res = send(fd, data, full_size, flags);
+
+    free(data);
+    return res;
+}
+#endif
diff --git a/configure.ac b/configure.ac
index c9713970fd..787421810e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -300,6 +300,8 @@ case "${host_os}" in
   *nacl*)
     SYS=nacl
     AC_DEFINE([_XOPEN_SOURCE], [700], [POSIX and XPG 7th edition])
+    AC_LIBOBJ([recvmsg])
+    AC_LIBOBJ([sendmsg])
     ;;
   *)
     SYS="${host_os}"
-- 
2.12.0



More information about the vlc-devel mailing list