gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r32395 - in libmicrohttpd: . src/include src/microhttpd src


From: gnunet
Subject: [GNUnet-SVN] r32395 - in libmicrohttpd: . src/include src/microhttpd src/platform
Date: Tue, 18 Feb 2014 19:38:41 +0100

Author: Karlson2k
Date: 2014-02-18 19:38:41 +0100 (Tue, 18 Feb 2014)
New Revision: 32395

Modified:
   libmicrohttpd/configure.ac
   libmicrohttpd/src/include/microhttpd.h
   libmicrohttpd/src/include/platform.h
   libmicrohttpd/src/microhttpd/daemon.c
   libmicrohttpd/src/microhttpd/internal.h
   libmicrohttpd/src/platform/platform_interface.h
   libmicrohttpd/src/platform/w32functions.c
   libmicrohttpd/src/platform/w32functions.h
Log:
add ability to use socketspair instead of pipe, implement W32 pipe/socketspair 
emulation, implement MHD_SYS_select_
configure.ac: add "--disable-pipes" option

Modified: libmicrohttpd/configure.ac
===================================================================
--- libmicrohttpd/configure.ac  2014-02-18 18:38:27 UTC (rev 32394)
+++ libmicrohttpd/configure.ac  2014-02-18 18:38:41 UTC (rev 32395)
@@ -167,6 +167,7 @@
      AM_CONDITIONAL(HAVE_GNU_LD, false)
      AM_CONDITIONAL(HAVE_W32, false)
      LDFLAGS="$LDFLAGS"
+     os_is_windows=yes
      ;;
 *mingw*)
      AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
@@ -180,6 +181,7 @@
      AC_SUBST(PLIBC_LIBS)
      AC_SUBST(PLIBC_LDFLAGS)
      AC_SUBST(PLIBC_CPPFLAGS)
+     os_is_windows=yes
      ;;
 *openedition*)
      AC_DEFINE_UNQUOTED(OS390,1,[This is a OS/390 system])
@@ -229,6 +231,37 @@
 
 AC_CHECK_HEADERS([search.h], AM_CONDITIONAL(HAVE_TSEARCH, true), 
AM_CONDITIONAL(HAVE_TSEARCH, false))
 
+# Check for pipe/socketpair signaling 
+AC_MSG_CHECKING([[whether to disable pipes signaling]])
+AC_ARG_ENABLE([[pipes]],
+       [AS_HELP_STRING([[--disable-pipes]], [[disable internal singalling by 
pipes and use socket pair instead]])],
+       [], [[enable_pipes=yes]])
+AS_IF([[test "x$os_is_windows" = "xyes"]], [disable_pipes=yes
+        AC_MSG_RESULT([[yes, forced on W32]])],
+       [[test "x$enable_pipes" != "xno"]], [disable_pipes=no
+        AC_MSG_RESULT([[$disable_pipes]])], 
+        [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+                               #ifdef HAVE_SYS_TYPES_H
+                               #include <sys/types.h>
+                               #endif
+                               #ifdef HAVE_SYS_SOCKET_H
+                               #include <sys/socket.h>
+                               #endif
+                               ]],[[
+                                 int sv[2];
+                                 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) 
!= 0) return 1
+                               
+                               ]])], 
+            [disable_pipes=yes
+              AC_MSG_RESULT([[yes, socketpair in available]])],
+            [disable_pipes=no
+              AC_MSG_RESULT([[no, socketpair in not available]])]
+          )
+       ])
+if test "x$disable_pipes" = "xyes"; then
+       AC_DEFINE([[MHD_DONT_USE_PIPES]], [[1]], [Define to use pair of sockets 
instead of pipes for signaling])
+fi
+
 # Check for plibc.h from system, if not found, use our own
 AC_CHECK_HEADERS([plibc.h],our_private_plibc_h=0,our_private_plibc_h=1)
 AM_CONDITIONAL(USE_PRIVATE_PLIBC_H, test x$our_private_plibc_h = x1)

Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h      2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/include/microhttpd.h      2014-02-18 18:38:41 UTC (rev 
32395)
@@ -520,7 +520,8 @@
    * use of this option is automatic (as in, you do not even have to
    * specify it), if #MHD_USE_NO_LISTEN_SOCKET is specified.  In
    * "external" `select()` mode, this option is always simply ignored.
-   * On W32 a pair of sockets is used instead of a pipe.
+   * MHD can be build for use a pair of sockets instead of a pipe.
+   * Pair of sockets is forced on W32.
    *
    * You must also use this option if you use internal select mode
    * or a thread pool in conjunction with #MHD_add_connection.

