unload again
[oweals/gnunet.git] / src / util / network.c
index f2c1faa4b23d210414f67c39b950e01a37bb0780..b5e65de60069ea5532610d93e6448dcded56a9a2 100644 (file)
 \r
 #define DEBUG_SOCK GNUNET_NO\r
 \r
+#ifndef INVALID_SOCKET\r
+#define INVALID_SOCKET -1\r
+#endif\r
+\r
 struct GNUNET_NETWORK_Handle\r
 {\r
   int fd;\r
@@ -43,7 +47,7 @@ struct GNUNET_NETWORK_FDSet
   fd_set sds;\r
 #ifdef WINDOWS\r
   /* handles */\r
-  struct GNUNET_CONTAINER_Vector *handles;\r
+  struct GNUNET_CONTAINER_SList *handles;\r
 #endif\r
 };\r
 \r
@@ -51,6 +55,109 @@ struct GNUNET_NETWORK_FDSet
 #define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))\r
 #endif\r
 \r
+\r
+\r
+/**\r
+ * Set if a socket should use blocking or non-blocking IO.\r
+ * @param fd socket\r
+ * @param doBlock blocking mode\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error\r
+ */\r
+static int\r
+socket_set_blocking (struct GNUNET_NETWORK_Handle *fd,\r
+                    int doBlock)\r
+{\r
+#if MINGW\r
+  u_long mode;\r
+  mode = !doBlock;\r
+  if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR)\r
+    {\r
+      SetErrnoFromWinsockError (WSAGetLastError ());\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  return GNUNET_OK;\r
+\r
+#else\r
+  /* not MINGW */\r
+  int flags = fcntl (fd->fd, F_GETFL);\r
+  if (flags == -1)\r
+    {\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  if (doBlock)\r
+    flags &= ~O_NONBLOCK;\r
+  else\r
+    flags |= O_NONBLOCK;\r
+  if (0 != fcntl (fd->fd, F_SETFL, flags))\r
+    {\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  return GNUNET_OK;\r
+#endif\r
+}\r
+\r
+\r
+#ifndef MINGW\r
+/**\r
+ * Make a socket non-inheritable to child processes\r
+ *\r
+ * @param h the socket to make non-inheritable\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise\r
+ * @warning Not implemented on Windows\r
+ */\r
+static int\r
+socket_set_inheritable (const struct GNUNET_NETWORK_Handle\r
+                                       *h)\r
+{\r
+  int i;\r
+\r
+  i = fcntl (h->fd, F_GETFD);\r
+  if (i == (i | FD_CLOEXEC))\r
+    return GNUNET_OK;\r
+  return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)\r
+    ? GNUNET_OK : GNUNET_SYSERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+#ifdef DARWIN\r
+/**\r
+ * The MSG_NOSIGNAL equivalent on Mac OS X\r
+ *\r
+ * @param h the socket to make non-delaying\r
+ */\r
+static void\r
+socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle\r
+                   *h)\r
+{\r
+  int value = 1;\r
+  setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));\r
+}\r
+#endif\r
+\r
+\r
+\r
+/**\r
+ * Disable delays when sending data via the socket.\r
+ * (GNUnet makes sure that messages are as big as\r
+ * possible already).\r
+ *\r
+ * @param h the socket to make non-delaying\r
+ */\r
+static void\r
+socket_set_nodelay (const struct GNUNET_NETWORK_Handle\r
+                   *h)\r
+{\r
+  int value = 1;\r
+  setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));\r
+}\r
+\r
+\r
+\r
 /**\r
  * accept a new connection on a socket\r
  *\r
@@ -68,10 +175,39 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
 \r
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));\r
   ret->fd = accept (desc->fd, address, address_len);\r
+  if (ret->fd == INVALID_SOCKET)\r
+    {\r
 #ifdef MINGW\r
-  if (INVALID_SOCKET == ret->fd)\r
-    SetErrnoFromWinsockError (WSAGetLastError ());\r
+      SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+      GNUNET_free (ret);\r
+      return NULL;\r
+    }\r
+#ifndef MINGW\r
+  if (ret->fd >= FD_SETSIZE)\r
+    {\r
+      close (ret->fd);\r
+      GNUNET_free (ret);\r
+      errno = EMFILE;\r
+      return NULL;\r
+    }\r
+#endif\r
+  if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))\r
+    {\r
+      /* we might want to treat this one as fatal... */\r
+      GNUNET_break (0);\r
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));\r
+      return NULL; \r
+    }\r
+#ifndef MINGW\r
+  if (GNUNET_OK != socket_set_inheritable (ret))\r
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,\r
+                        "socket_set_inheritable");\r
 #endif\r
