]> git.sesse.net Git - vlc/blobdiff - src/network/io.c
macosx: Fix controller playlist toggling to use the contentRect and not the window...
[vlc] / src / network / io.c
index c8b955c29ecd812ec268c3a7cb3fb95190730beb..0491c3992bdcbc34561684257a3083b019928793 100644 (file)
@@ -32,7 +32,7 @@
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 # define EAFNOSUPPORT WSAEAFNOSUPPORT
 #endif
 
+#ifdef HAVE_LINUX_DCCP_H
+/* TODO: use glibc instead of linux-kernel headers */
+# include <linux/dccp.h>
+# define SOL_DCCP 269
+#endif
+
 extern int rootwrap_bind (int family, int socktype, int protocol,
                           const struct sockaddr *addr, size_t alen);
 
@@ -118,6 +124,19 @@ int net_Socket (vlc_object_t *p_this, int family, int socktype,
                     &(int){ PROTECTION_LEVEL_UNRESTRICTED }, sizeof (int));
 #endif
 
+#ifdef DCCP_SOCKOPT_SERVICE
+    if (socktype == SOL_DCCP)
+    {
+        char *dccps = var_CreateGetNonEmptyString (p_this, "dccp-service");
+        if (dccps != NULL)
+        {
+            setsockopt (fd, SOL_DCCP, DCCP_SOCKOPT_SERVICE, dccps,
+                        (strlen (dccps) + 3) & ~3);
+            free (dccps);
+        }
+    }
+#endif
+
     return fd;
 }
 
@@ -267,7 +286,7 @@ int *net_Listen (vlc_object_t *p_this, const char *psz_host,
  *****************************************************************************/
 ssize_t
 __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
-            uint8_t *restrict p_buf, size_t i_buflen, vlc_bool_t waitall)
+            uint8_t *restrict p_buf, size_t i_buflen, bool waitall)
 {
     size_t i_total = 0;
     struct pollfd ufd[2] = {
@@ -284,7 +303,7 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
 
         if (poll (ufd, sizeof (ufd) / sizeof (ufd[0]), -1) < 0)
         {
-            if (errno =! EINTR)
+            if (errno != EINTR)
                 goto error;
             continue;
         }
@@ -306,13 +325,14 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
         {
             if (ufd[1].revents)
             {
+                assert (p_this->b_die);
                 msg_Dbg (p_this, "socket %d polling interrupted", fd);
 #if defined(WIN32) || defined(UNDER_CE)
                 WSASetLastError (WSAEINTR);
 #else
                 errno = EINTR;
 #endif
-                goto error;
+                goto silent;
             }
         }
 
@@ -350,16 +370,16 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
                                      "Increase the mtu size (--mtu option)");
                     n = i_buflen;
                     break;
-
-                default:
-                    goto error;
             }
 #else
-            /* spurious wake-up or TLS did not yield any actual data */
-            if (errno == EAGAIN)
-                continue;
-            goto error;
+            switch (errno)
+            {
+                case EAGAIN: /* spurious wakeup or no TLS data */
+                case EINTR:  /* asynchronous signal */
+                    continue;
+            }
 #endif
+            goto error;
         }
 
         if (n == 0)
@@ -383,6 +403,7 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
 
 error:
     msg_Err (p_this, "Read error: %m");
+silent:
     return -1;
 }
 
@@ -408,22 +429,30 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
 
         if (poll (ufd, 1, -1) == -1)
         {
-            if (errno != EINTR)
-            {
-                msg_Err (p_this, "Write error: %m");
-                goto out;
-            }
-            continue;
+            if (errno == EINTR)
+                continue;
+            msg_Err (p_this, "Polling error: %m");
+            return -1;
         }
 
         if (i_total > 0)
