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

Julian Scheel julian at jusst.de
Wed Mar 8 15:55:32 CET 2017


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

NaCl's recvmsg and sendmsg always return ENOTSUP.
---
 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 b74cea42a0..45852d6da5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -301,6 +301,8 @@ case "${host_os}" in
     SYS=nacl
     AC_DEFINE([_XOPEN_SOURCE], [700], [POSIX and XPG 7th edition])
     VLC_ADD_LIBS([nacl],[-lppapi -lppapi_gles2])
+    AC_LIBOBJ([recvmsg])
+    AC_LIBOBJ([sendmsg])
     ;;
   *)
     SYS="${host_os}"
-- 
2.12.0



More information about the vlc-devel mailing list