#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
-#endif /* */
+#endif
+
+
struct GNUNET_NETWORK_Handle
{
+#ifndef MINGW
int fd;
+
+#else
+ SOCKET fd;
+#endif
+
+ /**
+ * Address family / domain.
+ */
+ int af;
};
+
+
struct GNUNET_NETWORK_FDSet
{
- /* socket descriptors */
+ /**
+ * Maximum number of any socket socket descriptor in the set (plus one)
+ */
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.
}
return GNUNET_OK;
-#else /* */
+#else
/* not MINGW */
int flags = fcntl (fd->fd, F_GETFL);
if (flags == -1)
return GNUNET_SYSERR;
}
return GNUNET_OK;
-
-#endif /* */
+#endif
}
socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
{
int i;
- i = fcntl (h->fd, F_GETFD);
+
+ i = fcntl (h->fd, F_GETFD);
+ if (i < 0)
+ return GNUNET_SYSERR;
if (i == (i | FD_CLOEXEC))
return GNUNET_OK;
- return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)
- ? GNUNET_OK : GNUNET_SYSERR;
+ i |= FD_CLOEXEC;
+ if (fcntl (h->fd, F_SETFD, i) < 0)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
}
+#endif
-#endif /* */
-
#ifdef DARWIN
/**
* The MSG_NOSIGNAL equivalent on Mac OS X
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
static void
socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
{
+#ifndef WINDOWS
int value = 1;
- if (0 !=
- setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
+ if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+#else
+ const char * value = "1";
+ if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, value, sizeof (value)))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+#endif
}
socklen_t * address_len)
{
struct GNUNET_NETWORK_Handle *ret;
+
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
ret->fd = accept (desc->fd, address, address_len);
+ ret->af = address->sa_family;
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))
{
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;
}
socklen_t address_len)
{
int ret;
+
+#ifdef IPV6_V6ONLY
+#ifdef IPPROTO_IPV6
+ const int on = 1;
+ if (desc->af == AF_INET6)
+ setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on));
+#if 0
+ /* is this needed or desired? or done elsewhere? */
+ setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
+#endif
+#endif
+#endif
ret = bind (desc->fd, address, address_len);
-
#ifdef MINGW
if (SOCKET_ERROR == ret)
SetErrnoFromWinsockError (WSAGetLastError ());
-
-#endif /* */
+#else
+#ifndef LINUX
+ if ( (ret == 0) && (address->sa_family == AF_UNIX))
+ {
+ const struct sockaddr_un *un = (const struct sockaddr_un*) address;
+ if (0 != unlink (un->sun_path))
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "unlink",
+ un->sun_path);
+ }
+#endif
+#endif
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
}
GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
{
int ret;
- int eno;
#ifdef MINGW
ret = closesocket (desc->fd);
SetErrnoFromWinsockError (WSAGetLastError ());
-
-#else /* */
+#else
ret = close (desc->fd);
-
-#endif /* */
- eno = errno;
+#endif
GNUNET_free (desc);
- errno = eno;
return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
}
+/**
+ * Box a native socket (and check that it is a socket).
+ *
+ * @param fd socket to box
+ * @return NULL on error (including not supported on target platform)
+ */
+struct GNUNET_NETWORK_Handle *
+GNUNET_NETWORK_socket_box_native (int fd)
+{
+#if MINGW
+ return NULL;
+#else
+ struct GNUNET_NETWORK_Handle *ret;
+
+ if (fcntl (fd, F_GETFD) < 0)
+ return NULL; /* invalid FD */
+ ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
+ ret->fd = fd;
+ ret->af = AF_UNSPEC;
+ return ret;
+#endif
+}
+
+
/**
* Connect a socket
* @param desc socket
if (errno == EWOULDBLOCK)
errno = EINPROGRESS;
}
-
-#endif /* */
+#endif
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
}
else if (SOCKET_ERROR == ret)
SetErrnoFromWinsockError (WSAGetLastError ());
-#endif /* */
+#endif
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
}
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;
+
+ /* How much is there to be read? */
+#ifndef WINDOWS
+ int pending;
+ error = ioctl (desc->fd, FIONREAD, &pending);
+ if (error == 0)
+#else
+ u_long pending;
+ 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
#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;
}
#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;
}
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;
}
{
struct GNUNET_NETWORK_Handle *ret;
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
+ ret->af = domain;
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);
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));
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;
}
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;
}
{
FD_ZERO (&fds->sds);
fds->nsds = 0;
-
#ifdef MINGW
GNUNET_CONTAINER_slist_clear (fds->handles);
-
-#endif /* */
+#endif
}
/**
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
*/
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
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);
+}
+
+
+/**
+ * Test native fd in a set
+ *
+ * @param to set to test, NULL for empty set
+ * @param nfd native FD to test, or -1 for none
+ * @return GNUNET_YES if FD is set in the set
+ */
+int
+GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
+ int nfd)
+{
+ if ( (nfd == -1) || (to == NULL) )
+ return GNUNET_NO;
+ return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
+}
+
+
/**
* Add a file handle to the fd set
* @param fds fd set
GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
const struct GNUNET_DISK_FileHandle *h)
{
-
#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
}
+#if MINGW
+/**
+ * Add a W32 file handle to the fd set
+ * @param fds fd set
+ * @param h the file handle to add
+ */
+void
+GNUNET_NETWORK_fdset_handle_set_native_w32_handle (struct GNUNET_NETWORK_FDSet *fds,
+ HANDLE h)
+{
+ GNUNET_CONTAINER_slist_add (fds->handles,
+ GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
+ &h, sizeof (HANDLE));
+}
+#endif
+
+
/**
* Check if a file handle is part of an fd set
* @param fds fd set
{
#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
}
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 = (HANDLE *) GNUNET_CONTAINER_slist_get ((const struct GNUNET_CONTAINER_SList_Iterator *)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;
}
{
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;
}
void
GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
{
-
#ifdef MINGW
GNUNET_CONTAINER_slist_destroy (fds->handles);
-
-#endif /* */
+#endif
GNUNET_free (fds);
}
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,
_
"select");
GNUNET_break (0);
}
- return select (nfds + 1,
+#ifndef MINGW
+ return select (nfds,
(rfds != NULL) ? &rfds->sds : NULL,
(wfds != NULL) ? &wfds->sds : NULL,
(efds != NULL) ? &efds->sds : NULL,
(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;
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);
limit = GetTickCount () + ms_total;
do
-
{
retcode = 0;
if (nfds > 0)
#if DEBUG_NETWORK
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
-#endif /* */
+#endif
goto select_loop_end;
}
}
{
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 ());
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 */
{
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++)
}
}
}
- 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)
+ if (retcode != -1)
{
if (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
}