-        {
-            /* Errors will be dequeued separately, upon next call. */
-            if (ufd[0].revents & (POLLERR|POLLNVAL|POLLHUP))
+        {   /* If POLLHUP resp. POLLERR|POLLNVAL occurs while we have already
+             * read some data, it is important that we first return the number
+             * of bytes read, and then return 0 resp. -1 on the NEXT call. */
+            if (ufd[0].revents & (POLLHUP|POLLERR|POLLNVAL))
                 break;
-            if (ufd[1].revents)
+            if (ufd[1].revents) /* VLC object signaled */
                 break;
         }
+        else
+        {
+            if (ufd[1].revents)
+            {
+                assert (p_this->b_die);
+                errno = EINTR;
+                goto error;
+            }
+        }
 
         if (p_vs != NULL)
             val = p_vs->pf_send (p_vs->p_sys, p_data, i_data);
@@ -436,6 +465,8 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
 
         if (val == -1)
         {
+            if (errno == EINTR)
+                continue;
             msg_Err (p_this, "Write error: %m");
             break;
         }
@@ -445,10 +476,10 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
         i_total += val;
     }
 
-out:
     if ((i_total > 0) || (i_data == 0))
         return i_total;
 
+error:
     return -1;
 }
 
@@ -467,7 +498,7 @@ char *__net_Gets( vlc_object_t *p_this, int fd, const v_socket_t *p_vs )
             ptr = psz_line + i_line;
         }
 
-        if( net_Read( p_this, fd, p_vs, (uint8_t *)ptr, 1, VLC_TRUE ) != 1 )
+        if( net_Read( p_this, fd, p_vs, (uint8_t *)ptr, 1, true ) != 1 )
         {
             if( i_line == 0 )
             {
@@ -522,9 +553,9 @@ ssize_t __net_vaPrintf( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
 /*****************************************************************************
  * inet_pton replacement for obsolete and/or crap operating systems
  *****************************************************************************/
-#ifndef HAVE_INET_PTON
-int inet_pton(int af, const char *src, void *dst)
+int vlc_inet_pton(int af, const char *src, void *dst)
 {
+#ifndef HAVE_INET_PTON
 # ifdef WIN32
     /* As we already know, Microsoft always go its own way, so even if they do
      * provide IPv6, they don't provide the API. */
@@ -541,7 +572,7 @@ int inet_pton(int af, const char *src, void *dst)
     char *workaround_for_ill_designed_api = strdup( src );
 #endif
 
-    if( !WSAStringToAddress( workaround_for_ill_designed_api, af, NULL,
+    if( WSAStringToAddress( workaround_for_ill_designed_api, af, NULL,
                              (LPSOCKADDR)&addr, &len ) )
     {
         free( workaround_for_ill_designed_api );
@@ -582,14 +613,16 @@ int inet_pton(int af, const char *src, void *dst)
     memcpy( dst, &ipv4, 4 );
 # endif /* WIN32 */
     return 0;
-}
+#else /* HAVE_INET_PTON */
+    return inet_pton( af, src, dst );
 #endif /* HAVE_INET_PTON */
+}
 
-#ifndef HAVE_INET_NTOP
-#ifdef WIN32
-const char *inet_ntop(int af, const void * src,
+const char *vlc_inet_ntop(int af, const void * src,
                                char * dst, socklen_t cnt)
 {
+#ifndef HAVE_INET_NTOP
+#ifdef WIN32
     switch( af )
     {
 #ifdef AF_INET6
@@ -632,6 +665,25 @@ const char *inet_ntop(int af, const void * src,
     }
     errno = EAFNOSUPPORT;
     return NULL;
+#else /* WIN32 */
+    return NULL;
+#endif /* WIN32 */
+#else /* HAVE_INET_NTOP */
+    return inet_ntop( af, src, dst, cnt );
+#endif /* HAVE_INET_NTOP */
 }
-#endif
-#endif
+
+#ifdef WIN32
+    /* vlc_sendmsg, vlc_recvmsg Defined in winsock.c */
+#else /* !WIN32 */
+ssize_t vlc_sendmsg (int s, struct msghdr *hdr, int flags)
+{
+    return sendmsg (s, hdr, flags);
+}
+
+ssize_t vlc_recvmsg (int s, struct msghdr *hdr, int flags)
+{
+    return recvmsg (s, hdr, flags);
+}
+#endif /* WIN32 */
+