Modified: libmicrohttpd/src/include/platform.h
===================================================================
--- libmicrohttpd/src/include/platform.h        2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/include/platform.h        2014-02-18 18:38:41 UTC (rev 
32395)
@@ -135,4 +135,16 @@
 #define MHD_SOCKET_DEFINED 1
 #endif /* MHD_SOCKET_DEFINED */
 
+/* Force don't use pipes on W32 */
+#if defined(_WIN32) && !defined(MHD_DONT_USE_PIPES)
+#define MHD_DONT_USE_PIPES 1
+#endif /* defined(_WIN32) && !defined(MHD_DONT_USE_PIPES) */
+
+/* MHD_pipe is type for pipe FDs*/
+#ifndef MHD_DONT_USE_PIPES
+typedef int MHD_pipe;
+#else /* ! MHD_DONT_USE_PIPES */
+typedef MHD_socket MHD_pipe;
+#endif /* ! MHD_DONT_USE_PIPES */
+
 #endif

Modified: libmicrohttpd/src/microhttpd/daemon.c
===================================================================
--- libmicrohttpd/src/microhttpd/daemon.c       2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/microhttpd/daemon.c       2014-02-18 18:38:41 UTC (rev 
32395)
@@ -728,7 +728,7 @@
              /* how did we get here!? */
              goto exit;
            }
