X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fnetwork.c;h=8ec365269dd5b003ffce0a9407b19edaf4a20c8d;hb=d47f834c1f2de41c9fba74a4b6928e7c8e0679e0;hp=a16380736561bcba231eb052261c7169abacccac;hpb=bb82fb7f4ea781b843f032c6869f98e6fa6fa107;p=oweals%2Fgnunet.git diff --git a/src/util/network.c b/src/util/network.c index a16380736..8ec365269 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -33,28 +33,45 @@ #ifndef INVALID_SOCKET #define INVALID_SOCKET -1 -#endif /* */ +#endif + + struct GNUNET_NETWORK_Handle { +#ifndef MINGW int fd; +#else + SOCKET fd; +#endif }; + + struct GNUNET_NETWORK_FDSet { - /* socket descriptors */ + /** + * Maximum number of any socket socket descriptor in the set + */ int nsds; + + /** + * Bitset with the descriptors. + */ fd_set sds; #ifdef WINDOWS - /* handles */ + /** + * Linked list of handles + */ struct GNUNET_CONTAINER_SList *handles; +#endif -#endif /* */ }; #ifndef FD_COPY #define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set))) -#endif /* */ +#endif + /** * Set if a socket should use blocking or non-blocking IO. @@ -78,7 +95,7 @@ socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock) } return GNUNET_OK; -#else /* */ +#else /* not MINGW */ int flags = fcntl (fd->fd, F_GETFL); if (flags == -1) @@ -99,8 +116,7 @@ socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock) return GNUNET_SYSERR; } return GNUNET_OK; - -#endif /* */ +#endif } @@ -122,10 +138,9 @@ socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h) return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0) ? GNUNET_OK : GNUNET_SYSERR; } +#endif -#endif /* */ - #ifdef DARWIN /** * The MSG_NOSIGNAL equivalent on Mac OS X @@ -140,10 +155,9 @@ socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h) setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof (value))) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); } +#endif -#endif /* */ - /** * Disable delays when sending data via the socket. * (GNUnet makes sure that messages are as big as @@ -178,28 +192,22 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); ret->fd = accept (desc->fd, address, address_len); if (ret->fd == INVALID_SOCKET) - { - #ifdef MINGW SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif GNUNET_free (ret); return NULL; } - #ifndef MINGW if (ret->fd >= FD_SETSIZE) - { GNUNET_break (0 == close (ret->fd)); GNUNET_free (ret); errno = EMFILE; return NULL; } - -#endif /* */ +#endif if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) { @@ -214,13 +222,14 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, if (GNUNET_OK != socket_set_inheritable (ret)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "socket_set_inheritable"); - -#endif /* */ +#endif #ifdef DARWIN socket_set_nosigpipe (ret); - -#endif /* */ - socket_set_nodelay (ret); +#endif +#ifdef AF_UNIX + if (address->sa_family != AF_UNIX) +#endif + socket_set_nodelay (ret); return ret; } @@ -238,13 +247,12 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc, socklen_t address_len) { int ret; - ret = bind (desc->fd, address, address_len); + ret = bind (desc->fd, address, address_len); #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -263,11 +271,9 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc) #ifdef MINGW ret = closesocket (desc->fd); SetErrnoFromWinsockError (WSAGetLastError ()); - -#else /* */ +#else ret = close (desc->fd); - -#endif /* */ +#endif eno = errno; GNUNET_free (desc); errno = eno; @@ -298,8 +304,7 @@ GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc, if (errno == EWOULDBLOCK) errno = EINPROGRESS; } - -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -329,7 +334,7 @@ GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc, else if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -351,11 +356,69 @@ GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc, if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } +/** + * How much data is available to be read on this descriptor? + * + * Returns GNUNET_NO if no data is available, or on error! + * @param desc socket + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle + *desc) +{ + int error; + int pending; + + /* How much is there to be read? */ +#ifndef WINDOWS + error = ioctl (desc->fd, FIONREAD, &pending); + if (error == 0) +#else + error = ioctlsocket (desc->fd, FIONREAD, &pending); + if (error != SOCKET_ERROR) +#endif + return pending; + else + return GNUNET_NO; +} + +/** + * Read data from a connected socket (always non-blocking). + * @param desc socket + * @param buffer buffer + * @param length length of buffer + * @param src_addr either the source to recv from, or all zeroes + * to be filled in by recvfrom + * @param addrlen length of the addr + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle * desc, + void *buffer, size_t length, + struct sockaddr * src_addr, + socklen_t * addrlen) +{ + int ret; + int flags; + flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; + +#endif + ret = recvfrom (desc->fd, buffer, length, flags, src_addr, addrlen); +#ifdef MINGW + if (SOCKET_ERROR == ret) + SetErrnoFromWinsockError (WSAGetLastError ()); +#endif + return ret; +} + + /** * Read data from a connected socket (always non-blocking). * @param desc socket @@ -372,15 +435,12 @@ GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc, #ifdef MSG_DONTWAIT flags |= MSG_DONTWAIT; - -#endif /* */ +#endif ret = recv (desc->fd, buffer, length, flags); - #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret; } @@ -443,19 +503,15 @@ GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc, #ifdef MSG_DONTWAIT flags |= MSG_DONTWAIT; - -#endif /* */ +#endif #ifdef MSG_NOSIGNAL flags |= MSG_NOSIGNAL; - -#endif /* */ +#endif ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len); - #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret; } @@ -476,13 +532,12 @@ GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, socklen_t option_len) { int ret; - ret = setsockopt (fd->fd, level, option_name, option_value, option_len); + ret = setsockopt (fd->fd, level, option_name, option_value, option_len); #ifdef MINGW if (SOCKET_ERROR == ret) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -504,20 +559,16 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol) ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); ret->fd = socket (domain, type, protocol); if (INVALID_SOCKET == ret->fd) - { - #ifdef MINGW SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif GNUNET_free (ret); return NULL; } #ifndef MINGW if (ret->fd >= FD_SETSIZE) - { GNUNET_break (0 == close (ret->fd)); GNUNET_free (ret); @@ -525,11 +576,9 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol) return NULL; } -#endif /* */ +#endif if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) - { - /* we might want to treat this one as fatal... */ GNUNET_break (0); GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); @@ -540,13 +589,15 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol) if (GNUNET_OK != socket_set_inheritable (ret)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "socket_set_inheritable"); - -#endif /* */ +#endif #ifdef DARWIN socket_set_nosigpipe (ret); - -#endif /* */ - if (type == SOCK_STREAM) +#endif + if ( (type == SOCK_STREAM) +#ifdef AF_UNIX + && (domain != AF_UNIX) +#endif + ) socket_set_nodelay (ret); return ret; } @@ -562,13 +613,12 @@ int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how) { int ret; - ret = shutdown (desc->fd, how); + ret = shutdown (desc->fd, how); #ifdef MINGW if (ret != 0) SetErrnoFromWinsockError (WSAGetLastError ()); - -#endif /* */ +#endif return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; } @@ -582,11 +632,9 @@ GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds) { FD_ZERO (&fds->sds); fds->nsds = 0; - #ifdef MINGW GNUNET_CONTAINER_slist_clear (fds->handles); - -#endif /* */ +#endif } /** @@ -636,11 +684,15 @@ GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst, if (nfds + 1 > dst->nsds) dst->nsds = nfds + 1; } +#ifdef MINGW + GNUNET_CONTAINER_slist_append (dst->handles, src->handles); +#endif } /** * Copy one fd set to another + * * @param to destination * @param from source */ @@ -652,25 +704,20 @@ GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to, to->nsds = from->nsds; #ifdef MINGW - struct GNUNET_CONTAINER_SList_Iterator *iter; GNUNET_CONTAINER_slist_clear (to->handles); - for (iter = GNUNET_CONTAINER_slist_begin (from->handles); - GNUNET_CONTAINER_slist_end (iter) != GNUNET_YES; - GNUNET_CONTAINER_slist_next (iter)) + GNUNET_CONTAINER_slist_append (to->handles, from->handles); +#endif +} - { - void *handle; - size_t len; - handle = GNUNET_CONTAINER_slist_get (iter, &len); - GNUNET_CONTAINER_slist_add (to->handles, - GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, - handle, len); - } -#endif /* */ +int +GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc) +{ + return desc->fd; } /** * Copy a native fd set + * * @param to destination * @param from native source set * @param nfds the biggest socket number in from + 1 @@ -683,6 +730,21 @@ GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to, to->nsds = nfds; } + +/** + * Set a native fd in a set + * + * @param to destination + * @param nfd native FD to set + */ +void GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to, + int nfd) +{ + FD_SET (nfd, &to->sds); + to->nsds = GNUNET_MAX (nfd + 1, to->nsds); +} + + /** * Add a file handle to the fd set * @param fds fd set @@ -696,16 +758,18 @@ GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds, #ifdef MINGW HANDLE hw; GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE)); - GNUNET_CONTAINER_slist_add (fds->handles, GNUNET_NO, &hw, sizeof (HANDLE)); + GNUNET_CONTAINER_slist_add (fds->handles, + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &hw, sizeof (HANDLE)); -#else /* */ +#else int fd; GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int)); FD_SET (fd, &fds->sds); if (fd + 1 > fds->nsds) fds->nsds = fd + 1; -#endif /* */ +#endif } @@ -721,13 +785,11 @@ GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds, { #ifdef MINGW - return GNUNET_CONTAINER_slist_contains (fds->handles, h->h, + return GNUNET_CONTAINER_slist_contains (fds->handles, &h->h, sizeof (HANDLE)); - -#else /* */ +#else return FD_ISSET (h->fd, &fds->sds); - -#endif /* */ +#endif } @@ -748,6 +810,27 @@ GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, for (; nfds >= 0; nfds--) if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds)) return GNUNET_YES; +#ifdef MINGW + { + struct GNUNET_CONTAINER_SList_Iterator *it; + + for (it = GNUNET_CONTAINER_slist_begin (fds1->handles); + GNUNET_CONTAINER_slist_end (it) != GNUNET_YES; + GNUNET_CONTAINER_slist_next (it)) + { + HANDLE *h; + + h = GNUNET_CONTAINER_slist_get (it, NULL); + if (GNUNET_CONTAINER_slist_contains + (fds2->handles, h, sizeof (HANDLE))) + { + GNUNET_CONTAINER_slist_iter_destroy (it); + return GNUNET_YES; + } + } + GNUNET_CONTAINER_slist_iter_destroy (it); + } +#endif return GNUNET_NO; } @@ -761,11 +844,9 @@ GNUNET_NETWORK_fdset_create () { struct GNUNET_NETWORK_FDSet *fds; fds = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_FDSet)); - #ifdef MINGW fds->handles = GNUNET_CONTAINER_slist_create (); - -#endif /* */ +#endif GNUNET_NETWORK_fdset_zero (fds); return fds; } @@ -778,11 +859,9 @@ GNUNET_NETWORK_fdset_create () void GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds) { - #ifdef MINGW GNUNET_CONTAINER_slist_destroy (fds->handles); - -#endif /* */ +#endif GNUNET_free (fds); } @@ -801,21 +880,44 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, const struct GNUNET_TIME_Relative timeout) { int nfds; +#ifdef MINGW + int handles; +#endif nfds = 0; +#ifdef MINGW + handles = 0; +#endif if (NULL != rfds) - nfds = rfds->nsds; + { + nfds = rfds->nsds; +#ifdef MINGW + handles = GNUNET_CONTAINER_slist_count (rfds->handles); +#endif + } if (NULL != wfds) - nfds = GNUNET_MAX (nfds, wfds->nsds); + { + nfds = GNUNET_MAX (nfds, wfds->nsds); +#ifdef MINGW + handles += GNUNET_CONTAINER_slist_count (wfds->handles); +#endif + } if (NULL != efds) - nfds = GNUNET_MAX (nfds, efds->nsds); + { + nfds = GNUNET_MAX (nfds, efds->nsds); +#ifdef MINGW + handles += GNUNET_CONTAINER_slist_count (efds->handles); +#endif + } -#ifndef MINGW struct timeval tv; tv.tv_sec = timeout.value / GNUNET_TIME_UNIT_SECONDS.value; tv.tv_usec = 1000 * (timeout.value - (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.value)); - if ((nfds == 0) && (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value)) - + if ((nfds == 0) && (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value) +#ifdef MINGW + && handles == 0 +#endif + ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ @@ -823,6 +925,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, "select"); GNUNET_break (0); } +#ifndef MINGW return select (nfds + 1, (rfds != NULL) ? &rfds->sds : NULL, (wfds != NULL) ? &wfds->sds : NULL, @@ -830,10 +933,13 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value) ? NULL : &tv); -#else /* */ +#else DWORD limit; fd_set sock_read, sock_write, sock_except; fd_set aread, awrite, aexcept; + struct GNUNET_CONTAINER_SList *handles_read, *handles_write, + *handles_except; + int i; struct timeval tvslice; int retcode; @@ -855,19 +961,21 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, Sleep (ms_total); return 0; } + + handles_read = GNUNET_CONTAINER_slist_create (); + handles_write = GNUNET_CONTAINER_slist_create (); + handles_except = GNUNET_CONTAINER_slist_create (); + if (rfds) sock_read = rfds->sds; - else FD_ZERO (&sock_read); if (wfds) sock_write = wfds->sds; - else FD_ZERO (&sock_write); if (efds) sock_except = efds->sds; - else FD_ZERO (&sock_except); @@ -878,7 +986,6 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, limit = GetTickCount () + ms_total; do - { retcode = 0; if (nfds > 0) @@ -904,7 +1011,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, #if DEBUG_NETWORK GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select"); -#endif /* */ +#endif goto select_loop_end; } } @@ -914,22 +1021,16 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { struct GNUNET_CONTAINER_SList_Iterator *i; - int on_next; - on_next = GNUNET_NO; for (i = GNUNET_CONTAINER_slist_begin (rfds->handles); GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; - on_next || GNUNET_CONTAINER_slist_next (i)) + GNUNET_CONTAINER_slist_next (i)) { HANDLE h; DWORD dwBytes; h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL); - on_next = GNUNET_NO; if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL)) - { - GNUNET_CONTAINER_slist_erase (i); - on_next = GNUNET_YES; retcode = -1; SetErrnoFromWinError (GetLastError ()); @@ -937,23 +1038,19 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "PeekNamedPipe"); -#endif /* */ +#endif goto select_loop_end; } - else if (dwBytes) { + GNUNET_CONTAINER_slist_add (handles_read, + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &h, sizeof (HANDLE)); retcode++; } - - else - - { - GNUNET_CONTAINER_slist_erase (i); - on_next = GNUNET_YES; - } } + GNUNET_CONTAINER_slist_iter_destroy (i); } /* Poll for faulty pipes */ @@ -961,32 +1058,31 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { struct GNUNET_CONTAINER_SList_Iterator *i; - int on_next; - on_next = GNUNET_NO; for (i = GNUNET_CONTAINER_slist_begin (efds->handles); GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; - on_next || GNUNET_CONTAINER_slist_next (i)) + GNUNET_CONTAINER_slist_next (i)) { HANDLE h; DWORD dwBytes; h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL); - if (PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL)) + if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL)) { - GNUNET_CONTAINER_slist_erase (i); - on_next = GNUNET_YES; + GNUNET_CONTAINER_slist_add (handles_except, + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + &h, sizeof (HANDLE)); retcode++; } - - else - on_next = GNUNET_NO; } + GNUNET_CONTAINER_slist_iter_destroy (i); } - /* FIXME */ if (wfds) - GNUNET_assert (GNUNET_CONTAINER_slist_count (wfds->handles) == 0); + { + GNUNET_CONTAINER_slist_append (handles_write, wfds->handles); + retcode += GNUNET_CONTAINER_slist_count (wfds->handles); + } /* Check for closed sockets */ for (i = 0; i < nfds; i++) @@ -1017,9 +1113,12 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, } } } - select_loop_end:; + select_loop_end: + if (retcode == 0 && nfds == 0) + Sleep (GNUNET_MIN (100, limit - GetTickCount ())); } while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit)); + if (retcode != -1) { @@ -1028,23 +1127,34 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { GNUNET_NETWORK_fdset_zero (rfds); GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode); + GNUNET_CONTAINER_slist_clear (rfds->handles); + GNUNET_CONTAINER_slist_append (rfds->handles, handles_read); + } if (wfds) { GNUNET_NETWORK_fdset_zero (wfds); GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode); + GNUNET_CONTAINER_slist_clear (wfds->handles); + GNUNET_CONTAINER_slist_append (wfds->handles, handles_write); } if (efds) { GNUNET_NETWORK_fdset_zero (efds); GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode); + GNUNET_CONTAINER_slist_clear (efds->handles); + GNUNET_CONTAINER_slist_append (efds->handles, handles_except); } } - return retcode; -#endif /* */ + GNUNET_CONTAINER_slist_destroy (handles_read); + GNUNET_CONTAINER_slist_destroy (handles_write); + GNUNET_CONTAINER_slist_destroy (handles_except); + + return retcode; +#endif }