+#ifdef DARWIN\r
+  socket_set_nosigpipe (ret);  \r
+#endif\r
+  socket_set_nodelay (ret);\r
   return ret;\r
 }\r
 \r
@@ -97,47 +233,6 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
 }\r
 \r
-/**\r
- * Set if a socket should use blocking or non-blocking IO.\r
- * @param fd socket\r
- * @param doBlock blocking mode\r
- * @return GNUNET_OK on success, GNUNET_SYSERR on error\r
- */\r
-int\r
-GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd,\r
-                                    int doBlock)\r
-{\r
-#if MINGW\r
-  u_long mode;\r
-  mode = !doBlock;\r
-  if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR)\r
-    {\r
-      SetErrnoFromWinsockError (WSAGetLastError ());\r
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");\r
-      return GNUNET_SYSERR;\r
-    }\r
-  return GNUNET_OK;\r
-\r
-#else\r
-  /* not MINGW */\r
-  int flags = fcntl (fd->fd, F_GETFL);\r
-  if (flags == -1)\r
-    {\r
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
-      return GNUNET_SYSERR;\r
-    }\r
-  if (doBlock)\r
-    flags &= ~O_NONBLOCK;\r
-  else\r
-    flags |= O_NONBLOCK;\r
-  if (0 != fcntl (fd->fd, F_SETFL, flags))\r
-    {\r
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
-      return GNUNET_SYSERR;\r
-    }\r
-  return GNUNET_OK;\r
-#endif\r
-}\r
 \r
 /**\r
  * Close a socket\r
@@ -148,21 +243,18 @@ int
 GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)\r
 {\r
   int ret;\r
+  int eno;\r
+\r
 #ifdef MINGW\r
   ret = closesocket (desc->fd);\r
-  if (SOCKET_ERROR != ret)\r
-    GNUNET_free (desc);\r
-  else\r
-    SetErrnoFromWinsockError (WSAGetLastError ());\r
+  SetErrnoFromWinsockError (WSAGetLastError ());  \r
 #else\r
   ret = close (desc->fd);\r
-  if (-1 == ret)\r
-    {\r
-      GNUNET_free (desc);\r
-    }\r
-#endif\r
-\r
-  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
+#endif  \r
+  eno = errno;\r
+  GNUNET_free (desc);\r
+  errno = eno;\r
+  return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;\r
 }\r
 \r
 /**\r
@@ -193,6 +285,7 @@ GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
 \r
 /**\r
  * Get socket options\r
+ *\r
  * @param desc socket\r
  * @param level protocol level of the option\r
  * @param optname identifier of the option\r
@@ -239,18 +332,22 @@ GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc,
 }\r
 \r
 /**\r
- * Read data from a connected socket\r
+ * Read data from a connected socket (always non-blocking).\r
  * @param desc socket\r
  * @param buffer buffer\r
  * @param length length of buffer\r
- * @param flags type of message reception\r
  */\r
 ssize_t\r
 GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,\r
-                            void *buffer, size_t length, int flags)\r
+                            void *buffer, size_t length)\r
 {\r
   int ret;\r
+  int flags;\r
 \r
+  flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+  flags |= MSG_DONTWAIT;\r
+#endif\r
   ret = recv (desc->fd, buffer, length, flags);\r
 #ifdef MINGW\r
   if (SOCKET_ERROR == ret)\r
@@ -261,19 +358,27 @@ GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,
 }\r
 \r
 /**\r
- * Send data\r
+ * Send data (always non-blocking).\r
+ *\r
  * @param desc socket\r
  * @param buffer data to send\r
  * @param length size of the buffer\r
- * @param flags type of message transmission\r
  * @return number of bytes sent, GNUNET_SYSERR on error\r
  */\r
 ssize_t\r
 GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,\r