-         num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp);
+         num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
          if (num_ready < 0)
            {
              if (EINTR == MHD_socket_errno_)
@@ -1306,8 +1306,8 @@
     }
   else
     if ( (MHD_YES == external_add) &&
-        (-1 != daemon->wpipe[1]) &&
-        (1 != WRITE (daemon->wpipe[1], "n", 1)) )
+        (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
+        (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) )
       {
 #if HAVE_MESSAGES
        MHD_DLOG (daemon,
@@ -1477,8 +1477,8 @@
     MHD_PANIC ("Failed to acquire cleanup mutex\n");
   connection->resuming = MHD_YES;
   daemon->resuming = MHD_YES;
-  if ( (-1 != daemon->wpipe[1]) &&
-       (1 != WRITE (daemon->wpipe[1], "r", 1)) )
+  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
+       (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) )
     {
 #if HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -1963,9 +1963,9 @@
        (FD_ISSET (ds, read_fd_set)) )
     (void) MHD_accept_connection (daemon);
   /* drain signaling pipe to avoid spinning select */
-  if ( (-1 != daemon->wpipe[0]) &&
+  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
        (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
-    (void) read (daemon->wpipe[0], &tmp, sizeof (tmp));
+    (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
 
   if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
     {
@@ -2064,7 +2064,7 @@
          FD_SET (daemon->socket_fd, &rs);
        }
     }
-  if (-1 != daemon->wpipe[0])
+  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
     {
       FD_SET (daemon->wpipe[0], &rs);
       /* update max file descriptor */
@@ -2089,7 +2089,7 @@
     }
   if (MHD_INVALID_SOCKET == max)
     return MHD_YES;
-  num_ready = SELECT (max + 1, &rs, &ws, &es, tv);
+  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv);
   if (MHD_YES == daemon->shutdown)
     return MHD_NO;
   if (num_ready < 0)
@@ -2150,7 +2150,7 @@
        poll_listen = (int) poll_server;
        poll_server++;
       }
-    if (-1 != daemon->wpipe[0])
+    if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
       {
        p[poll_server].fd = daemon->wpipe[0];
        p[poll_server].events = POLLIN;
@@ -2284,7 +2284,7 @@
       poll_listen = poll_count;
       poll_count++;
     }
-  if (-1 != daemon->wpipe[0])
+  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
     {
       p[poll_count].fd = daemon->wpipe[0];
       p[poll_count].events = POLLIN;
@@ -2456,10 +2456,10 @@
        {
          if (NULL == events[i].data.ptr)
            continue; /* shutdown signal! */
-      if ( (-1 != daemon->wpipe[0]) &&
+      if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
            (daemon->wpipe[0] == events[i].data.fd) )
         {
-          (void) read (daemon->wpipe[0], &tmp, sizeof (tmp));
+          (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
           continue;
         }
          if (daemon != events[i].data.ptr)
@@ -2692,7 +2692,7 @@
   ret = daemon->socket_fd;
   if (MHD_INVALID_SOCKET == ret)
     return MHD_INVALID_SOCKET;
-  if ( (-1 == daemon->wpipe[1]) &&
+  if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) &&
        (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
     {
 #if HAVE_MESSAGES
@@ -3140,7 +3140,7 @@
 #endif
       return MHD_NO;
     }
-  if ( (-1 != daemon->wpipe[0]) &&
+  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
        (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
     {
       event.events = EPOLLIN | EPOLLET;
@@ -3250,8 +3250,8 @@
   daemon->pool_increment = MHD_BUF_INC_SIZE;
   daemon->unescape_callback = &MHD_http_unescape;
   daemon->connection_timeout = 0;       /* no timeout */
-  daemon->wpipe[0] = -1;
-  daemon->wpipe[1] = -1;
+  daemon->wpipe[0] = MHD_INVALID_PIPE_;
+  daemon->wpipe[1] = MHD_INVALID_PIPE_;
 #if HAVE_MESSAGES
   daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
   daemon->custom_error_log_cls = stderr;
@@ -3263,13 +3263,7 @@
 #endif
   if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | 
MHD_USE_THREAD_PER_CONNECTION)))
     use_pipe = 0; /* useless if we are using 'external' select */
-  if ( (use_pipe) &&
-#ifdef WINDOWS
-       (0 != SOCKETPAIR (AF_INET, SOCK_STREAM, IPPROTO_TCP, daemon->wpipe))
-#else
-       (0 != PIPE (daemon->wpipe))
-#endif
-    )
+  if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) )
     {
 #if HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -3288,9 +3282,9 @@
       MHD_DLOG (daemon,
                "file descriptor for control pipe exceeds maximum value\n");
 #endif
-      if (0 != CLOSE (daemon->wpipe[0]))
+      if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
        MHD_PANIC ("close failed\n");
-      if (0 != CLOSE (daemon->wpipe[1]))
+      if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
        MHD_PANIC ("close failed\n");
       free (daemon);
       return NULL;
@@ -3705,17 +3699,12 @@
           d->worker_pool = NULL;
 
           if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
-#ifdef WINDOWS
-               (0 != SOCKETPAIR (AF_INET, SOCK_STREAM, IPPROTO_TCP, d->wpipe))
-#else
-               (0 != PIPE (d->wpipe))
-#endif
-             )
+               (0 != MHD_pipe_ (d->wpipe)) )
             {
 #if HAVE_MESSAGES
               MHD_DLOG (daemon,
                         "Failed to create worker control pipe: %s\n",
-                        MHD_strerror_ (errno));
+                        MHD_pipe_last_strerror_() );
 #endif
               goto thread_failed;
             }
@@ -3728,9 +3717,9 @@
               MHD_DLOG (daemon,
                         "file descriptor for worker control pipe exceeds 
maximum value\n");
 #endif
-              if (0 != CLOSE (d->wpipe[0]))
+              if (0 != MHD_pipe_close_ (d->wpipe[0]))
                 MHD_PANIC ("close failed\n");
-              if (0 != CLOSE (d->wpipe[1]))
+              if (0 != MHD_pipe_close_ (d->wpipe[1]))
                 MHD_PANIC ("close failed\n");
               goto thread_failed;
             }
@@ -3906,7 +3895,7 @@
 {
   struct epoll_event event;
 
-  if (-1 == daemon->wpipe[1])
+  if (MHD_INVALID_PIPE_ == daemon->wpipe[1])
     {
       /* wpipe was required in this mode, how could this happen? */
       MHD_PANIC ("Internal error\n");
@@ -3957,9 +3946,9 @@
 #endif
        }
     }
-  if (-1 != daemon->wpipe[1])
+  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
     {
-      if (1 != WRITE (daemon->wpipe[1], "e", 1))
+      if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1))
        MHD_PANIC ("failed to signal shutdown via pipe");
     }
 #ifdef HAVE_LISTEN_SHUTDOWN
@@ -3990,9 +3979,9 @@
       /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to 
check */
       for (i = 0; i < daemon->worker_pool_size; ++i)
        {
-         if (-1 != daemon->worker_pool[i].wpipe[1])
+         if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
            {
-             if (1 != WRITE (daemon->worker_pool[i].wpipe[1], "e", 1))
+             if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 
1))
                MHD_PANIC ("failed to signal shutdown via pipe");
            }
          if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
@@ -4006,11 +3995,11 @@
 #endif
           if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & 
MHD_USE_SUSPEND_RESUME)) )
             {
-              if (-1 != daemon->worker_pool[i].wpipe[1])
+              if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
                 {
-                  if (0 != CLOSE (daemon->worker_pool[i].wpipe[0]))
+                  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0]))
                     MHD_PANIC ("close failed\n");
-                  if (0 != CLOSE (daemon->worker_pool[i].wpipe[1]))
+                  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1]))
                     MHD_PANIC ("close failed\n");
                 }
            }
