/**
* Set if a socket should use blocking or non-blocking IO.
+ *
* @param fd socket
* @param doBlock blocking mode
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
-static int
-socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
+int
+GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
{
#if MINGW
#else
BOOL b;
SetLastError (0);
- b = SetHandleInformation (h->fd, HANDLE_FLAG_INHERIT, 0);
+ b = SetHandleInformation ((HANDLE) h->fd, HANDLE_FLAG_INHERIT, 0);
if (!b)
{
SetErrnoFromWinsockError (WSAGetLastError ());
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"socket_set_inheritable");
- if (GNUNET_SYSERR == socket_set_blocking (h, GNUNET_NO))
+ if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (h, GNUNET_NO))
{
GNUNET_break (0);
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
/**
* Bind to a connected socket
- * @param desc socket
+ *
+ * @param desc socket to bind
* @param address address to be bound
* @param address_len length of address
+ * @param flags flags affecting bind behaviour
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
*/
int
GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
const struct sockaddr *address,
- socklen_t address_len)
+ socklen_t address_len,
+ int flags)
{
int ret;
#ifdef IPV6_V6ONLY
#ifdef IPPROTO_IPV6
- const int on = 1;
+ {
+ const int on = 1;
- if (desc->af == AF_INET6)
- if (0 != setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
- LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ if (desc->af == AF_INET6)
+ if (setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ }
#endif
#endif
#ifndef WINDOWS
- /* This is required, and required here, but only on UNIX */
- if (0 != setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
- LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ {
+ const int on = 1;
+
+ /* This is required, and required here, but only on UNIX */
+ if (0 != setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ }
#endif
#ifndef LINUX
#ifndef MINGW
- if (address->sa_family == AF_UNIX)
+ if (address->sa_family == AF_UNIX && (flags & GNUNET_BIND_EXCLUSIVE) == 0)
{
const struct sockaddr_un *un = (const struct sockaddr_un *) address;
_selector (LPVOID p)
{
struct _select_params *sp = p;
- int i;
+
while (1)
{
WaitForSingleObject (sp->standby, INFINITE);
p = 1;
res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: ioctlsocket() returns %d\n", res);
alen = sizeof (s_in);
s_in.sin_family = AF_INET;
s_in.sin_addr.S_un.S_un_b.s_b3 = 0;
s_in.sin_addr.S_un.S_un_b.s_b4 = 1;
res = bind (select_listening_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: bind() returns %d\n", res);
res = getsockname (select_listening_socket, (struct sockaddr *) &s_in, &alen);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: getsockname() returns %d\n", res);
res = listen (select_listening_socket, SOMAXCONN);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: listen() returns %d\n", res);
res = connect (select_wakeup_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: connect() returns %d\n", res);
select_send_socket = accept (select_listening_socket, (struct sockaddr *) &s_in, &alen);
/* Copy all the writes to the except, so we can detect connect() errors */
for (i = 0; i < awrite.fd_count; i++)
- {
- if (awrite.fd_array[i] != 0 && awrite.fd_array[i] != -1)
- FD_SET (awrite.fd_array[i], &aexcept);
- }
+ FD_SET (awrite.fd_array[i], &aexcept);
if (aread.fd_count > 0 || awrite.fd_count > 0 || aexcept.fd_count > 0)
selectret = select (1, (rfds != NULL) ? &aread : NULL,
(wfds != NULL) ? &awrite : NULL, &aexcept, &select_timeout);
have checked that descriptors were in awrite originally before re-adding them from
aexcept. Luckily, GNUnet never uses aexcept for anything, so this does not become a problem (yet). */
for (i = 0; i < aexcept.fd_count; i++)
- {
- if (aexcept.fd_array[i] != 0 && aexcept.fd_array[i] != -1)
- FD_SET (aexcept.fd_array[i], &awrite);
- }
+ FD_SET (aexcept.fd_array[i], &awrite);
/* If our select returned something or is a 0-timed request, then also check the pipes and get out of here! */
/* Sadly, it means code duplication :( */
if (rfds && read_handles)
{
struct GNUNET_CONTAINER_SList_Iterator i;
+ int c;
- for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);
+ for (c = 0, i = GNUNET_CONTAINER_slist_begin (rfds->handles);
GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&i))
+ GNUNET_CONTAINER_slist_next (&i), c++)
{
struct GNUNET_DISK_FileHandle *fh;
bret = PeekNamedPipe (fh->h, NULL, 0, NULL, &waitstatus, NULL);
error = GetLastError ();
LOG (GNUNET_ERROR_TYPE_DEBUG, "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
- i, fh->h, bret, waitstatus, error);
+ c, fh->h, bret, waitstatus, error);
if (bret == 0)
{
/* TODO: either add more errors to this condition, or eliminate it
* but we don't use OOB data.
*/
for (i = 0; i < awrite.fd_count; i++)
- {
- if (awrite.fd_array[i] != 0 && awrite.fd_array[i] != -1)
- FD_SET (awrite.fd_array[i], &aexcept);
- }
+ FD_SET (awrite.fd_array[i], &aexcept);
ResetEvent (select_finished_event);
SetEvent (select_standby_event);
}
}
/* Check aexcept, add its contents to awrite */
for (i = 0; i < aexcept.fd_count; i++)
- {
- if (aexcept.fd_array[i] != 0 && aexcept.fd_array[i] != -1)
- FD_SET (aexcept.fd_array[i], &awrite);
- }
+ FD_SET (aexcept.fd_array[i], &awrite);
}
returnedpos = returncode - WAIT_OBJECT_0;