-                            const void *buffer, size_t length, int flags)\r
+                            const void *buffer, size_t length)\r
 {\r
   int ret;\r
+  int flags;\r
 \r
+  flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+  flags |= MSG_DONTWAIT;\r
+#endif\r
+#ifdef MSG_NOSIGNAL\r
+  flags |= MSG_NOSIGNAL;\r
+#endif\r
   ret = send (desc->fd, buffer, length, flags);\r
 #ifdef MINGW\r
   if (SOCKET_ERROR == ret)\r
@@ -283,24 +388,34 @@ GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,
   return ret;\r
 }\r
 \r
+\r
 /**\r
- * Send data\r
+ * Send data to a particular destination (always non-blocking).\r
+ * This function only works for UDP sockets.\r
+ *\r
  * @param desc socket\r
  * @param message data to send\r
  * @param length size of the data\r
- * @param flags type of message transmission\r
  * @param dest_addr destination address\r
  * @param dest_len length of address\r
  * @return number of bytes sent, GNUNET_SYSERR on error\r
  */\r
 ssize_t\r
 GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc,\r
-                              const void *message, size_t length, int flags,\r
+                              const void *message, size_t length,\r
                               const struct sockaddr * dest_addr,\r
                               socklen_t dest_len)\r
 {\r
   int ret;\r
+  int flags;\r
 \r
+  flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+  flags |= MSG_DONTWAIT;\r
+#endif\r
+#ifdef MSG_NOSIGNAL\r
+  flags |= MSG_NOSIGNAL;\r
+#endif\r
   ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);\r
 #ifdef MINGW\r
   if (SOCKET_ERROR == ret)\r
@@ -336,30 +451,60 @@ GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
 }\r
 \r
+\r
+\r
 /**\r
- * Create a new socket\r
+ * Create a new socket.  Configure it for non-blocking IO and\r
+ * mark it as non-inheritable to child processes (set the\r
+ * close-on-exec flag).\r
+ *\r
  * @param domain domain of the socket\r
  * @param type socket type\r
  * @param protocol network protocol\r
  * @return new socket, NULL on error\r
  */\r
 struct GNUNET_NETWORK_Handle *\r
-GNUNET_NETWORK_socket_socket (int domain, int type, int protocol)\r
+GNUNET_NETWORK_socket_create (int domain, int type, int protocol)\r
 {\r
   struct GNUNET_NETWORK_Handle *ret;\r
 \r
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));\r
   ret->fd = socket (domain, type, protocol);\r
-#ifdef MINGW\r
   if (INVALID_SOCKET == ret->fd)\r
-    SetErrnoFromWinsockError (WSAGetLastError ());\r
+    {\r
+#ifdef MINGW\r
+      SetErrnoFromWinsockError (WSAGetLastError ());\r
 #endif\r
-\r
-  if (ret->fd < 0)\r
+      GNUNET_free (ret);\r
+      return NULL;\r
+    }\r
+#ifndef MINGW\r
+  if (ret->fd >= FD_SETSIZE)\r
     {\r
+      close (ret->fd);\r
       GNUNET_free (ret);\r
-      ret = NULL;\r
+      errno = EMFILE;\r
+      return NULL;\r
     }\r
+#endif\r
+\r
+  if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))\r
+    {\r
+      /* we might want to treat this one as fatal... */\r
+      GNUNET_break (0);\r
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));\r
+      return NULL; \r
+    }\r
+#ifndef MINGW\r
+  if (GNUNET_OK != socket_set_inheritable (ret))\r
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,\r
+                        "socket_set_inheritable");\r
+#endif\r
+#ifdef DARWIN\r
+  socket_set_nosigpipe (ret);  \r
+#endif\r
+  if (type == SOCK_STREAM)\r
+    socket_set_nodelay (ret);\r
 \r
   return ret;\r
 }\r
@@ -385,27 +530,6 @@ GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc,
   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
 }\r
 \r
