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);
75 /* Shutdown the socket for reading, to interrupt any potential
76 * receives that may be blocking for data. See bug 75705.
78 shutdown (GPOINTER_TO_UINT (handle), SHUT_RD);
81 ret = close (GPOINTER_TO_UINT(handle));
82 } while (ret == -1 && errno == EINTR &&
83 !_wapi_thread_cur_apc_pending ());
88 g_message ("%s: close error: %s", __func__, strerror (errno));
90 errnum = errno_to_WSA (errnum, __func__);
91 WSASetLastError (errnum);
95 int WSAStartup(guint32 requested, WapiWSAData *data)
101 /* Insist on v2.0+ */
102 if (requested < MAKEWORD(2,0)) {
103 return(WSAVERNOTSUPPORTED);
108 /* I've no idea what is the minor version of the spec I read */
109 data->wHighVersion = MAKEWORD(2,2);
111 data->wVersion = requested < data->wHighVersion? requested:
115 g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
118 strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
119 strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
125 cleanup_close (gpointer handle, gpointer data)
127 _wapi_handle_ops_close (handle, NULL);
134 g_message ("%s: cleaning up", __func__);
137 if (--startup_count) {
142 _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
146 static void error_init(void)
150 ret = pthread_key_create (&error_key, NULL);
154 void WSASetLastError(int error)
158 mono_once (&error_key_once, error_init);
159 ret = pthread_setspecific (error_key, GINT_TO_POINTER(error));
163 int WSAGetLastError(void)
168 mono_once (&error_key_once, error_init);
169 errptr = pthread_getspecific (error_key);
170 err = GPOINTER_TO_INT(errptr);
175 int closesocket(guint32 fd)
177 gpointer handle = GUINT_TO_POINTER (fd);
179 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
180 WSASetLastError (WSAENOTSOCK);
184 _wapi_handle_unref (handle);
188 guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
190 gpointer handle = GUINT_TO_POINTER (fd);
192 struct _WapiHandle_socket *socket_handle;
193 struct _WapiHandle_socket new_socket_handle = {0};
197 if (startup_count == 0) {
198 WSASetLastError (WSANOTINITIALISED);
199 return(INVALID_SOCKET);
202 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
203 WSASetLastError (WSAENOTSOCK);
204 return(INVALID_SOCKET);
207 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
208 (gpointer *)&socket_handle);
210 g_warning ("%s: error looking up socket handle %p",
212 WSASetLastError (WSAENOTSOCK);
213 return(INVALID_SOCKET);
217 new_fd = accept (fd, addr, addrlen);
218 } while (new_fd == -1 && errno == EINTR &&
219 !_wapi_thread_cur_apc_pending());
224 g_message ("%s: accept error: %s", __func__, strerror(errno));
227 errnum = errno_to_WSA (errnum, __func__);
228 WSASetLastError (errnum);
230 return(INVALID_SOCKET);
233 if (new_fd >= _wapi_fd_reserve) {
235 g_message ("%s: File descriptor is too big", __func__);
238 WSASetLastError (WSASYSCALLFAILURE);
242 return(INVALID_SOCKET);
245 new_socket_handle.domain = socket_handle->domain;
246 new_socket_handle.type = socket_handle->type;
247 new_socket_handle.protocol = socket_handle->protocol;
248 new_socket_handle.still_readable = 1;
250 new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd,
252 if(new_handle == _WAPI_HANDLE_INVALID) {
253 g_warning ("%s: error creating socket handle", __func__);
254 WSASetLastError (ERROR_GEN_FAILURE);
255 return(INVALID_SOCKET);
259 g_message ("%s: returning newly accepted socket handle %p with",
260 __func__, new_handle);
266 int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
268 gpointer handle = GUINT_TO_POINTER (fd);
271 if (startup_count == 0) {
272 WSASetLastError (WSANOTINITIALISED);
273 return(SOCKET_ERROR);
276 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
277 WSASetLastError (WSAENOTSOCK);
278 return(SOCKET_ERROR);
281 ret = bind (fd, my_addr, addrlen);
285 g_message ("%s: bind error: %s", __func__, strerror(errno));
287 errnum = errno_to_WSA (errnum, __func__);
288 WSASetLastError (errnum);
290 return(SOCKET_ERROR);
295 int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
298 gpointer handle = GUINT_TO_POINTER (fd);
299 struct _WapiHandle_socket *socket_handle;
303 if (startup_count == 0) {
304 WSASetLastError (WSANOTINITIALISED);
305 return(SOCKET_ERROR);
308 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
309 WSASetLastError (WSAENOTSOCK);
310 return(SOCKET_ERROR);
313 if (connect (fd, serv_addr, addrlen) == -1) {
320 if (errno != EINTR) {
322 g_message ("%s: connect error: %s", __func__,
326 errnum = errno_to_WSA (errnum, __func__);
327 if (errnum == WSAEINPROGRESS)
328 errnum = WSAEWOULDBLOCK; /* see bug #73053 */
330 WSASetLastError (errnum);
332 return(SOCKET_ERROR);
336 fds.events = POLLOUT;
337 while (poll (&fds, 1, -1) == -1 &&
338 !_wapi_thread_cur_apc_pending ()) {
339 if (errno != EINTR) {
340 errnum = errno_to_WSA (errno, __func__);
343 g_message ("%s: connect poll error: %s",
344 __func__, strerror (errno));
347 WSASetLastError (errnum);
348 return(SOCKET_ERROR);
352 len = sizeof(so_error);
353 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &so_error,
355 errnum = errno_to_WSA (errno, __func__);
358 g_message ("%s: connect getsockopt error: %s",
359 __func__, strerror (errno));
362 WSASetLastError (errnum);
363 return(SOCKET_ERROR);
367 errnum = errno_to_WSA (so_error, __func__);
369 /* Need to save this socket error */
370 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
371 (gpointer *)&socket_handle);
373 g_warning ("%s: error looking up socket handle %p", __func__, handle);
375 socket_handle->saved_error = errnum;
379 g_message ("%s: connect getsockopt returned error: %s",
380 __func__, strerror (so_error));
383 WSASetLastError (errnum);
384 return(SOCKET_ERROR);
391 int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
393 gpointer handle = GUINT_TO_POINTER (fd);
396 if (startup_count == 0) {
397 WSASetLastError (WSANOTINITIALISED);
398 return(SOCKET_ERROR);
401 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
402 WSASetLastError (WSAENOTSOCK);
403 return(SOCKET_ERROR);
406 ret = getpeername (fd, name, namelen);
410 g_message ("%s: getpeername error: %s", __func__,
414 errnum = errno_to_WSA (errnum, __func__);
415 WSASetLastError (errnum);
417 return(SOCKET_ERROR);
423 int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
425 gpointer handle = GUINT_TO_POINTER (fd);
428 if (startup_count == 0) {
429 WSASetLastError (WSANOTINITIALISED);
430 return(SOCKET_ERROR);
433 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
434 WSASetLastError (WSAENOTSOCK);
435 return(SOCKET_ERROR);
438 ret = getsockname (fd, name, namelen);
442 g_message ("%s: getsockname error: %s", __func__,
446 errnum = errno_to_WSA (errnum, __func__);
447 WSASetLastError (errnum);
449 return(SOCKET_ERROR);
455 int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
458 gpointer handle = GUINT_TO_POINTER (fd);
462 struct _WapiHandle_socket *socket_handle;
465 if (startup_count == 0) {
466 WSASetLastError (WSANOTINITIALISED);
467 return(SOCKET_ERROR);
470 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
471 WSASetLastError (WSAENOTSOCK);
472 return(SOCKET_ERROR);
476 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
478 *optlen = sizeof (tv);
481 ret = getsockopt (fd, level, optname, tmp_val, optlen);
485 g_message ("%s: getsockopt error: %s", __func__,
489 errnum = errno_to_WSA (errnum, __func__);
490 WSASetLastError (errnum);
492 return(SOCKET_ERROR);
495 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
496 *((int *) optval) = tv.tv_sec * 1000 + (tv.tv_usec / 1000); // milli from micro
497 *optlen = sizeof (int);
500 if (optname == SO_ERROR) {
501 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
502 (gpointer *)&socket_handle);
504 g_warning ("%s: error looking up socket handle %p",
507 /* can't extract the last error */
508 *((int *) optval) = errno_to_WSA (*((int *)optval),
511 if (*((int *)optval) != 0) {
512 *((int *) optval) = errno_to_WSA (*((int *)optval),
514 socket_handle->saved_error = *((int *)optval);
516 *((int *)optval) = socket_handle->saved_error;
524 int _wapi_listen(guint32 fd, int backlog)
526 gpointer handle = GUINT_TO_POINTER (fd);
529 if (startup_count == 0) {
530 WSASetLastError (WSANOTINITIALISED);
531 return(SOCKET_ERROR);
534 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
535 WSASetLastError (WSAENOTSOCK);
536 return(SOCKET_ERROR);
539 ret = listen (fd, backlog);
543 g_message ("%s: listen error: %s", __func__, strerror (errno));
546 errnum = errno_to_WSA (errnum, __func__);
547 WSASetLastError (errnum);
549 return(SOCKET_ERROR);
555 int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
557 return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0));
560 int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
561 struct sockaddr *from, socklen_t *fromlen)
563 gpointer handle = GUINT_TO_POINTER (fd);
564 struct _WapiHandle_socket *socket_handle;
568 if (startup_count == 0) {
569 WSASetLastError (WSANOTINITIALISED);
570 return(SOCKET_ERROR);
573 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
574 WSASetLastError (WSAENOTSOCK);
575 return(SOCKET_ERROR);
579 ret = recvfrom (fd, buf, len, recv_flags, from, fromlen);
580 } while (ret == -1 && errno == EINTR &&
581 !_wapi_thread_cur_apc_pending ());
583 if (ret == 0 && len > 0) {
584 /* According to the Linux man page, recvfrom only
585 * returns 0 when the socket has been shut down
586 * cleanly. Turn this into an EINTR to simulate win32
587 * behaviour of returning EINTR when a socket is
588 * closed while the recvfrom is blocking (we use a
589 * shutdown() in socket_close() to trigger this.) See
592 /* Distinguish between the socket being shut down at
593 * the local or remote ends, and reads that request 0
597 /* If this returns FALSE, it means the socket has been
598 * closed locally. If it returns TRUE, but
599 * still_readable != 1 then shutdown
600 * (SHUT_RD|SHUT_RDWR) has been called locally.
602 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
603 (gpointer *)&socket_handle);
604 if (ok == FALSE || socket_handle->still_readable != 1) {
613 g_message ("%s: recv error: %s", __func__, strerror(errno));
616 errnum = errno_to_WSA (errnum, __func__);
617 WSASetLastError (errnum);
619 return(SOCKET_ERROR);
624 int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
626 gpointer handle = GUINT_TO_POINTER (fd);
629 if (startup_count == 0) {
630 WSASetLastError (WSANOTINITIALISED);
631 return(SOCKET_ERROR);
634 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
635 WSASetLastError (WSAENOTSOCK);
636 return(SOCKET_ERROR);
640 ret = send (fd, msg, len, send_flags);
641 } while (ret == -1 && errno == EINTR &&
642 !_wapi_thread_cur_apc_pending ());
647 g_message ("%s: send error: %s", __func__, strerror (errno));
650 errnum = errno_to_WSA (errnum, __func__);
651 WSASetLastError (errnum);
653 return(SOCKET_ERROR);
658 int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
659 const struct sockaddr *to, socklen_t tolen)
661 gpointer handle = GUINT_TO_POINTER (fd);
664 if (startup_count == 0) {
665 WSASetLastError (WSANOTINITIALISED);
666 return(SOCKET_ERROR);
669 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
670 WSASetLastError (WSAENOTSOCK);
671 return(SOCKET_ERROR);
675 ret = sendto (fd, msg, len, send_flags, to, tolen);
676 } while (ret == -1 && errno == EINTR &&
677 !_wapi_thread_cur_apc_pending ());
682 g_message ("%s: send error: %s", __func__, strerror (errno));
685 errnum = errno_to_WSA (errnum, __func__);
686 WSASetLastError (errnum);
688 return(SOCKET_ERROR);
693 int _wapi_setsockopt(guint32 fd, int level, int optname,
694 const void *optval, socklen_t optlen)
696 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);
712 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
713 int ms = *((int *) optval);
714 tv.tv_sec = ms / 1000;
715 tv.tv_usec = (ms % 1000) * 1000; // micro from milli
717 optlen = sizeof (tv);
718 #if defined (__linux__)
719 } else if (optname == SO_SNDBUF || optname == SO_RCVBUF) {
720 /* According to socket(7) the Linux kernel doubles the
721 * buffer sizes "to allow space for bookkeeping
724 int bufsize = *((int *) optval);
731 ret = setsockopt (fd, level, optname, tmp_val, optlen);
735 g_message ("%s: setsockopt error: %s", __func__,
739 errnum = errno_to_WSA (errnum, __func__);
740 WSASetLastError (errnum);
742 return(SOCKET_ERROR);
748 int _wapi_shutdown(guint32 fd, int how)
750 struct _WapiHandle_socket *socket_handle;
752 gpointer handle = GUINT_TO_POINTER (fd);
755 if (startup_count == 0) {
756 WSASetLastError (WSANOTINITIALISED);
757 return(SOCKET_ERROR);
760 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
761 WSASetLastError (WSAENOTSOCK);
762 return(SOCKET_ERROR);
765 if (how == SHUT_RD ||
767 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
768 (gpointer *)&socket_handle);
770 g_warning ("%s: error looking up socket handle %p",
772 WSASetLastError (WSAENOTSOCK);
773 return(SOCKET_ERROR);
776 socket_handle->still_readable = 0;
779 ret = shutdown (fd, how);
783 g_message ("%s: shutdown error: %s", __func__,
787 errnum = errno_to_WSA (errnum, __func__);
788 WSASetLastError (errnum);
790 return(SOCKET_ERROR);
796 guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
797 guint32 unused2, guint32 unused3)
799 struct _WapiHandle_socket socket_handle = {0};
803 socket_handle.domain = domain;
804 socket_handle.type = type;
805 socket_handle.protocol = protocol;
806 socket_handle.still_readable = 1;
808 fd = socket (domain, type, protocol);
809 if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
811 /* Retry with protocol == 4 (see bug #54565) */
812 socket_handle.protocol = 4;
813 fd = socket (AF_INET, SOCK_RAW, 4);
819 g_message ("%s: socket error: %s", __func__, strerror (errno));
821 errnum = errno_to_WSA (errnum, __func__);
822 WSASetLastError (errnum);
824 return(INVALID_SOCKET);
827 if (fd >= _wapi_fd_reserve) {
829 g_message ("%s: File descriptor is too big (%d >= %d)",
830 __func__, fd, _wapi_fd_reserve);
833 WSASetLastError (WSASYSCALLFAILURE);
836 return(INVALID_SOCKET);
840 mono_once (&socket_ops_once, socket_ops_init);
842 handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
843 if (handle == _WAPI_HANDLE_INVALID) {
844 g_warning ("%s: error creating socket handle", __func__);
845 return(INVALID_SOCKET);
849 g_message ("%s: returning socket handle %p", __func__, handle);
855 struct hostent *_wapi_gethostbyname(const char *hostname)
859 if (startup_count == 0) {
860 WSASetLastError (WSANOTINITIALISED);
864 he = gethostbyname (hostname);
867 g_message ("%s: gethostbyname error: %s", __func__,
873 WSASetLastError (WSAHOST_NOT_FOUND);
875 #if NO_ADDRESS != NO_DATA
879 WSASetLastError (WSANO_DATA);
882 WSASetLastError (WSANO_RECOVERY);
885 WSASetLastError (WSATRY_AGAIN);
888 g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
896 static gboolean socket_disconnect (guint32 fd)
898 struct _WapiHandle_socket *socket_handle;
900 gpointer handle = GUINT_TO_POINTER (fd);
903 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
904 (gpointer *)&socket_handle);
906 g_warning ("%s: error looking up socket handle %p", __func__,
908 WSASetLastError (WSAENOTSOCK);
912 newsock = socket (socket_handle->domain, socket_handle->type,
913 socket_handle->protocol);
918 g_message ("%s: socket error: %s", __func__, strerror (errno));
921 errnum = errno_to_WSA (errnum, __func__);
922 WSASetLastError (errnum);
927 /* According to Stevens "Advanced Programming in the UNIX
928 * Environment: UNIX File I/O" dup2() is atomic so there
929 * should not be a race condition between the old fd being
930 * closed and the new socket fd being copied over
933 ret = dup2 (newsock, fd);
934 } while (ret == -1 && errno == EAGAIN);
940 g_message ("%s: dup2 error: %s", __func__, strerror (errno));
943 errnum = errno_to_WSA (errnum, __func__);
944 WSASetLastError (errnum);
954 static gboolean wapi_disconnectex (guint32 fd, WapiOverlapped *overlapped,
955 guint32 flags, guint32 reserved)
958 g_message ("%s: called on socket %d!", __func__, fd);
962 WSASetLastError (WSAEINVAL);
966 /* We could check the socket type here and fail unless its
967 * SOCK_STREAM, SOCK_SEQPACKET or SOCK_RDM (according to msdn)
968 * if we really wanted to
971 return(socket_disconnect (fd));
974 /* NB only supports NULL file handle, NULL buffers and
975 * TF_DISCONNECT|TF_REUSE_SOCKET flags to disconnect the socket fd.
976 * Shouldn't actually ever need to be called anyway though, because we
977 * have DisconnectEx ().
979 static gboolean wapi_transmitfile (guint32 fd, gpointer file,
980 guint32 num_write, guint32 num_per_send,
981 WapiOverlapped *overlapped,
982 WapiTransmitFileBuffers *buffers,
983 WapiTransmitFileFlags flags)
986 g_message ("%s: called on socket %d!", __func__, fd);
989 g_assert (file == NULL);
990 g_assert (overlapped == NULL);
991 g_assert (buffers == NULL);
992 g_assert (num_write == 0);
993 g_assert (num_per_send == 0);
994 g_assert (flags == (TF_DISCONNECT | TF_REUSE_SOCKET));
996 return(socket_disconnect (fd));
1003 } extension_functions[] = {
1004 {WSAID_DISCONNECTEX, wapi_disconnectex},
1005 {WSAID_TRANSMITFILE, wapi_transmitfile},
1010 WSAIoctl (guint32 fd, gint32 command,
1011 gchar *input, gint i_len,
1012 gchar *output, gint o_len, glong *written,
1013 void *unused1, void *unused2)
1015 gpointer handle = GUINT_TO_POINTER (fd);
1017 gchar *buffer = NULL;
1019 if (startup_count == 0) {
1020 WSASetLastError (WSANOTINITIALISED);
1021 return(SOCKET_ERROR);
1024 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1025 WSASetLastError (WSAENOTSOCK);
1026 return SOCKET_ERROR;
1029 if (command == SIO_GET_EXTENSION_FUNCTION_POINTER) {
1031 WapiGuid *guid = (WapiGuid *)input;
1033 if (i_len < sizeof(WapiGuid)) {
1034 /* As far as I can tell, windows doesn't
1035 * actually set an error here...
1037 WSASetLastError (WSAEINVAL);
1038 return(SOCKET_ERROR);
1041 if (o_len < sizeof(gpointer)) {
1043 WSASetLastError (WSAEINVAL);
1044 return(SOCKET_ERROR);
1047 if (output == NULL) {
1049 WSASetLastError (WSAEINVAL);
1050 return(SOCKET_ERROR);
1053 while(extension_functions[i].func != NULL) {
1054 if (!memcmp (guid, &extension_functions[i].guid,
1055 sizeof(WapiGuid))) {
1056 memcpy (output, &extension_functions[i].func,
1058 *written = sizeof(gpointer);
1065 WSASetLastError (WSAEINVAL);
1066 return(SOCKET_ERROR);
1070 buffer = g_memdup (input, i_len);
1073 ret = ioctl (fd, command, buffer);
1075 gint errnum = errno;
1077 g_message("%s: WSAIoctl error: %s", __func__,
1081 errnum = errno_to_WSA (errnum, __func__);
1082 WSASetLastError (errnum);
1085 return(SOCKET_ERROR);
1088 if (buffer == NULL) {
1091 /* We just copy the buffer to the output. Some ioctls
1092 * don't even output any data, but, well...
1094 * NB windows returns WSAEFAULT if o_len is too small
1096 i_len = (i_len > o_len) ? o_len : i_len;
1098 if (i_len > 0 && output != NULL) {
1099 memcpy (output, buffer, i_len);
1109 int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
1111 gpointer handle = GUINT_TO_POINTER (fd);
1114 if (startup_count == 0) {
1115 WSASetLastError (WSANOTINITIALISED);
1116 return(SOCKET_ERROR);
1119 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1120 WSASetLastError (WSAENOTSOCK);
1121 return(SOCKET_ERROR);
1127 /* This works better than ioctl(...FIONBIO...)
1128 * on Linux (it causes connect to return
1129 * EINPROGRESS, but the ioctl doesn't seem to)
1131 ret = fcntl(fd, F_GETFL, 0);
1133 if (*(gboolean *)arg) {
1138 ret = fcntl(fd, F_SETFL, ret);
1141 #endif /* O_NONBLOCK */
1144 ret = ioctl (fd, command, arg);
1147 WSASetLastError (WSAEINVAL);
1148 return(SOCKET_ERROR);
1152 gint errnum = errno;
1154 g_message ("%s: ioctl error: %s", __func__, strerror (errno));
1157 errnum = errno_to_WSA (errnum, __func__);
1158 WSASetLastError (errnum);
1160 return(SOCKET_ERROR);
1166 int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
1167 fd_set *exceptfds, struct timeval *timeout)
1171 if (startup_count == 0) {
1172 WSASetLastError (WSANOTINITIALISED);
1173 return(SOCKET_ERROR);
1176 for (maxfd = FD_SETSIZE-1; maxfd >= 0; maxfd--) {
1177 if ((readfds && FD_ISSET (maxfd, readfds)) ||
1178 (writefds && FD_ISSET (maxfd, writefds)) ||
1179 (exceptfds && FD_ISSET (maxfd, exceptfds))) {
1185 WSASetLastError (WSAEINVAL);
1186 return(SOCKET_ERROR);
1190 ret = select(maxfd + 1, readfds, writefds, exceptfds,
1192 } while (ret == -1 && errno == EINTR &&
1193 !_wapi_thread_cur_apc_pending ());
1196 gint errnum = errno;
1198 g_message ("%s: select error: %s", __func__, strerror (errno));
1200 errnum = errno_to_WSA (errnum, __func__);
1201 WSASetLastError (errnum);
1203 return(SOCKET_ERROR);
1209 void _wapi_FD_CLR(guint32 fd, fd_set *set)
1211 gpointer handle = GUINT_TO_POINTER (fd);
1213 if (fd >= FD_SETSIZE) {
1214 WSASetLastError (WSAEINVAL);
1218 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1219 WSASetLastError (WSAENOTSOCK);
1226 int _wapi_FD_ISSET(guint32 fd, fd_set *set)
1228 gpointer handle = GUINT_TO_POINTER (fd);
1230 if (fd >= FD_SETSIZE) {
1231 WSASetLastError (WSAEINVAL);
1235 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1236 WSASetLastError (WSAENOTSOCK);
1240 return(FD_ISSET (fd, set));
1243 void _wapi_FD_SET(guint32 fd, fd_set *set)
1245 gpointer handle = GUINT_TO_POINTER (fd);
1247 if (fd >= FD_SETSIZE) {
1248 WSASetLastError (WSAEINVAL);
1252 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1253 WSASetLastError (WSAENOTSOCK);