+/*
+ * sockets.c: Socket handles
+ *
+ * Author:
+ * Dick Porter (dick@ximian.com)
+ *
+ * (C) 2002 Ximian, Inc.
+ */
+
#include <config.h>
#include <glib.h>
#include <pthread.h>
#include <sys/sockio.h> /* defines SIOCATMARK */
#endif
#include <unistd.h>
+#include <fcntl.h>
-#include "mono/io-layer/wapi.h"
-#include "wapi-private.h"
+#ifndef HAVE_MSG_NOSIGNAL
+#include <signal.h>
+#endif
-#define DEBUG
+#include <mono/io-layer/wapi.h>
+#include <mono/io-layer/wapi-private.h>
+#include <mono/io-layer/socket-private.h>
+#include <mono/io-layer/handles-private.h>
+#include <mono/io-layer/socket-wrappers.h>
-struct _WapiHandle_socket
-{
- WapiHandle handle;
- int fd;
-};
+#undef DEBUG
static guint32 startup_count=0;
-static GPtrArray *sockets=NULL;
static pthread_key_t error_key;
-static pthread_once_t error_key_once=PTHREAD_ONCE_INIT;
+static mono_once_t error_key_once=MONO_ONCE_INIT;
-static void socket_close(WapiHandle *handle);
+static void socket_close (gpointer handle, gpointer data);
-static struct _WapiHandleOps socket_ops = {
+struct _WapiHandleOps _wapi_socket_ops = {
socket_close, /* close */
- NULL, /* getfiletype */
- NULL, /* readfile */
- NULL, /* writefile */
- NULL, /* seek */
- NULL, /* setendoffile */
- NULL, /* getfilesize */
- NULL, /* getfiletime */
- NULL, /* setfiletime */
- NULL, /* wait */
- NULL, /* wait_multiple */
NULL, /* signal */
+ NULL, /* own */
+ NULL, /* is_owned */
};
-static void socket_close(WapiHandle *handle)
+static mono_once_t socket_ops_once=MONO_ONCE_INIT;
+
+static void socket_ops_init (void)
{
+ /* No capabilities to register */
+}
+
+static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED)
+{
+ int ret;
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing socket handle %p", handle);
+ g_message ("%s: closing socket handle %p", __func__, handle);
#endif
- closesocket(handle);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return;
+ }
+
+ do {
+ ret = close (GPOINTER_TO_UINT(handle));
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+
+ if (ret == -1) {
+ gint errnum = errno;
+#ifdef DEBUG
+ g_message ("%s: close error: %s", __func__, strerror (errno));
+#endif
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
+ }
}
int WSAStartup(guint32 requested, WapiWSAData *data)
{
- if(data==NULL) {
+ if (data == NULL) {
return(WSAEFAULT);
}
/* Insist on v2.0+ */
- if(requested < MAKEWORD(2,0)) {
+ if (requested < MAKEWORD(2,0)) {
return(WSAVERNOTSUPPORTED);
}
- if(startup_count==0) {
- sockets=g_ptr_array_new();
- }
-
startup_count++;
/* I've no idea what is the minor version of the spec I read */
- data->wHighVersion=MAKEWORD(2,0);
+ data->wHighVersion = MAKEWORD(2,0);
- data->wVersion=requested < data->wHighVersion? requested:
+ data->wVersion = requested < data->wHighVersion? requested:
data->wHighVersion;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": high version 0x%x",
- data->wHighVersion);
+ g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
#endif
- strncpy(data->szDescription, "WAPI", WSADESCRIPTION_LEN);
- strncpy(data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
+ strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
+ strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
return(0);
}
+static gboolean
+cleanup_close (gpointer handle, gpointer data)
+{
+ _wapi_handle_ops_close (handle, NULL);
+ return TRUE;
+}
+
int WSACleanup(void)
{
- guint32 i;
-
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": cleaning up");
+ g_message ("%s: cleaning up", __func__);
#endif
- if(--startup_count) {
+ if (--startup_count) {
/* Do nothing */
return(0);
}
-
- /* Close down all sockets */
- for(i=0; i<sockets->len; i++) {
- WapiHandle *handle;
- handle=g_ptr_array_index(sockets, i);
- handle->ops->close(handle);
- }
-
- g_ptr_array_free(sockets, FALSE);
- sockets=NULL;
-
+ _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
return(0);
}
static void error_init(void)
{
- pthread_key_create(&error_key, NULL);
+ int ret;
+
+ ret = pthread_key_create (&error_key, NULL);
+ g_assert (ret == 0);
}
void WSASetLastError(int error)
{
- pthread_once(&error_key_once, error_init);
- pthread_setspecific(error_key, GINT_TO_POINTER(error));
+ int ret;
+
+ mono_once (&error_key_once, error_init);
+ ret = pthread_setspecific (error_key, GINT_TO_POINTER(error));
+ g_assert (ret == 0);
}
int WSAGetLastError(void)
int err;
void *errptr;
- pthread_once(&error_key_once, error_init);
- errptr=pthread_getspecific(error_key);
- err=GPOINTER_TO_INT(errptr);
+ mono_once (&error_key_once, error_init);
+ errptr = pthread_getspecific (error_key);
+ err = GPOINTER_TO_INT(errptr);
return(err);
}
-int closesocket(WapiHandle *handle)
+int closesocket(guint32 fd)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
- int ret;
+ gpointer handle = GUINT_TO_POINTER (fd);
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
- return(SOCKET_ERROR);
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(0);
}
- if(handle->type!=WAPI_HANDLE_SOCKET) {
- WSASetLastError(WSAENOTSOCK);
- return(SOCKET_ERROR);
+ _wapi_handle_unref (handle);
+ return(0);
+}
+
+guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ gpointer handle = GUINT_TO_POINTER (fd);
+ gpointer new_handle;
+ int new_fd;
+
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(INVALID_SOCKET);
}
- g_ptr_array_remove_fast(sockets, handle);
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(INVALID_SOCKET);
+ }
- ret=close(socket_handle->fd);
- if(ret==-1) {
+ do {
+ new_fd = accept (fd, addr, addrlen);
+ } while (new_fd == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
+
+ if (new_fd == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": close error: %s",
- strerror(errno));
+ g_message ("%s: accept error: %s", __func__, strerror(errno));
#endif
- switch(errno) {
- case EBADF:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EINTR:
- WSASetLastError(WSAEINTR);
- break;
- case EIO:
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
- return(SOCKET_ERROR);
- }
- return(ret);
-}
-
-WapiHandle *_wapi_accept(WapiHandle *handle, struct sockaddr *addr, socklen_t *addrlen)
-{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
- struct _WapiHandle_socket *new_socket_handle;
- WapiHandle *new_handle;
- int fd;
-
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
return(INVALID_SOCKET);
}
-
- fd=accept(socket_handle->fd, addr, addrlen);
- if(fd==-1) {
+
+ if (new_fd >= _wapi_fd_reserve) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": accept error: %s",
- strerror(errno));
+ g_message ("%s: File descriptor is too big", __func__);
#endif
- switch(errno) {
-#if EAGAIN != EWOULDBLOCK
- case EAGAIN:
-#endif
- case EWOULDBLOCK:
- WSASetLastError(WSAEWOULDBLOCK);
- break;
- case EBADF:
- break;
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EOPNOTSUPP:
- WSASetLastError(WSAEOPNOTSUPP);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EPERM:
- WSASetLastError(WSAENETDOWN);
- break;
- case ENOBUFS:
- case ENOMEM:
- WSASetLastError(WSAENOBUFS);
- break;
- case EMFILE:
- WSASetLastError(WSAEMFILE);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- case ENOSR:
- case ECONNABORTED:
- case ESOCKTNOSUPPORT:
- case EPROTONOSUPPORT:
- case ETIMEDOUT:
-#ifdef ERESTARTSYS
- case ERESTARTSYS:
-#endif
- WSASetLastError(WSAENETDOWN);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ WSASetLastError (WSASYSCALLFAILURE);
+
+ close (new_fd);
return(INVALID_SOCKET);
}
-
- new_socket_handle=g_new0(struct _WapiHandle_socket, 1);
- new_handle=(WapiHandle *)new_socket_handle;
-
- _WAPI_HANDLE_INIT(new_handle, WAPI_HANDLE_SOCKET, socket_ops);
-
- new_socket_handle->fd=fd;
-
+
+ new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd, NULL);
+ if(new_handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating socket handle", __func__);
+ WSASetLastError (ERROR_GEN_FAILURE);
+ return(INVALID_SOCKET);
+ }
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": returning newly accepted socket handle %p with fd %d",
- new_handle, new_socket_handle->fd);
+ g_message ("%s: returning newly accepted socket handle %p with",
+ __func__, new_handle);
#endif
-
- return(new_handle);
+
+ return(new_fd);
}
-int _wapi_bind(WapiHandle *handle, struct sockaddr *my_addr, socklen_t addrlen)
+int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(SOCKET_ERROR);
+ }
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=bind(socket_handle->fd, my_addr, addrlen);
- if(ret==-1) {
+ ret = bind (fd, my_addr, addrlen);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": bind error: %s",
- strerror(errno));
+ g_message ("%s: bind error: %s", __func__, strerror(errno));
#endif
-
- switch(errno) {
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- case EACCES:
- WSASetLastError(WSAEACCES);
- break;
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
-
- /* The following apply to Unix domain sockets */
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EROFS:
- case ENAMETOOLONG:
- case ENOENT:
- case ENOMEM:
- case ENOTDIR:
- case ELOOP:
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_connect(WapiHandle *handle, const struct sockaddr *serv_addr, socklen_t addrlen)
+int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
+ socklen_t addrlen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
+ gint errnum;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=connect(socket_handle->fd, serv_addr, addrlen);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+ do {
+ ret = connect (fd, serv_addr, addrlen);
+ } while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+
+ if (ret == -1 && errno == EACCES) {
+ /* Try setting SO_BROADCAST and connecting again, but
+ * keep the original errno
+ */
+ int true=1;
+
+ errnum = errno;
+
+ ret = setsockopt (fd, SOL_SOCKET, SO_BROADCAST, &true,
+ sizeof(true));
+ if (ret == 0) {
+ do {
+ ret = connect (fd, serv_addr, addrlen);
+ } while (ret==-1 && errno==EINTR &&
+ !_wapi_thread_cur_apc_pending());
+ }
+ } else if (ret == -1) {
+ errnum = errno;
+ }
+
+ if (ret == -1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": bind error: %s",
- strerror(errno));
+ g_message ("%s: connect error: %s", __func__,
+ strerror (errnum));
#endif
+ errnum = errno_to_WSA (errnum, __func__);
+ if (errnum == WSAEINPROGRESS)
+ errnum = WSAEWOULDBLOCK; /* see bug #73053 */
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EISCONN:
- WSASetLastError(WSAEISCONN);
- break;
- case ECONNREFUSED:
- WSASetLastError(WSAECONNREFUSED);
- break;
- case ETIMEDOUT:
- WSASetLastError(WSAETIMEDOUT);
- break;
- case ENETUNREACH:
- WSASetLastError(WSAENETUNREACH);
- break;
- case EADDRINUSE:
- WSASetLastError(WSAEADDRINUSE);
- break;
- case EINPROGRESS:
- WSASetLastError(WSAEINPROGRESS);
- break;
- case EALREADY:
- WSASetLastError(WSAEALREADY);
- break;
- case EAFNOSUPPORT:
- WSASetLastError(WSAEAFNOSUPPORT);
- break;
- case EACCES:
- case EPERM:
- WSASetLastError(WSAEACCES);
- break;
- case EAGAIN:
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_getpeername(WapiHandle *handle, struct sockaddr *name, socklen_t *namelen)
+int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(SOCKET_ERROR);
+ }
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=getpeername(socket_handle->fd, name, namelen);
- if(ret==-1) {
+ ret = getpeername (fd, name, namelen);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": getpeername error: %s",
- strerror(errno));
+ g_message ("%s: getpeername error: %s", __func__,
+ strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ENOTCONN:
- WSASetLastError(WSAENOTCONN);
- break;
- case ENOBUFS:
- /* not documented */
- WSASetLastError(WSAENOBUFS);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_getsockname(WapiHandle *handle, struct sockaddr *name, socklen_t *namelen)
+int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(SOCKET_ERROR);
+ }
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=getsockname(socket_handle->fd, name, namelen);
- if(ret==-1) {
+ ret = getsockname (fd, name, namelen);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": getsockname error: %s",
- strerror(errno));
+ g_message ("%s: getsockname error: %s", __func__,
+ strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ENOBUFS:
- /* not documented */
- WSASetLastError(WSAENOBUFS);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_getsockopt(WapiHandle *handle, int level, int optname, void *optval, socklen_t *optlen)
+int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
+ socklen_t *optlen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
-
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ struct timeval tv;
+ void *tmp_val;
+
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=getsockopt(socket_handle->fd, level, optname, optval, optlen);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+ tmp_val = optval;
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ tmp_val = &tv;
+ *optlen = sizeof (tv);
+ }
+
+ ret = getsockopt (fd, level, optname, tmp_val, optlen);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": getsockopt error: %s",
- strerror(errno));
+ g_message ("%s: getsockopt error: %s", __func__,
+ strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ENOPROTOOPT:
- WSASetLastError(WSAENOPROTOOPT);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
+
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ *((int *) optval) = tv.tv_sec * 1000 + tv.tv_usec;
+ *optlen = sizeof (int);
+ }
return(ret);
}
-int _wapi_listen(WapiHandle *handle, int backlog)
+int _wapi_listen(guint32 fd, int backlog)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=listen(socket_handle->fd, backlog);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+ ret = listen (fd, backlog);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": listen error: %s",
- strerror(errno));
+ g_message ("%s: listen error: %s", __func__, strerror (errno));
#endif
- switch(errno) {
- case EADDRINUSE:
- WSASetLastError(WSAEADDRINUSE);
- break;
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EOPNOTSUPP:
- WSASetLastError(WSAEOPNOTSUPP);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(0);
}
-int _wapi_recv(WapiHandle *handle, void *buf, size_t len, int flags)
+int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
{
- return(_wapi_recvfrom(handle, buf, len, flags, NULL, 0));
+ return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0));
}
-int _wapi_recvfrom(WapiHandle *handle, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
+int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
+ struct sockaddr *from, socklen_t *fromlen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+#ifndef HAVE_MSG_NOSIGNAL
+ void (*old_sigpipe)(int); // old SIGPIPE handler
+#endif
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(SOCKET_ERROR);
+ }
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=recvfrom(socket_handle->fd, buf, len, flags, from, fromlen);
- if(ret==-1) {
+#ifdef HAVE_MSG_NOSIGNAL
+ do {
+ ret = recvfrom (fd, buf, len, recv_flags | MSG_NOSIGNAL, from,
+ fromlen);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+#else
+ old_sigpipe = signal (SIGPIPE, SIG_IGN);
+ do {
+ ret = recvfrom (fd, buf, len, recv_flags, from, fromlen);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+ signal (SIGPIPE, old_sigpipe);
+#endif
+
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": recv error: %s",
- strerror(errno));
+ g_message ("%s: recv error: %s", __func__, strerror(errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ECONNREFUSED:
- /* Not documented */
- WSASetLastError(WSAECONNREFUSED);
- break;
- case ENOTCONN:
- WSASetLastError(WSAENOTCONN);
- break;
- case EAGAIN:
- WSASetLastError(WSAEWOULDBLOCK);
- break;
- case EINTR:
- WSASetLastError(WSAEINTR);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_send(WapiHandle *handle, const void *msg, size_t len, int flags)
+int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+#ifndef HAVE_MSG_NOSIGNAL
+ void (*old_sigpipe)(int); // old SIGPIPE handler
+#endif
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=send(socket_handle->fd, msg, len, flags);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+#ifdef HAVE_MSG_NOSIGNAL
+ do {
+ ret = send (fd, msg, len, send_flags | MSG_NOSIGNAL);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+#else
+ old_sigpipe = signal (SIGPIPE, SIG_IGN);
+ do {
+ ret = send (fd, msg, len, send_flags);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+ signal (SIGPIPE, old_sigpipe);
+#endif
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": send error: %s",
- strerror(errno));
+ g_message ("%s: send error: %s", __func__, strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EMSGSIZE:
- WSASetLastError(WSAEMSGSIZE);
- break;
-#if EAGAIN != EWOULDBLOCK
- case EAGAIN:
-#endif
- case EWOULDBLOCK:
- WSASetLastError(WSAEWOULDBLOCK);
- break;
- case ENOBUFS:
- WSASetLastError(WSAENOBUFS);
- break;
- case EINTR:
- WSASetLastError(WSAEINTR);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- case EPIPE:
- WSASetLastError(WSAESHUTDOWN);
- break;
- case ENOMEM:
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_sendto(WapiHandle *handle, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
+int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
+ const struct sockaddr *to, socklen_t tolen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+#ifndef HAVE_MSG_NOSIGNAL
+ void (*old_sigpipe)(int); // old SIGPIPE handler
+#endif
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=sendto(socket_handle->fd, msg, len, flags, to, tolen);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+#ifdef HAVE_MSG_NOSIGNAL
+ do {
+ ret = sendto (fd, msg, len, send_flags | MSG_NOSIGNAL, to,
+ tolen);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+#else
+ old_sigpipe = signal (SIGPIPE, SIG_IGN);
+ do {
+ ret = sendto (fd, msg, len, send_flags, to, tolen);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+ signal (SIGPIPE, old_sigpipe);
+#endif
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": send error: %s",
- strerror(errno));
+ g_message ("%s: send error: %s", __func__, strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EMSGSIZE:
- WSASetLastError(WSAEMSGSIZE);
- break;
-#if EAGAIN != EWOULDBLOCK
- case EAGAIN:
-#endif
- case EWOULDBLOCK:
- WSASetLastError(WSAEWOULDBLOCK);
- break;
- case ENOBUFS:
- WSASetLastError(WSAENOBUFS);
- break;
- case EINTR:
- WSASetLastError(WSAEINTR);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- case EPIPE:
- WSASetLastError(WSAESHUTDOWN);
- break;
- case ENOMEM:
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_setsockopt(WapiHandle *handle, int level, int optname, const void *optval, socklen_t optlen)
+int _wapi_setsockopt(guint32 fd, int level, int optname,
+ const void *optval, socklen_t optlen)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
+ const void *tmp_val;
+ struct timeval tv;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=setsockopt(socket_handle->fd, level, optname, optval, optlen);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+ tmp_val = optval;
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ int ms = *((int *) optval);
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = ms % 1000;
+ tmp_val = &tv;
+ optlen = sizeof (tv);
+ }
+
+ ret = setsockopt (fd, level, optname, tmp_val, optlen);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": setsockopt error: %s",
- strerror(errno));
+ g_message ("%s: setsockopt error: %s", __func__,
+ strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ENOPROTOOPT:
- WSASetLastError(WSAENOPROTOOPT);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-int _wapi_shutdown(WapiHandle *handle, int how)
+int _wapi_shutdown(guint32 fd, int how)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=shutdown(socket_handle->fd, how);
- if(ret==-1) {
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(SOCKET_ERROR);
+ }
+
+ ret = shutdown (fd, how);
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": shutdown error: %s",
- strerror(errno));
+ g_message ("%s: shutdown error: %s", __func__,
+ strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- case ENOTSOCK:
- WSASetLastError(WSAENOTSOCK);
- break;
- case ENOTCONN:
- WSASetLastError(WSAENOTCONN);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-WapiHandle *_wapi_socket(int domain, int type, int protocol)
+guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
+ guint32 unused2, guint32 unused3)
{
- struct _WapiHandle_socket *socket_handle;
- WapiHandle *handle;
+ gpointer handle;
int fd;
- fd=socket(domain, type, protocol);
- if(fd==-1) {
+ fd = socket (domain, type, protocol);
+ if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
+ protocol == 0) {
+ /* Retry with protocol == 4 (see bug #54565) */
+ fd = socket (AF_INET, SOCK_RAW, 4);
+ }
+
+ if (fd == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": socket error: %s", strerror(errno));
+ g_message ("%s: socket error: %s", __func__, strerror (errno));
#endif
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(INVALID_SOCKET);
}
+
+ if (fd >= _wapi_fd_reserve) {
+#ifdef DEBUG
+ g_message ("%s: File descriptor is too big", __func__);
+#endif
+
+ WSASetLastError (WSASYSCALLFAILURE);
+ close (fd);
+
+ return(INVALID_SOCKET);
+ }
- socket_handle=g_new0(struct _WapiHandle_socket, 1);
- handle=(WapiHandle *)socket_handle;
-
- _WAPI_HANDLE_INIT(handle, WAPI_HANDLE_SOCKET, socket_ops);
- socket_handle->fd=fd;
+ mono_once (&socket_ops_once, socket_ops_init);
+ handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, NULL);
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating socket handle", __func__);
+ return(INVALID_SOCKET);
+ }
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": returning socket handle %p with fd %d", handle,
- socket_handle->fd);
+ g_message ("%s: returning socket handle %p", __func__, handle);
#endif
- return(handle);
+ return(fd);
}
struct hostent *_wapi_gethostbyname(const char *hostname)
{
struct hostent *he;
-
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(NULL);
}
- he=gethostbyname(hostname);
- if(he==NULL) {
+ he = gethostbyname (hostname);
+ if (he == NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": listen error: %s",
- strerror(errno));
+ g_message ("%s: gethostbyname error: %s", __func__,
+ strerror (h_errno));
#endif
switch(h_errno) {
case HOST_NOT_FOUND:
- WSASetLastError(WSAHOST_NOT_FOUND);
+ WSASetLastError (WSAHOST_NOT_FOUND);
break;
#if NO_ADDRESS != NO_DATA
case NO_ADDRESS:
#endif
case NO_DATA:
- WSASetLastError(WSANO_DATA);
+ WSASetLastError (WSANO_DATA);
break;
case NO_RECOVERY:
- WSASetLastError(WSANO_RECOVERY);
+ WSASetLastError (WSANO_RECOVERY);
break;
case TRY_AGAIN:
- WSASetLastError(WSATRY_AGAIN);
+ WSASetLastError (WSATRY_AGAIN);
break;
default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
+ g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
break;
}
}
return(he);
}
-int ioctlsocket(WapiHandle *handle, gint32 command, gpointer arg)
+int
+WSAIoctl (guint32 fd, gint32 command,
+ gchar *input, gint i_len,
+ gchar *output, gint o_len, glong *written,
+ void *unused1, void *unused2)
+{
+ gpointer handle = GUINT_TO_POINTER (fd);
+ int ret;
+ gchar *buffer = NULL;
+
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
+ return(SOCKET_ERROR);
+ }
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (i_len > 0) {
+ buffer = g_memdup (input, i_len);
+ }
+
+ ret = ioctl (fd, command, buffer);
+ if (ret == -1) {
+ gint errnum = errno;
+#ifdef DEBUG
+ g_message("%s: WSAIoctl error: %s", __func__,
+ strerror (errno));
+#endif
+
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
+ g_free (buffer);
+
+ return(SOCKET_ERROR);
+ }
+
+ if (buffer == NULL) {
+ *written = 0;
+ } else {
+ /* We just copy the buffer to the output. Some ioctls
+ * don't even output any data, but, well...
+ */
+ i_len = (i_len > o_len) ? o_len : i_len;
+ memcpy (output, buffer, i_len);
+ g_free (buffer);
+ *written = i_len;
+ }
+
+ return(0);
+}
+
+int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- if(handle->type!=WAPI_HANDLE_SOCKET) {
- WSASetLastError(WSAENOTSOCK);
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
- if(command!=FIONBIO &&
- command!=FIONREAD &&
- command!=SIOCATMARK) {
+ if (command != FIONBIO &&
+ command != FIONREAD &&
+ command != SIOCATMARK) {
/* Not listed in the MSDN specs, but ioctl(2) returns
* this if command is invalid
*/
- WSASetLastError(WSAEINVAL);
+ WSASetLastError (WSAEINVAL);
return(SOCKET_ERROR);
}
- ret=ioctl(socket_handle->fd, command, arg);
- if(ret==-1) {
+#ifdef O_NONBLOCK
+ /* This works better than ioctl(...FIONBIO...) on Linux (it causes
+ * connect to return EINPROGRESS, but the ioctl doesn't seem to)
+ */
+ if (command == FIONBIO) {
+ ret = fcntl (fd, F_GETFL, 0);
+ if (ret != -1) {
+ if (*(gboolean *)arg) {
+ ret |= O_NONBLOCK;
+ } else {
+ ret &= ~O_NONBLOCK;
+ }
+ ret = fcntl (fd, F_SETFL, ret);
+ }
+ } else
+#endif /* O_NONBLOCK */
+ {
+ ret = ioctl (fd, command, arg);
+ }
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": ioctl error: %s",
- strerror(errno));
+ g_message ("%s: ioctl error: %s", __func__, strerror (errno));
#endif
- switch(errno) {
- case ENOTTY:
- case EBADF:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EFAULT:
- WSASetLastError(WSAEFAULT);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
{
int ret;
- if(startup_count==0) {
- WSASetLastError(WSANOTINITIALISED);
+ if (startup_count == 0) {
+ WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
}
- ret=select(getdtablesize(), readfds, writefds, exceptfds, timeout);
- if(ret==-1) {
+ do {
+ ret = select(getdtablesize (), readfds, writefds, exceptfds,
+ timeout);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending ());
+
+ if (ret == -1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": select error: %s",
- strerror(errno));
+ g_message ("%s: select error: %s", __func__, strerror (errno));
#endif
- switch(errno) {
- case EBADF:
- WSASetLastError(WSAENOTSOCK);
- break;
- case EINTR:
- WSASetLastError(WSAEINTR);
- break;
- case EINVAL:
- WSASetLastError(WSAEINVAL);
- break;
- case ENOMEM:
- WSASetLastError(WSAEFAULT);
- break;
- default:
- g_warning(G_GNUC_PRETTY_FUNCTION ": Need to translate [%s] into winsock error", strerror(errno));
- break;
- }
+ errnum = errno_to_WSA (errnum, __func__);
+ WSASetLastError (errnum);
return(SOCKET_ERROR);
}
return(ret);
}
-void _wapi_FD_CLR(WapiHandle *handle, fd_set *set)
+void _wapi_FD_CLR(guint32 fd, fd_set *set)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return;
+ }
- FD_CLR(socket_handle->fd, set);
+ FD_CLR (fd, set);
}
-int _wapi_FD_ISSET(WapiHandle *handle, fd_set *set)
+int _wapi_FD_ISSET(guint32 fd, fd_set *set)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(0);
+ }
- return(FD_ISSET(socket_handle->fd, set));
+ return(FD_ISSET (fd, set));
}
-void _wapi_FD_SET(WapiHandle *handle, fd_set *set)
+void _wapi_FD_SET(guint32 fd, fd_set *set)
{
- struct _WapiHandle_socket *socket_handle=(struct _WapiHandle_socket *)handle;
+ gpointer handle = GUINT_TO_POINTER (fd);
+
+ if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return;
+ }
- FD_SET(socket_handle->fd, set);
+ FD_SET (fd, set);
}