-/**\r
- * Make a non-inheritable to child processes\r
- * @param socket\r
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise\r
- * @warning Not implemented on Windows\r
- */\r
-int\r
-GNUNET_NETWORK_socket_set_inheritable (const struct GNUNET_NETWORK_Handle\r
-                                       *desc)\r
-{\r
-#ifdef MINGW\r
-  errno = ENOSYS;\r
-  return GNUNET_SYSERR;\r
-#else\r
-  return fcntl (desc->fd, F_SETFD,\r
-                fcntl (desc->fd,\r
-                       F_GETFD) | FD_CLOEXEC) ==\r
-    0 ? GNUNET_OK : GNUNET_SYSERR;\r
-#endif\r
-}\r
-\r
 \r
 /**\r
  * Reset FD set\r
@@ -417,9 +541,7 @@ GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)
   FD_ZERO (&fds->sds);\r
   fds->nsds = 0;\r
 #ifdef MINGW\r
-  if (fds->handles)\r
-    GNUNET_CONTAINER_vector_destroy (fds->handles);\r
-  fds->handles = GNUNET_CONTAINER_vector_create (2);\r
+  GNUNET_CONTAINER_slist_clear (fds->handles);\r
 #endif\r
 }\r
 \r
@@ -487,15 +609,19 @@ GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
   FD_COPY (&from->sds, &to->sds);\r
   to->nsds = from->nsds;\r
 #ifdef MINGW\r
-  void *obj;\r
+  struct GNUNET_CONTAINER_SList_Iterator *iter;\r
+\r
+\r
+  GNUNET_CONTAINER_slist_clear (to->handles);\r
 \r
-  if (to->handles)\r
-    GNUNET_CONTAINER_vector_destroy (to->handles);\r
-  to->handles = GNUNET_CONTAINER_vector_create (2);\r
-  for (obj = GNUNET_CONTAINER_vector_get_first (from->handles); obj != NULL;\r
-       obj = GNUNET_CONTAINER_vector_get_next (from->handles))\r
+  for (iter = GNUNET_CONTAINER_slist_begin (from->handles);\r
+      GNUNET_CONTAINER_slist_end (iter) != GNUNET_YES; GNUNET_CONTAINER_slist_next (iter))\r
     {\r
-      GNUNET_CONTAINER_vector_insert_last (to->handles, obj);\r
+      void *handle;\r
+      size_t len;\r
+\r
+      handle = GNUNET_CONTAINER_slist_get (iter, &len);\r
+      GNUNET_CONTAINER_slist_add (to->handles, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, handle, len);\r
     }\r
 #endif\r
 }\r
@@ -528,12 +654,12 @@ GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
 #ifdef MINGW\r
   HANDLE hw;\r
 \r
-  GNUNET_internal_disk_file_handle (h, &hw, sizeof (HANDLE));\r
-  GNUNET_CONTAINER_vector_insert_last (fds->handles, h);\r
+  GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE));\r
+  GNUNET_CONTAINER_slist_add (fds->handles, GNUNET_NO, &hw, sizeof (HANDLE));\r
 #else\r
   int fd;\r
 \r
-  GNUNET_internal_disk_file_handle (h, &fd, sizeof (int));\r
+  GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int));\r
   FD_SET (fd, &fds->sds);\r
   if (fd + 1 > fds->nsds)\r
     fds->nsds = fd + 1;\r
@@ -551,8 +677,7 @@ GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
                                    const struct GNUNET_DISK_FileHandle *h)\r
 {\r
 #ifdef MINGW\r
-  return GNUNET_CONTAINER_vector_index_of (fds->handles, h->h) !=\r
-    (unsigned int) -1;\r
+  return GNUNET_CONTAINER_slist_contains (fds->handles, h->h, sizeof (HANDLE));\r
 #else\r
   return FD_ISSET (h->fd, &fds->sds);\r
 #endif\r
@@ -592,10 +717,9 @@ GNUNET_NETWORK_fdset_create ()
 \r
   fds = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_FDSet));\r
 #ifdef MINGW\r
-  fds->handles = NULL;\r
+  fds->handles = GNUNET_CONTAINER_slist_create ();\r
 #endif\r
   GNUNET_NETWORK_fdset_zero (fds);\r
-\r
   return fds;\r
 }\r
 \r
@@ -608,7 +732,7 @@ void
 GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)\r
 {\r
 #ifdef MINGW\r
-  GNUNET_CONTAINER_vector_destroy (fds->handles);\r
+  GNUNET_CONTAINER_slist_destroy (fds->handles);\r
 #endif\r
   GNUNET_free (fds);\r
 }\r
@@ -738,50 +862,76 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
 \r
       /* Poll read pipes */\r
       if (rfds)\r
