-dce
[oweals/gnunet.git] / src / util / network.c
index c61704be984df087c5f88fef44968af7e255a3d9..86bc47677b2422fd88bf3856d3c0b317f8df1a8a 100644 (file)
@@ -163,7 +163,6 @@ socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
 }
 
 
-#ifndef MINGW
 /**
  * Make a socket non-inheritable to child processes
  *
@@ -174,8 +173,8 @@ socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
 static int
 socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
 {
+#ifndef MINGW
   int i;
-
   i = fcntl (h->fd, F_GETFD);
   if (i < 0)
     return GNUNET_SYSERR;
@@ -184,9 +183,18 @@ socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
   i |= FD_CLOEXEC;
   if (fcntl (h->fd, F_SETFD, i) < 0)
     return GNUNET_SYSERR;
+#else
+  BOOL b;
+  SetLastError (0);
+  b = SetHandleInformation (h->fd, HANDLE_FLAG_INHERIT, 0);
+  if (!b)
+  {
+    SetErrnoFromWinsockError (WSAGetLastError ());
+    return GNUNET_SYSERR;
+  }
+#endif
   return GNUNET_OK;
 }
-#endif
 
 
 #ifdef DARWIN
@@ -266,10 +274,11 @@ initialize_network_handle (struct GNUNET_NETWORK_Handle *h,
     errno = EMFILE;
     return GNUNET_SYSERR;
   }
+#endif
   if (GNUNET_OK != socket_set_inheritable (h))
     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                   "socket_set_inheritable");
-#endif
+
   if (GNUNET_SYSERR == socket_set_blocking (h, GNUNET_NO))
   {
     GNUNET_break (0);
@@ -1273,11 +1282,11 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
 #endif
       )
   {
+    GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _
          ("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
          "select");
-    GNUNET_break (0);
   }
 #ifndef MINGW
   tv.tv_sec = timeout.rel_value / GNUNET_TIME_UNIT_SECONDS.rel_value;
@@ -1409,7 +1418,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
 
       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
                                                                          NULL);
-      if (fh->type == GNUNET_PIPE)
+      if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
       {
         /* Read zero bytes to check the status of the pipe */
         LOG (GNUNET_ERROR_TYPE_DEBUG, "Reading 0 bytes from the pipe 0x%x\n",
@@ -1470,7 +1479,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
 
       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
                                                                          NULL);
-      if (fh->type == GNUNET_PIPE)
+      if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
       {
         if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
         {
@@ -1523,10 +1532,22 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
   LOG (GNUNET_ERROR_TYPE_DEBUG, "nfds: %d, handles: %d, will wait: %llu ms\n", 
        nfds, nhandles, (unsigned long long) ms_total);
   if (nhandles)
+  {
     returncode =
         WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_total);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n",
-       returncode);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n",
+         returncode);
+  }
+  else if (nfds > 0)
+  {
+    i = (int) WaitForSingleObject (select_finished_event, INFINITE);
+    returncode = WAIT_TIMEOUT;
+  }
+  else
+  {
+    /* Shouldn't come this far. If it does - investigate. */
+    GNUNET_assert (0);
+  }
 
   if (nfds > 0)
   {
@@ -1587,7 +1608,11 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
              i, readArray[i]->h, bret, waitstatus, error);
         if (bret == 0)
         {
-          if (error != ERROR_BROKEN_PIPE)
+          /* TODO: either add more errors to this condition, or eliminate it
+           * entirely (failed to peek -> pipe is in serious trouble, should
+           * be selected as readable).
+           */
+          if (error != ERROR_BROKEN_PIPE && error != ERROR_INVALID_HANDLE)
             continue;
         }
         else if (waitstatus <= 0)
@@ -1616,7 +1641,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
 
       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
                                                                          NULL);
-      if (fh->type == GNUNET_PIPE)
+      if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
       {
         CancelIo (fh->h);
       }