[vlc-commits] input: add vlc_io_{send, recv, sendto, recvfrom, sendmsg, recvmsg} helpers

Rémi Denis-Courmont git at videolan.org
Wed Jul 1 18:22:11 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jun 30 23:52:51 2015 +0300| [e72c9ec91e313c69759c6d99586f194ce276bdef] | committer: Rémi Denis-Courmont

input: add vlc_io_{send,recv,sendto,recvfrom,sendmsg,recvmsg} helpers

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e72c9ec91e313c69759c6d99586f194ce276bdef
---

 include/vlc_interrupt.h |   26 ++++++++++++
 src/libvlccore.sym      |    4 ++
 src/misc/interrupt.c    |  106 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 136 insertions(+)

diff --git a/include/vlc_interrupt.h b/include/vlc_interrupt.h
index 99f11df..4e3ed26 100644
--- a/include/vlc_interrupt.h
+++ b/include/vlc_interrupt.h
@@ -26,9 +26,16 @@
 #ifndef VLC_INTERRUPT_H
 # define VLC_INTERRUPT_H 1
 # include <vlc_threads.h>
+# ifndef _WIN32
+#  include <sys/socket.h> /* socklen_t */
+# else
+#  include <ws2tcpip.h>
+# endif
 
 struct pollfd;
 struct iovec;
+struct sockaddr;
+struct msghdr;
 
 /**
  * @defgroup interrupt Interruptible sleep
@@ -77,6 +84,25 @@ VLC_API ssize_t vlc_writev_i11e(int fd, const struct iovec *, int);
 VLC_API ssize_t vlc_read_i11e(int fd, void *, size_t);
 VLC_API ssize_t vlc_write_i11e(int fd, const void *, size_t);
 
+VLC_API ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *, int flags);
+VLC_API ssize_t vlc_sendmsg_i11e(int fd, const struct msghdr *, int flags);
+
+VLC_API ssize_t vlc_recvfrom_i11e(int fd, void *, size_t, int flags,
+                                struct sockaddr *, socklen_t *);
+VLC_API ssize_t vlc_sendto_i11e(int fd, const void *, size_t, int flags,
+                              const struct sockaddr *, socklen_t);
+
+static inline ssize_t vlc_recv_i11e(int fd, void *buf, size_t len, int flags)
+{
+    return vlc_recvfrom_i11e(fd, buf, len, flags, NULL, NULL);
+}
+
+static inline
+ssize_t vlc_send_i11e(int fd, const void *buf, size_t len, int flags)
+{
+    return vlc_sendto_i11e(fd, buf, len, flags, NULL, 0);
+}
+
 /**
  * @}
  * @defgroup interrupt_context Interrupt context signaling and manipulation
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 0a9cac2..a0a794c 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -544,6 +544,10 @@ vlc_read_i11e
 vlc_readv_i11e
 vlc_write_i11e
 vlc_writev_i11e
+vlc_recvmsg_i11e
+vlc_recvfrom_i11e
+vlc_sendmsg_i11e
+vlc_sendto_i11e
 vlc_sem_wait_i11e
 vlc_interrupt_create
 vlc_interrupt_destroy
diff --git a/src/misc/interrupt.c b/src/misc/interrupt.c
index 5017a36..a202740 100644
--- a/src/misc/interrupt.c
+++ b/src/misc/interrupt.c
@@ -362,6 +362,8 @@ int vlc_poll_i11e(struct pollfd *fds, unsigned nfds, int timeout)
 
 # include <fcntl.h>
 # include <sys/uio.h>
+# include <sys/socket.h>
+
 
 /* There are currently no ways to atomically force a non-blocking read or write
  * operations. Even for sockets, the MSG_DONTWAIT flag is non-standard.
@@ -429,6 +431,64 @@ ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
     return writev(fd, &iov, 1);
 }
 
+ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *msg, int flags)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLIN;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+    /* NOTE: MSG_OOB and MSG_PEEK should work fine here.
+     * MSG_WAITALL is not supported at this point. */
+    return recvmsg(fd, msg, flags);
+}
+
+ssize_t vlc_recvfrom_i11e(int fd, void *buf, size_t len, int flags,
+                        struct sockaddr *addr, socklen_t *addrlen)
+{
+    struct iovec iov = { .iov_base = buf, .iov_len = len };
+    struct msghdr msg = {
+        .msg_name = addr,
+        .msg_namelen = (addrlen != NULL) ? *addrlen : 0,
+        .msg_iov = &iov,
+        .msg_iovlen = 1,
+    };
+
+    ssize_t ret = vlc_recvmsg_i11e(fd, &msg, flags);
+    if (ret >= 0 && addrlen != NULL)
+        *addrlen = msg.msg_namelen;
+    return ret;
+}
+
+ssize_t vlc_sendmsg_i11e(int fd, const struct msghdr *msg, int flags)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLOUT;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+    /* NOTE: MSG_EOR, MSG_OOB and MSG_NOSIGNAL should all work fine here. */
+    return sendmsg(fd, msg, flags);
+}
+
+ssize_t vlc_sendto_i11e(int fd, const void *buf, size_t len, int flags,
+                      const struct sockaddr *addr, socklen_t addrlen)
+{
+    struct iovec iov = { .iov_base = (void *)buf, .iov_len = len };
+    struct msghdr msg = {
+        .msg_name = (struct sockaddr *)addr,
+        .msg_namelen = addrlen,
+        .msg_iov = &iov,
+        .msg_iovlen = 1,
+    };
+
+    return vlc_sendmsg_i11e(fd, &msg, flags);
+}
+
 #else /* _WIN32 */
 
 static void CALLBACK vlc_poll_i11e_wake_self(ULONG_PTR data)
@@ -514,4 +574,50 @@ ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
     return write(fd, buf, count);
 }
 
+ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *msg, int flags)
+{
+    (void) fd; (void) msg; (void) flags;
+    vlc_assert_unreachable();
+}
+
+ssize_t vlc_recvfrom_i11e(int fd, void *buf, size_t len, int flags,
+                        struct sockaddr *addr, socklen_t *addrlen)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLIN;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+
+    ssize_t ret = recvfrom(fd, buf, len, flags, addr, addrlen);
+    if (ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
+        errno = EAGAIN;
+    return ret;
+}
+
+ssize_t vlc_sendmsg_i11e(int fd, const struct msghdr *msg, int flags)
+{
+    (void) fd; (void) msg; (void) flags;
+    vlc_assert_unreachable();
+}
+
+ssize_t vlc_sendto_i11e(int fd, const void *buf, size_t len, int flags,
+                      const struct sockaddr *addr, socklen_t addrlen)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLOUT;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+
+    ssize_t ret = sendto(fd, buf, len, flags, addr, addrlen);
+    if (ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
+        errno = EAGAIN;
+    return ret;
+}
+
 #endif



More information about the vlc-commits mailing list