2 * sockets.c: Socket handles
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/ioctl.h>
19 #ifdef HAVE_SYS_FILIO_H
20 #include <sys/filio.h> /* defines FIONBIO and FIONREAD */
22 #ifdef HAVE_SYS_SOCKIO_H
23 #include <sys/sockio.h> /* defines SIOCATMARK */
28 #ifndef HAVE_MSG_NOSIGNAL
32 #include <mono/io-layer/wapi.h>
33 #include <mono/io-layer/wapi-private.h>
34 #include <mono/io-layer/socket-private.h>
35 #include <mono/io-layer/handles-private.h>
36 #include <mono/io-layer/socket-wrappers.h>
40 static guint32 startup_count=0;
41 static pthread_key_t error_key;
42 static mono_once_t error_key_once=MONO_ONCE_INIT;
44 static void socket_close (gpointer handle, gpointer data);
46 struct _WapiHandleOps _wapi_socket_ops = {
47 socket_close, /* close */
51 NULL, /* special_wait */
55 static mono_once_t socket_ops_once=MONO_ONCE_INIT;
57 static void socket_ops_init (void)
59 /* No capabilities to register */
62 static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED)
67 g_message ("%s: closing socket handle %p", __func__, handle);
70 if (startup_count == 0) {
71 WSASetLastError (WSANOTINITIALISED);
76 ret = close (GPOINTER_TO_UINT(handle));
77 } while (ret == -1 && errno == EINTR &&
78 !_wapi_thread_cur_apc_pending ());
83 g_message ("%s: close error: %s", __func__, strerror (errno));
85 errnum = errno_to_WSA (errnum, __func__);
86 WSASetLastError (errnum);
90 int WSAStartup(guint32 requested, WapiWSAData *data)
97 if (requested < MAKEWORD(2,0)) {
98 return(WSAVERNOTSUPPORTED);
103 /* I've no idea what is the minor version of the spec I read */
104 data->wHighVersion = MAKEWORD(2,2);
106 data->wVersion = requested < data->wHighVersion? requested:
110 g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
113 strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
114 strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
120 cleanup_close (gpointer handle, gpointer data)
122 _wapi_handle_ops_close (handle, NULL);
129 g_message ("%s: cleaning up", __func__);
132 if (--startup_count) {
137 _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
141 static void error_init(void)
145 ret = pthread_key_create (&error_key, NULL);
149 void WSASetLastError(int error)
153 mono_once (&error_key_once, error_init);
154 ret = pthread_setspecific (error_key, GINT_TO_POINTER(error));
158 int WSAGetLastError(void)
163 mono_once (&error_key_once, error_init);
164 errptr = pthread_getspecific (error_key);
165 err = GPOINTER_TO_INT(errptr);
170 int closesocket(guint32 fd)
172 gpointer handle = GUINT_TO_POINTER (fd);
174 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
175 WSASetLastError (WSAENOTSOCK);
179 _wapi_handle_unref (handle);
183 guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
185 gpointer handle = GUINT_TO_POINTER (fd);
189 if (startup_count == 0) {
190 WSASetLastError (WSANOTINITIALISED);
191 return(INVALID_SOCKET);
194 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
195 WSASetLastError (WSAENOTSOCK);
196 return(INVALID_SOCKET);
200 new_fd = accept (fd, addr, addrlen);
201 } while (new_fd == -1 && errno == EINTR &&
202 !_wapi_thread_cur_apc_pending());
207 g_message ("%s: accept error: %s", __func__, strerror(errno));
210 errnum = errno_to_WSA (errnum, __func__);
211 WSASetLastError (errnum);
213 return(INVALID_SOCKET);
216 if (new_fd >= _wapi_fd_reserve) {
218 g_message ("%s: File descriptor is too big", __func__);
221 WSASetLastError (WSASYSCALLFAILURE);
225 return(INVALID_SOCKET);
228 new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd, NULL);
229 if(new_handle == _WAPI_HANDLE_INVALID) {
230 g_warning ("%s: error creating socket handle", __func__);
231 WSASetLastError (ERROR_GEN_FAILURE);
232 return(INVALID_SOCKET);
236 g_message ("%s: returning newly accepted socket handle %p with",
237 __func__, new_handle);
243 int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
245 gpointer handle = GUINT_TO_POINTER (fd);
248 if (startup_count == 0) {
249 WSASetLastError (WSANOTINITIALISED);
250 return(SOCKET_ERROR);
253 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
254 WSASetLastError (WSAENOTSOCK);
255 return(SOCKET_ERROR);
258 ret = bind (fd, my_addr, addrlen);
262 g_message ("%s: bind error: %s", __func__, strerror(errno));
264 errnum = errno_to_WSA (errnum, __func__);
265 WSASetLastError (errnum);
267 return(SOCKET_ERROR);
272 int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
275 gpointer handle = GUINT_TO_POINTER (fd);
276 struct _WapiHandle_socket *socket_handle;
280 if (startup_count == 0) {
281 WSASetLastError (WSANOTINITIALISED);
282 return(SOCKET_ERROR);
285 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
286 WSASetLastError (WSAENOTSOCK);
287 return(SOCKET_ERROR);
290 if (connect (fd, serv_addr, addrlen) == -1) {
297 if (errno != EINTR) {
299 g_message ("%s: connect error: %s", __func__,
303 errnum = errno_to_WSA (errnum, __func__);
304 if (errnum == WSAEINPROGRESS)
305 errnum = WSAEWOULDBLOCK; /* see bug #73053 */
307 WSASetLastError (errnum);
309 return(SOCKET_ERROR);
313 fds.events = POLLOUT;
314 while (poll (&fds, 1, -1) == -1 &&
315 !_wapi_thread_cur_apc_pending ()) {
316 if (errno != EINTR) {
317 errnum = errno_to_WSA (errno, __func__);
320 g_message ("%s: connect poll error: %s",
321 __func__, strerror (errno));
324 WSASetLastError (errnum);
325 return(SOCKET_ERROR);
329 len = sizeof(so_error);
330 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &so_error,
332 errnum = errno_to_WSA (errno, __func__);
335 g_message ("%s: connect getsockopt error: %s",
336 __func__, strerror (errno));
339 WSASetLastError (errnum);
340 return(SOCKET_ERROR);
344 errnum = errno_to_WSA (so_error, __func__);
346 /* Need to save this socket error */
347 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
348 (gpointer *)&socket_handle);
350 g_warning ("%s: error looking up socket handle %p", __func__, handle);
352 socket_handle->saved_error = errnum;
356 g_message ("%s: connect getsockopt returned error: %s",
357 __func__, strerror (so_error));
360 WSASetLastError (errnum);
361 return(SOCKET_ERROR);
368 int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
370 gpointer handle = GUINT_TO_POINTER (fd);
373 if (startup_count == 0) {
374 WSASetLastError (WSANOTINITIALISED);
375 return(SOCKET_ERROR);
378 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
379 WSASetLastError (WSAENOTSOCK);
380 return(SOCKET_ERROR);
383 ret = getpeername (fd, name, namelen);
387 g_message ("%s: getpeername error: %s", __func__,
391 errnum = errno_to_WSA (errnum, __func__);
392 WSASetLastError (errnum);
394 return(SOCKET_ERROR);
400 int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
402 gpointer handle = GUINT_TO_POINTER (fd);
405 if (startup_count == 0) {
406 WSASetLastError (WSANOTINITIALISED);
407 return(SOCKET_ERROR);
410 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
411 WSASetLastError (WSAENOTSOCK);
412 return(SOCKET_ERROR);
415 ret = getsockname (fd, name, namelen);
419 g_message ("%s: getsockname error: %s", __func__,
423 errnum = errno_to_WSA (errnum, __func__);
424 WSASetLastError (errnum);
426 return(SOCKET_ERROR);
432 int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
435 gpointer handle = GUINT_TO_POINTER (fd);
439 struct _WapiHandle_socket *socket_handle;
442 if (startup_count == 0) {
443 WSASetLastError (WSANOTINITIALISED);
444 return(SOCKET_ERROR);
447 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
448 WSASetLastError (WSAENOTSOCK);
449 return(SOCKET_ERROR);
453 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
455 *optlen = sizeof (tv);
458 ret = getsockopt (fd, level, optname, tmp_val, optlen);
462 g_message ("%s: getsockopt error: %s", __func__,
466 errnum = errno_to_WSA (errnum, __func__);
467 WSASetLastError (errnum);
469 return(SOCKET_ERROR);
472 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
473 *((int *) optval) = tv.tv_sec * 1000 + (tv.tv_usec / 1000); // milli from micro
474 *optlen = sizeof (int);
477 if (optname == SO_ERROR) {
478 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
479 (gpointer *)&socket_handle);
481 g_warning ("%s: error looking up socket handle %p",
484 /* can't extract the last error */
485 *((int *) optval) = errno_to_WSA (*((int *)optval),
488 if (*((int *)optval) != 0) {
489 *((int *) optval) = errno_to_WSA (*((int *)optval),
491 socket_handle->saved_error = *((int *)optval);
493 *((int *)optval) = socket_handle->saved_error;
501 int _wapi_listen(guint32 fd, int backlog)
503 gpointer handle = GUINT_TO_POINTER (fd);
506 if (startup_count == 0) {
507 WSASetLastError (WSANOTINITIALISED);
508 return(SOCKET_ERROR);
511 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
512 WSASetLastError (WSAENOTSOCK);
513 return(SOCKET_ERROR);
516 ret = listen (fd, backlog);
520 g_message ("%s: listen error: %s", __func__, strerror (errno));
523 errnum = errno_to_WSA (errnum, __func__);
524 WSASetLastError (errnum);
526 return(SOCKET_ERROR);
532 int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
534 return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0));
537 int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
538 struct sockaddr *from, socklen_t *fromlen)
540 gpointer handle = GUINT_TO_POINTER (fd);
543 if (startup_count == 0) {
544 WSASetLastError (WSANOTINITIALISED);
545 return(SOCKET_ERROR);
548 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
549 WSASetLastError (WSAENOTSOCK);
550 return(SOCKET_ERROR);
554 ret = recvfrom (fd, buf, len, recv_flags, from, fromlen);
555 } while (ret == -1 && errno == EINTR &&
556 !_wapi_thread_cur_apc_pending ());
561 g_message ("%s: recv error: %s", __func__, strerror(errno));
564 errnum = errno_to_WSA (errnum, __func__);
565 WSASetLastError (errnum);
567 return(SOCKET_ERROR);
572 int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
574 gpointer handle = GUINT_TO_POINTER (fd);
577 if (startup_count == 0) {
578 WSASetLastError (WSANOTINITIALISED);
579 return(SOCKET_ERROR);
582 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
583 WSASetLastError (WSAENOTSOCK);
584 return(SOCKET_ERROR);
588 ret = send (fd, msg, len, send_flags);
589 } while (ret == -1 && errno == EINTR &&
590 !_wapi_thread_cur_apc_pending ());
595 g_message ("%s: send error: %s", __func__, strerror (errno));
598 errnum = errno_to_WSA (errnum, __func__);
599 WSASetLastError (errnum);
601 return(SOCKET_ERROR);
606 int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
607 const struct sockaddr *to, socklen_t tolen)
609 gpointer handle = GUINT_TO_POINTER (fd);
612 if (startup_count == 0) {
613 WSASetLastError (WSANOTINITIALISED);
614 return(SOCKET_ERROR);
617 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
618 WSASetLastError (WSAENOTSOCK);
619 return(SOCKET_ERROR);
623 ret = sendto (fd, msg, len, send_flags, to, tolen);
624 } while (ret == -1 && errno == EINTR &&
625 !_wapi_thread_cur_apc_pending ());
630 g_message ("%s: send error: %s", __func__, strerror (errno));
633 errnum = errno_to_WSA (errnum, __func__);
634 WSASetLastError (errnum);
636 return(SOCKET_ERROR);
641 int _wapi_setsockopt(guint32 fd, int level, int optname,
642 const void *optval, socklen_t optlen)
644 gpointer handle = GUINT_TO_POINTER (fd);
649 if (startup_count == 0) {
650 WSASetLastError (WSANOTINITIALISED);
651 return(SOCKET_ERROR);
654 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
655 WSASetLastError (WSAENOTSOCK);
656 return(SOCKET_ERROR);
660 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
661 int ms = *((int *) optval);
662 tv.tv_sec = ms / 1000;
663 tv.tv_usec = (ms % 1000) * 1000; // micro from milli
665 optlen = sizeof (tv);
666 #if defined (__linux__)
667 } else if (optname == SO_SNDBUF || optname == SO_RCVBUF) {
668 /* According to socket(7) the Linux kernel doubles the
669 * buffer sizes "to allow space for bookkeeping
672 int bufsize = *((int *) optval);
679 ret = setsockopt (fd, level, optname, tmp_val, optlen);
683 g_message ("%s: setsockopt error: %s", __func__,
687 errnum = errno_to_WSA (errnum, __func__);
688 WSASetLastError (errnum);
690 return(SOCKET_ERROR);
696 int _wapi_shutdown(guint32 fd, int how)
698 gpointer handle = GUINT_TO_POINTER (fd);
701 if (startup_count == 0) {
702 WSASetLastError (WSANOTINITIALISED);
703 return(SOCKET_ERROR);
706 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
707 WSASetLastError (WSAENOTSOCK);
708 return(SOCKET_ERROR);
711 ret = shutdown (fd, how);
715 g_message ("%s: shutdown error: %s", __func__,
719 errnum = errno_to_WSA (errnum, __func__);
720 WSASetLastError (errnum);
722 return(SOCKET_ERROR);
728 guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
729 guint32 unused2, guint32 unused3)
731 struct _WapiHandle_socket socket_handle = {0};
735 socket_handle.domain = domain;
736 socket_handle.type = type;
737 socket_handle.protocol = protocol;
739 fd = socket (domain, type, protocol);
740 if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
742 /* Retry with protocol == 4 (see bug #54565) */
743 socket_handle.protocol = 4;
744 fd = socket (AF_INET, SOCK_RAW, 4);
750 g_message ("%s: socket error: %s", __func__, strerror (errno));
752 errnum = errno_to_WSA (errnum, __func__);
753 WSASetLastError (errnum);
755 return(INVALID_SOCKET);
758 if (fd >= _wapi_fd_reserve) {
760 g_message ("%s: File descriptor is too big (%d >= %d)",
761 __func__, fd, _wapi_fd_reserve);
764 WSASetLastError (WSASYSCALLFAILURE);
767 return(INVALID_SOCKET);
771 mono_once (&socket_ops_once, socket_ops_init);
773 handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
774 if (handle == _WAPI_HANDLE_INVALID) {
775 g_warning ("%s: error creating socket handle", __func__);
776 return(INVALID_SOCKET);
780 g_message ("%s: returning socket handle %p", __func__, handle);
786 struct hostent *_wapi_gethostbyname(const char *hostname)
790 if (startup_count == 0) {
791 WSASetLastError (WSANOTINITIALISED);
795 he = gethostbyname (hostname);
798 g_message ("%s: gethostbyname error: %s", __func__,
804 WSASetLastError (WSAHOST_NOT_FOUND);
806 #if NO_ADDRESS != NO_DATA
810 WSASetLastError (WSANO_DATA);
813 WSASetLastError (WSANO_RECOVERY);
816 WSASetLastError (WSATRY_AGAIN);
819 g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
827 static gboolean socket_disconnect (guint32 fd)
829 struct _WapiHandle_socket *socket_handle;
831 gpointer handle = GUINT_TO_POINTER (fd);
834 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
835 (gpointer *)&socket_handle);
837 g_warning ("%s: error looking up socket handle %p", __func__,
839 WSASetLastError (WSAENOTSOCK);
843 newsock = socket (socket_handle->domain, socket_handle->type,
844 socket_handle->protocol);
849 g_message ("%s: socket error: %s", __func__, strerror (errno));
852 errnum = errno_to_WSA (errnum, __func__);
853 WSASetLastError (errnum);
858 /* According to Stevens "Advanced Programming in the UNIX
859 * Environment: UNIX File I/O" dup2() is atomic so there
860 * should not be a race condition between the old fd being
861 * closed and the new socket fd being copied over
864 ret = dup2 (newsock, fd);
865 } while (ret == -1 && errno == EAGAIN);
871 g_message ("%s: dup2 error: %s", __func__, strerror (errno));
874 errnum = errno_to_WSA (errnum, __func__);
875 WSASetLastError (errnum);
885 static gboolean wapi_disconnectex (guint32 fd, WapiOverlapped *overlapped,
886 guint32 flags, guint32 reserved)
889 g_message ("%s: called on socket %d!", __func__, fd);
893 WSASetLastError (WSAEINVAL);
897 /* We could check the socket type here and fail unless its
898 * SOCK_STREAM, SOCK_SEQPACKET or SOCK_RDM (according to msdn)
899 * if we really wanted to
902 return(socket_disconnect (fd));
905 /* NB only supports NULL file handle, NULL buffers and
906 * TF_DISCONNECT|TF_REUSE_SOCKET flags to disconnect the socket fd.
907 * Shouldn't actually ever need to be called anyway though, because we
908 * have DisconnectEx ().
910 static gboolean wapi_transmitfile (guint32 fd, gpointer file,
911 guint32 num_write, guint32 num_per_send,
912 WapiOverlapped *overlapped,
913 WapiTransmitFileBuffers *buffers,
914 WapiTransmitFileFlags flags)
917 g_message ("%s: called on socket %d!", __func__, fd);
920 g_assert (file == NULL);
921 g_assert (overlapped == NULL);
922 g_assert (buffers == NULL);
923 g_assert (num_write == 0);
924 g_assert (num_per_send == 0);
925 g_assert (flags == (TF_DISCONNECT | TF_REUSE_SOCKET));
927 return(socket_disconnect (fd));
934 } extension_functions[] = {
935 {WSAID_DISCONNECTEX, wapi_disconnectex},
936 {WSAID_TRANSMITFILE, wapi_transmitfile},
941 WSAIoctl (guint32 fd, gint32 command,
942 gchar *input, gint i_len,
943 gchar *output, gint o_len, glong *written,
944 void *unused1, void *unused2)
946 gpointer handle = GUINT_TO_POINTER (fd);
948 gchar *buffer = NULL;
950 if (startup_count == 0) {
951 WSASetLastError (WSANOTINITIALISED);
952 return(SOCKET_ERROR);
955 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
956 WSASetLastError (WSAENOTSOCK);
960 if (command == SIO_GET_EXTENSION_FUNCTION_POINTER) {
962 WapiGuid *guid = (WapiGuid *)input;
964 if (i_len < sizeof(WapiGuid)) {
965 /* As far as I can tell, windows doesn't
966 * actually set an error here...
968 WSASetLastError (WSAEINVAL);
969 return(SOCKET_ERROR);
972 if (o_len < sizeof(gpointer)) {
974 WSASetLastError (WSAEINVAL);
975 return(SOCKET_ERROR);
978 if (output == NULL) {
980 WSASetLastError (WSAEINVAL);
981 return(SOCKET_ERROR);
984 while(extension_functions[i].func != NULL) {
985 if (!memcmp (guid, &extension_functions[i].guid,
987 memcpy (output, &extension_functions[i].func,
989 *written = sizeof(gpointer);
996 WSASetLastError (WSAEINVAL);
997 return(SOCKET_ERROR);
1001 buffer = g_memdup (input, i_len);
1004 ret = ioctl (fd, command, buffer);
1006 gint errnum = errno;
1008 g_message("%s: WSAIoctl error: %s", __func__,
1012 errnum = errno_to_WSA (errnum, __func__);
1013 WSASetLastError (errnum);
1016 return(SOCKET_ERROR);
1019 if (buffer == NULL) {
1022 /* We just copy the buffer to the output. Some ioctls
1023 * don't even output any data, but, well...
1025 * NB windows returns WSAEFAULT if o_len is too small
1027 i_len = (i_len > o_len) ? o_len : i_len;
1029 if (i_len > 0 && output != NULL) {
1030 memcpy (output, buffer, i_len);
1040 int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
1042 gpointer handle = GUINT_TO_POINTER (fd);
1045 if (startup_count == 0) {
1046 WSASetLastError (WSANOTINITIALISED);
1047 return(SOCKET_ERROR);
1050 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1051 WSASetLastError (WSAENOTSOCK);
1052 return(SOCKET_ERROR);
1058 /* This works better than ioctl(...FIONBIO...)
1059 * on Linux (it causes connect to return
1060 * EINPROGRESS, but the ioctl doesn't seem to)
1062 ret = fcntl(fd, F_GETFL, 0);
1064 if (*(gboolean *)arg) {
1069 ret = fcntl(fd, F_SETFL, ret);
1072 #endif /* O_NONBLOCK */
1075 ret = ioctl (fd, command, arg);
1078 WSASetLastError (WSAEINVAL);
1079 return(SOCKET_ERROR);
1083 gint errnum = errno;
1085 g_message ("%s: ioctl error: %s", __func__, strerror (errno));
1088 errnum = errno_to_WSA (errnum, __func__);
1089 WSASetLastError (errnum);
1091 return(SOCKET_ERROR);
1097 int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
1098 fd_set *exceptfds, struct timeval *timeout)
1102 if (startup_count == 0) {
1103 WSASetLastError (WSANOTINITIALISED);
1104 return(SOCKET_ERROR);
1107 for (maxfd = FD_SETSIZE-1; maxfd >= 0; maxfd--) {
1108 if ((readfds && FD_ISSET (maxfd, readfds)) ||
1109 (writefds && FD_ISSET (maxfd, writefds)) ||
1110 (exceptfds && FD_ISSET (maxfd, exceptfds))) {
1116 WSASetLastError (WSAEINVAL);
1117 return(SOCKET_ERROR);
1121 ret = select(maxfd + 1, readfds, writefds, exceptfds,
1123 } while (ret == -1 && errno == EINTR &&
1124 !_wapi_thread_cur_apc_pending ());
1127 gint errnum = errno;
1129 g_message ("%s: select error: %s", __func__, strerror (errno));
1131 errnum = errno_to_WSA (errnum, __func__);
1132 WSASetLastError (errnum);
1134 return(SOCKET_ERROR);
1140 void _wapi_FD_CLR(guint32 fd, fd_set *set)
1142 gpointer handle = GUINT_TO_POINTER (fd);
1144 if (fd >= FD_SETSIZE) {
1145 WSASetLastError (WSAEINVAL);
1149 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1150 WSASetLastError (WSAENOTSOCK);
1157 int _wapi_FD_ISSET(guint32 fd, fd_set *set)
1159 gpointer handle = GUINT_TO_POINTER (fd);
1161 if (fd >= FD_SETSIZE) {
1162 WSASetLastError (WSAEINVAL);
1166 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1167 WSASetLastError (WSAENOTSOCK);
1171 return(FD_ISSET (fd, set));
1174 void _wapi_FD_SET(guint32 fd, fd_set *set)
1176 gpointer handle = GUINT_TO_POINTER (fd);
1178 if (fd >= FD_SETSIZE) {
1179 WSASetLastError (WSAEINVAL);
1183 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1184 WSASetLastError (WSAENOTSOCK);