@@ -4058,11 +4047,11 @@
   pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
   pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
 
-  if (-1 != daemon->wpipe[1])
+  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
     {
-      if (0 != CLOSE (daemon->wpipe[0]))
+      if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
        MHD_PANIC ("close failed\n");
-      if (0 != CLOSE (daemon->wpipe[1]))
+      if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
        MHD_PANIC ("close failed\n");
     }
   free (daemon);

Modified: libmicrohttpd/src/microhttpd/internal.h
===================================================================
--- libmicrohttpd/src/microhttpd/internal.h     2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/microhttpd/internal.h     2014-02-18 18:38:41 UTC (rev 
32395)
@@ -1102,9 +1102,10 @@
    * Pipe we use to signal shutdown, unless
    * 'HAVE_LISTEN_SHUTDOWN' is defined AND we have a listen
    * socket (which we can then 'shutdown' to stop listening).
-   * On W32 this is a socketpair, not a pipe.
+   * MHD can be build with usage of socketpair instead of
+   * pipe (forced on W32).
    */
-  int wpipe[2];
+  MHD_pipe wpipe[2];
 
   /**
    * Are we shutting down?

Modified: libmicrohttpd/src/platform/platform_interface.h
===================================================================
--- libmicrohttpd/src/platform/platform_interface.h     2014-02-18 18:38:27 UTC 
(rev 32394)
+++ libmicrohttpd/src/platform/platform_interface.h     2014-02-18 18:38:41 UTC 
(rev 32395)
@@ -26,6 +26,7 @@
 #ifndef MHD_PLATFORM_INTERFACE_H
 #define MHD_PLATFORM_INTERFACE_H
 
+#include "platform.h"
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #include "w32functions.h"
 #endif
@@ -66,4 +67,70 @@
 #define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
 #endif
 
+/* MHD_SYS_select_ is wrapper macro for system select() function */
+#if !defined(MHD_WINSOCK_SOCKETS)
+#define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
+#else
+#define MHD_SYS_select_(n,r,w,e,t) select((int)0,(r),(w),(e),(t))
+#endif
+
+/* MHD_pipe_ create pipe (!MHD_DONT_USE_PIPES) /
+ *           create two connected sockets (MHD_DONT_USE_PIPES) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_(fdarr) pipe((fdarr))
+#else /* MHD_DONT_USE_PIPES */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#define MHD_pipe_(fdarr) socketpair(AF_LOCAL, SOCK_STREAM, 0, (fdarr))
+#else /* !defined(_WIN32) || defined(__CYGWIN__) */
+#define MHD_pipe_(fdarr) MHD_W32_pair_of_sockets_((fdarr))
+#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
+#endif /* MHD_DONT_USE_PIPES */
+
+/* MHD_pipe_errno_ is errno of last function (!MHD_DONT_USE_PIPES) /
+ *                    errno of last emulated pipe function 
(MHD_DONT_USE_PIPES) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_errno_ errno
+#else
+#define MHD_pipe_errno_ MHD_socket_errno_
+#endif
+
+/* MHD_pipe_last_strerror_ is description string of last errno 
(!MHD_DONT_USE_PIPES) /
+ *                            description string of last pipe error 
(MHD_DONT_USE_PIPES) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_last_strerror_() strerror(errno)
+#else
+#define MHD_pipe_last_strerror_() MHD_socket_last_strerr_()
+#endif
+
+/* MHD_pipe_write_ write data to real pipe (!MHD_DONT_USE_PIPES) /
+ *                 write data to emulated pipe (MHD_DONT_USE_PIPES) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_write_(fd, ptr, sz) write((fd), (const void*)(ptr), (sz))
+#else
+#define MHD_pipe_write_(fd, ptr, sz) send((fd), (const char*)(ptr), (sz), 0)
+#endif
+
+/* MHD_pipe_read_ read data from real pipe (!MHD_DONT_USE_PIPES) /
+ *                read data from emulated pipe (MHD_DONT_USE_PIPES) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_read_(fd, ptr, sz) read((fd), (void*)(ptr), (sz))
+#else
+#define MHD_pipe_read_(fd, ptr, sz) recv((fd), (char*)(ptr), (sz), 0)
+#endif
+
+/* MHD_pipe_close_(fd) close any FDs (non-W32) /
+ *                     close emulated pipe FDs (W32) */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_pipe_close_(fd) close((fd))
+#else
+#define MHD_pipe_close_(fd) MHD_socket_close_((fd))
+#endif
+
+/* MHD_INVALID_PIPE_ is a value of bad pipe FD */
+#ifndef MHD_DONT_USE_PIPES
+#define MHD_INVALID_PIPE_ (-1)
+#else
+#define MHD_INVALID_PIPE_ MHD_INVALID_SOCKET
+#endif
+
 #endif // MHD_PLATFORM_INTERFACE_H

