X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fio-layer%2Fsockets.c;h=b2cf55faf211c4398f153bba7e86636c7d907b4a;hb=a6bce082e4da5a3f144b7ae8974819a88efb6817;hp=399c40a68445d99c6c5bfbb14ac23b691c441a0b;hpb=932312e171711a945bfa07629101cecb31a08fbb;p=mono.git diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c index 399c40a6844..b2cf55faf21 100644 --- a/mono/io-layer/sockets.c +++ b/mono/io-layer/sockets.c @@ -22,116 +22,134 @@ #include /* defines SIOCATMARK */ #endif #include +#include + +#ifndef HAVE_MSG_NOSIGNAL +#include +#endif #include #include #include #include +#include #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_private (gpointer handle); +static void socket_close (gpointer handle, gpointer data); struct _WapiHandleOps _wapi_socket_ops = { - NULL, /* close_shared */ - socket_close_private, /* close_private */ + socket_close, /* close */ NULL, /* signal */ NULL, /* own */ NULL, /* is_owned */ }; -static pthread_once_t socket_ops_once=PTHREAD_ONCE_INIT; +static mono_once_t socket_ops_once=MONO_ONCE_INIT; static void socket_ops_init (void) { /* No capabilities to register */ } -static void socket_close_private (gpointer handle) +static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED) { + int ret; + #ifdef DEBUG - g_message(G_GNUC_PRETTY_FUNCTION ": closing socket handle 0x%x", - handle); + g_message ("%s: closing socket handle %p", __func__, handle); #endif - closesocket(GPOINTER_TO_UINT (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; ilen; i++) { - gpointer handle; - - handle=g_ptr_array_index(sockets, i); - _wapi_handle_ops_close_private (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) @@ -139,358 +157,197 @@ 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(guint32 handle) +int closesocket(guint32 fd) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; - int ret; - - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); - return(SOCKET_ERROR); - } + gpointer handle = GUINT_TO_POINTER (fd); - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); - return(SOCKET_ERROR); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); + return(0); } - g_ptr_array_remove_fast(sockets, GUINT_TO_POINTER (handle)); - - ret=close(socket_private_handle->fd); - if(ret==-1) { -#ifdef DEBUG - g_message(G_GNUC_PRETTY_FUNCTION ": close error: %s", - 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; - } - - return(SOCKET_ERROR); - } - return(ret); + _wapi_handle_unref (handle); + return(0); } -guint32 _wapi_accept(guint32 handle, struct sockaddr *addr, - socklen_t *addrlen) +guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - struct _WapiHandlePrivate_socket *new_socket_private_handle; + gpointer handle = GUINT_TO_POINTER (fd); gpointer new_handle; - gboolean ok; - int fd; + int new_fd; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(INVALID_SOCKET); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(INVALID_SOCKET); } - fd=accept(socket_private_handle->fd, addr, addrlen); - if(fd==-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 ": accept error: %s", - strerror(errno)); + g_message ("%s: accept error: %s", __func__, strerror(errno)); #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; -#ifdef ENOSR - case ENOSR: -#endif - 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; - } + errnum = errno_to_WSA (errnum, __func__); + WSASetLastError (errnum); return(INVALID_SOCKET); } - new_handle=_wapi_handle_new (WAPI_HANDLE_SOCKET); - if(new_handle==_WAPI_HANDLE_INVALID) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error creating socket handle"); + if (new_fd >= _wapi_fd_reserve) { +#ifdef DEBUG + g_message ("%s: File descriptor is too big", __func__); +#endif + + WSASetLastError (WSASYSCALLFAILURE); + + close (new_fd); + return(INVALID_SOCKET); } - _wapi_handle_lock_handle (new_handle); - - ok=_wapi_lookup_handle (new_handle, WAPI_HANDLE_SOCKET, NULL, - (gpointer *)&new_socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - _wapi_handle_unlock_handle (new_handle); + 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); } - - new_socket_private_handle->fd=fd; - + #ifdef DEBUG - g_message(G_GNUC_PRETTY_FUNCTION - ": returning newly accepted socket handle %p with fd %d", - new_handle, new_socket_private_handle->fd); + g_message ("%s: returning newly accepted socket handle %p with", + __func__, new_handle); #endif - - _wapi_handle_unlock_handle (new_handle); - - return(GPOINTER_TO_UINT (new_handle)); + + return(new_fd); } -int _wapi_bind(guint32 handle, struct sockaddr *my_addr, socklen_t addrlen) +int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=bind(socket_private_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 EADDRINUSE: - WSASetLastError(WSAEADDRINUSE); - 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(guint32 handle, const struct sockaddr *serv_addr, +int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr, socklen_t addrlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + 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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=connect(socket_private_handle->fd, serv_addr, addrlen); - if(ret==-1) { + 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(guint32 handle, struct sockaddr *name, - socklen_t *namelen) +int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=getpeername(socket_private_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); } @@ -498,50 +355,31 @@ int _wapi_getpeername(guint32 handle, struct sockaddr *name, return(ret); } -int _wapi_getsockname(guint32 handle, struct sockaddr *name, - socklen_t *namelen) +int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=getsockname(socket_private_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); } @@ -549,99 +387,76 @@ int _wapi_getsockname(guint32 handle, struct sockaddr *name, return(ret); } -int _wapi_getsockopt(guint32 handle, int level, int optname, void *optval, +int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval, socklen_t *optlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + 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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - - ret=getsockopt(socket_private_handle->fd, level, optname, optval, - optlen); - if(ret==-1) { + + 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(guint32 handle, int backlog) +int _wapi_listen(guint32 fd, int backlog) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=listen(socket_private_handle->fd, backlog); - if(ret==-1) { + 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); } @@ -649,253 +464,188 @@ int _wapi_listen(guint32 handle, int backlog) return(0); } -int _wapi_recv(guint32 handle, void *buf, size_t len, int recv_flags) +int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags) { - return(_wapi_recvfrom(handle, buf, len, recv_flags, NULL, 0)); + return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0)); } -int _wapi_recvfrom(guint32 handle, void *buf, size_t len, int recv_flags, +int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags, struct sockaddr *from, socklen_t *fromlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; +#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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=recvfrom(socket_private_handle->fd, buf, len, recv_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(guint32 handle, const void *msg, size_t len, int send_flags) +int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; +#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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - - ret=send(socket_private_handle->fd, msg, len, send_flags); - if(ret==-1) { + +#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(guint32 handle, const void *msg, size_t len, int send_flags, +int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags, const struct sockaddr *to, socklen_t tolen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; +#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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=sendto(socket_private_handle->fd, msg, len, send_flags, to, tolen); - if(ret==-1) { +#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(guint32 handle, int level, int optname, +int _wapi_setsockopt(guint32 fd, int level, int optname, const void *optval, socklen_t optlen) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + 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); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - - ret=setsockopt(socket_private_handle->fd, level, optname, optval, - optlen); - if(ret==-1) { + + 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); } @@ -903,45 +653,31 @@ int _wapi_setsockopt(guint32 handle, int level, int optname, return(ret); } -int _wapi_shutdown(guint32 handle, int how) +int _wapi_shutdown(guint32 fd, int how) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(SOCKET_ERROR); } - ret=shutdown(socket_private_handle->fd, how); - if(ret==-1) { + 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); } @@ -949,89 +685,91 @@ int _wapi_shutdown(guint32 handle, int how) return(ret); } -guint32 _wapi_socket(int domain, int type, int protocol) +guint32 _wapi_socket(int domain, int type, int protocol, void *unused, + guint32 unused2, guint32 unused3) { - struct _WapiHandlePrivate_socket *socket_private_handle; gpointer handle; - gboolean ok; 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); } - - pthread_once (&socket_ops_once, socket_ops_init); - - handle=_wapi_handle_new (WAPI_HANDLE_SOCKET); - if(handle==_WAPI_HANDLE_INVALID) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error creating socket handle"); - return(INVALID_SOCKET); - } - _wapi_handle_lock_handle (handle); - - ok=_wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET, NULL, - (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle %p", handle); - _wapi_handle_unlock_handle (handle); + 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_private_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_private_handle->fd); + g_message ("%s: returning socket handle %p", __func__, handle); #endif - _wapi_handle_unlock_handle (handle); - - return(GPOINTER_TO_UINT (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; } } @@ -1039,57 +777,112 @@ struct hostent *_wapi_gethostbyname(const char *hostname) return(he); } -int ioctlsocket(guint32 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 _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); int ret; - if(startup_count==0) { - WSASetLastError(WSANOTINITIALISED); + if (startup_count == 0) { + WSASetLastError (WSANOTINITIALISED); return(SOCKET_ERROR); } - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - 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); - return(SOCKET_ERROR); + WSASetLastError (WSAEINVAL); + return(SOCKET_ERROR); + } + +#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); } - - ret=ioctl(socket_private_handle->fd, command, arg); - if(ret==-1) { + 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); } @@ -1102,34 +895,24 @@ int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds, { 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); } @@ -1137,54 +920,39 @@ int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds, return(ret); } -void _wapi_FD_CLR(guint32 handle, fd_set *set) +void _wapi_FD_CLR(guint32 fd, fd_set *set) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return; } - FD_CLR(socket_private_handle->fd, set); + FD_CLR (fd, set); } -int _wapi_FD_ISSET(guint32 handle, fd_set *set) +int _wapi_FD_ISSET(guint32 fd, fd_set *set) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return(0); } - return(FD_ISSET(socket_private_handle->fd, set)); + return(FD_ISSET (fd, set)); } -void _wapi_FD_SET(guint32 handle, fd_set *set) +void _wapi_FD_SET(guint32 fd, fd_set *set) { - struct _WapiHandlePrivate_socket *socket_private_handle; - gboolean ok; + gpointer handle = GUINT_TO_POINTER (fd); - ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET, - NULL, (gpointer *)&socket_private_handle); - if(ok==FALSE) { - g_warning (G_GNUC_PRETTY_FUNCTION - ": error looking up socket handle 0x%x", handle); - WSASetLastError(WSAENOTSOCK); + if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + WSASetLastError (WSAENOTSOCK); return; } - FD_SET(socket_private_handle->fd, set); + FD_SET (fd, set); }