-        for (i = GNUNET_CONTAINER_vector_size (rfds->handles) - 1; i >= 0; i--)\r
-          {\r
-            DWORD dwBytes;\r
-\r
-            if (!PeekNamedPipe\r
-                (GNUNET_CONTAINER_vector_get_at (rfds->handles, i), NULL, 0,\r
-                 NULL, &dwBytes, NULL))\r
-              {\r
-                GNUNET_CONTAINER_vector_remove_at (rfds->handles, i);\r
-\r
-                retcode = -1;\r
-                SetErrnoFromWinError (GetLastError ());\r
+        {\r
+          struct GNUNET_CONTAINER_SList_Iterator *i;\r
+          int on_next;\r
+\r
+          on_next = GNUNET_NO;\r
+          for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);\r
+                    GNUNET_CONTAINER_slist_end (i) != GNUNET_YES;\r
+                    on_next || GNUNET_CONTAINER_slist_next (i))\r
+            {\r
+              HANDLE h;\r
+              DWORD dwBytes;\r
+\r
+              h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);\r
+              on_next = GNUNET_NO;\r
+\r
+              if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))\r
+                {\r
+                  GNUNET_CONTAINER_slist_erase (i);\r
+                  on_next = GNUNET_YES;\r
+\r
+                  retcode = -1;\r
+                  SetErrnoFromWinError (GetLastError ());\r
 #if DEBUG_SOCK\r
-            GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "PeekNamedPipe");\r
-#endif\r
-               goto select_loop_end;\r
-              }\r
-            else if (dwBytes)\r
-              {\r
-                retcode++;\r
-              }\r
-            else\r
-              GNUNET_CONTAINER_vector_remove_at (rfds->handles, i);\r
-          }\r
+                  GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "PeekNamedPipe");\r
+#endif\r
+                  goto select_loop_end;\r
+                }\r
+              else if (dwBytes)\r
+                {\r
+                  retcode++;\r
+                }\r
+              else\r
+                {\r
+                  GNUNET_CONTAINER_slist_erase (i);\r
+                  on_next = GNUNET_YES;\r
+                }\r
+            }\r
+        }\r
 \r
       /* Poll for faulty pipes */\r
       if (efds)\r
-        for (i = GNUNET_CONTAINER_vector_size (efds->handles); i >= 0; i--)\r
-          {\r
-            DWORD dwBytes;\r
+        {\r
+          struct GNUNET_CONTAINER_SList_Iterator *i;\r
+          int on_next;\r
+\r
+          on_next = GNUNET_NO;\r
+          for (i = GNUNET_CONTAINER_slist_begin (efds->handles);\r
+                    GNUNET_CONTAINER_slist_end (i) != GNUNET_YES;\r
+                    on_next || GNUNET_CONTAINER_slist_next (i))\r
+            {\r
+              HANDLE h;\r
+              DWORD dwBytes;\r
+\r
+              h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);\r
 \r
-            if (PeekNamedPipe\r
-                (GNUNET_CONTAINER_vector_get_at (rfds->handles, i), NULL, 0,\r
-                 NULL, &dwBytes, NULL))\r
-              {\r
-                GNUNET_CONTAINER_vector_remove_at (efds->handles, i);\r
+              if (PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))\r
+                {\r
+                  GNUNET_CONTAINER_slist_erase (i);\r
+                  on_next = GNUNET_YES;\r
 \r
-                retcode++;\r
-              }\r
-          }\r
+                  retcode++;\r
+                }\r
+              else\r
+                on_next = GNUNET_NO;\r
+            }\r
+        }\r
 \r
       /* FIXME */\r
       if (wfds)\r
-        GNUNET_assert (GNUNET_CONTAINER_vector_size (wfds->handles) == 0);\r
+        GNUNET_assert (GNUNET_CONTAINER_slist_count (wfds->handles) == 0);\r
 \r
       /* Check for closed sockets */\r
       for (i = 0; i < nfds; i++)\r