Modified: libmicrohttpd/src/platform/w32functions.c
===================================================================
--- libmicrohttpd/src/platform/w32functions.c   2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/platform/w32functions.c   2014-02-18 18:38:41 UTC (rev 
32395)
@@ -541,3 +541,80 @@
     break;
     }
 }
+
+/**
+ * Create pair of mutually connected TCP/IP sockets on loopback address
+ * @param sockets_pair array to receive resulted sockets
+ * @return zero on success, -1 otherwise
+ */
+int MHD_W32_pair_of_sockets_(SOCKET sockets_pair[2])
+{
+  int i;
+  if (!sockets_pair)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+#define PAIRMAXTRYIES 800
+  for (i = 0; i < PAIRMAXTRYIES; i++)
+    {
+      struct sockaddr_in listen_addr;
+      SOCKET listen_s;
+      static const int c_addinlen = sizeof(struct sockaddr_in); /* help 
compiler to optimize */
+      int addr_len = c_addinlen;
+      int opt = 1;
+
+      listen_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+      if (INVALID_SOCKET == listen_s)
+        break; /* can't create even single socket */
+
+      listen_addr.sin_family = AF_INET;
+      listen_addr.sin_port = htons(0);
+      listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+      if (0 == bind(listen_s, (struct sockaddr*) &listen_addr, c_addinlen)
+          && 0 == listen(listen_s, 1)
+          && 0 == getsockname(listen_s, (struct sockaddr*) &listen_addr,
+                  &addr_len))
+        {
+          SOCKET client_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+          if (INVALID_SOCKET != client_s)
+            {
+              if (0 == ioctlsocket(client_s, FIONBIO, (u_long*) &opt)
+                  && (0 == connect(client_s, (struct sockaddr*) &listen_addr, 
c_addinlen)
+                      || WSAGetLastError() == WSAEWOULDBLOCK))
+                {
+                  struct sockaddr_in accepted_from_addr;
+                  addr_len = c_addinlen;
+                  SOCKET server_s = accept(listen_s,
+                      (struct sockaddr*) &accepted_from_addr, &addr_len);
+                  if (INVALID_SOCKET != server_s)
+                    {
+                      struct sockaddr_in client_addr;
+                      addr_len = c_addinlen;
+                      opt = 0;
+                      if (0 == getsockname(client_s, (struct sockaddr*) 
&client_addr, &addr_len)
+                          && accepted_from_addr.sin_family == 
client_addr.sin_family
+                          && accepted_from_addr.sin_port == 
client_addr.sin_port
+                          && accepted_from_addr.sin_addr.s_addr == 
client_addr.sin_addr.s_addr
+                          && 0 == ioctlsocket(client_s, FIONBIO, (u_long*) 
&opt)
+                          && 0 == ioctlsocket(server_s, FIONBIO, (u_long*) 
&opt))
+                        {
+                          closesocket(listen_s);
+                          sockets_pair[0] = client_s;
+                          sockets_pair[1] = server_s;
+                          return 0;
+                        }
+                      closesocket(server_s);
+                    }
+                }
+              closesocket(client_s);
+            }
+        }
+      closesocket(listen_s);
+    }
+
+  sockets_pair[0] = INVALID_SOCKET;
+  sockets_pair[1] = INVALID_SOCKET;
+  return -1;
+}

Modified: libmicrohttpd/src/platform/w32functions.h
===================================================================
--- libmicrohttpd/src/platform/w32functions.h   2014-02-18 18:38:27 UTC (rev 
32394)
+++ libmicrohttpd/src/platform/w32functions.h   2014-02-18 18:38:41 UTC (rev 
32395)
@@ -32,6 +32,7 @@
 #include <errno.h>
 #include <winsock2.h>
 #include "platform.h"
+#include "platform_interface.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -170,6 +171,13 @@
  */
 void MHD_W32_set_last_winsock_error_(int errnum);
 
+/**
+ * Create pair of mutually connected TCP/IP sockets on loopback address
+ * @param sockets_pair array to receive resulted sockets
+ * @return zero on success, -1 otherwise
+ */
+int MHD_W32_pair_of_sockets_(SOCKET sockets_pair[2]);
+
 #ifdef __cplusplus
 }
 #endif




reply via email to

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