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;
42 static void socket_close (gpointer handle, gpointer data);
44 struct _WapiHandleOps _wapi_socket_ops = {
45 socket_close, /* close */
49 NULL, /* special_wait */
53 static mono_once_t socket_ops_once=MONO_ONCE_INIT;
55 static void socket_ops_init (void)
57 /* No capabilities to register */
60 static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED)
65 g_message ("%s: closing socket handle %p", __func__, handle);
68 if (startup_count == 0) {
69 WSASetLastError (WSANOTINITIALISED);
73 /* Shutdown the socket for reading, to interrupt any potential
74 * receives that may be blocking for data. See bug 75705.
76 shutdown (GPOINTER_TO_UINT (handle), SHUT_RD);
79 ret = close (GPOINTER_TO_UINT(handle));
80 } while (ret == -1 && errno == EINTR &&
81 !_wapi_thread_cur_apc_pending ());
86 g_message ("%s: close error: %s", __func__, strerror (errno));
88 errnum = errno_to_WSA (errnum, __func__);
89 WSASetLastError (errnum);
93 int WSAStartup(guint32 requested, WapiWSAData *data)
100 if (requested < MAKEWORD(2,0)) {
101 return(WSAVERNOTSUPPORTED);
106 /* I've no idea what is the minor version of the spec I read */
107 data->wHighVersion = MAKEWORD(2,2);
109 data->wVersion = requested < data->wHighVersion? requested:
113 g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
116 strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
117 strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
123 cleanup_close (gpointer handle, gpointer data)
125 _wapi_handle_ops_close (handle, NULL);
132 g_message ("%s: cleaning up", __func__);
135 if (--startup_count) {
140 _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
144 void WSASetLastError(int error)
146 SetLastError (error);
149 int WSAGetLastError(void)
151 return(GetLastError ());
154 int closesocket(guint32 fd)
156 gpointer handle = GUINT_TO_POINTER (fd);
158 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
159 WSASetLastError (WSAENOTSOCK);
163 _wapi_handle_unref (handle);
167 guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
169 gpointer handle = GUINT_TO_POINTER (fd);
171 struct _WapiHandle_socket *socket_handle;
172 struct _WapiHandle_socket new_socket_handle = {0};
176 if (startup_count == 0) {
177 WSASetLastError (WSANOTINITIALISED);
178 return(INVALID_SOCKET);
181 if (addr != NULL && *addrlen < sizeof(struct sockaddr)) {
182 WSASetLastError (WSAEFAULT);
183 return(INVALID_SOCKET);
186 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
187 WSASetLastError (WSAENOTSOCK);
188 return(INVALID_SOCKET);
191 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
192 (gpointer *)&socket_handle);
194 g_warning ("%s: error looking up socket handle %p",
196 WSASetLastError (WSAENOTSOCK);
197 return(INVALID_SOCKET);
201 new_fd = accept (fd, addr, addrlen);
202 } while (new_fd == -1 && errno == EINTR &&
203 !_wapi_thread_cur_apc_pending());
208 g_message ("%s: accept error: %s", __func__, strerror(errno));
211 errnum = errno_to_WSA (errnum, __func__);
212 WSASetLastError (errnum);
214 return(INVALID_SOCKET);
217 if (new_fd >= _wapi_fd_reserve) {
219 g_message ("%s: File descriptor is too big", __func__);
222 WSASetLastError (WSASYSCALLFAILURE);
226 return(INVALID_SOCKET);
229 new_socket_handle.domain = socket_handle->domain;
230 new_socket_handle.type = socket_handle->type;
231 new_socket_handle.protocol = socket_handle->protocol;
232 new_socket_handle.still_readable = 1;
234 new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd,
236 if(new_handle == _WAPI_HANDLE_INVALID) {
237 g_warning ("%s: error creating socket handle", __func__);
238 WSASetLastError (ERROR_GEN_FAILURE);
239 return(INVALID_SOCKET);
243 g_message ("%s: returning newly accepted socket handle %p with",
244 __func__, new_handle);
250 int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
252 gpointer handle = GUINT_TO_POINTER (fd);
255 if (startup_count == 0) {
256 WSASetLastError (WSANOTINITIALISED);
257 return(SOCKET_ERROR);
260 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
261 WSASetLastError (WSAENOTSOCK);
262 return(SOCKET_ERROR);
265 ret = bind (fd, my_addr, addrlen);
269 g_message ("%s: bind error: %s", __func__, strerror(errno));
271 errnum = errno_to_WSA (errnum, __func__);
272 WSASetLastError (errnum);
274 return(SOCKET_ERROR);
279 int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
282 gpointer handle = GUINT_TO_POINTER (fd);
283 struct _WapiHandle_socket *socket_handle;
287 if (startup_count == 0) {
288 WSASetLastError (WSANOTINITIALISED);
289 return(SOCKET_ERROR);
292 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
293 WSASetLastError (WSAENOTSOCK);
294 return(SOCKET_ERROR);
297 if (connect (fd, serv_addr, addrlen) == -1) {
304 if (errno != EINTR) {
306 g_message ("%s: connect error: %s", __func__,
310 errnum = errno_to_WSA (errnum, __func__);
311 if (errnum == WSAEINPROGRESS)
312 errnum = WSAEWOULDBLOCK; /* see bug #73053 */
314 WSASetLastError (errnum);
317 * On solaris x86 getsockopt (SO_ERROR) is not set after
318 * connect () fails so we need to save this error.
320 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
321 (gpointer *)&socket_handle);
323 g_warning ("%s: error looking up socket handle %p", __func__, handle);
325 socket_handle->saved_error = errnum;
328 return(SOCKET_ERROR);
332 fds.events = POLLOUT;
333 while (poll (&fds, 1, -1) == -1 &&
334 !_wapi_thread_cur_apc_pending ()) {
335 if (errno != EINTR) {
336 errnum = errno_to_WSA (errno, __func__);
339 g_message ("%s: connect poll error: %s",
340 __func__, strerror (errno));
343 WSASetLastError (errnum);
344 return(SOCKET_ERROR);
348 len = sizeof(so_error);
349 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &so_error,
351 errnum = errno_to_WSA (errno, __func__);
354 g_message ("%s: connect getsockopt error: %s",
355 __func__, strerror (errno));
358 WSASetLastError (errnum);
359 return(SOCKET_ERROR);
363 errnum = errno_to_WSA (so_error, __func__);
365 /* Need to save this socket error */
366 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
367 (gpointer *)&socket_handle);
369 g_warning ("%s: error looking up socket handle %p", __func__, handle);
371 socket_handle->saved_error = errnum;
375 g_message ("%s: connect getsockopt returned error: %s",
376 __func__, strerror (so_error));
379 WSASetLastError (errnum);
380 return(SOCKET_ERROR);
387 int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
389 gpointer handle = GUINT_TO_POINTER (fd);
392 if (startup_count == 0) {
393 WSASetLastError (WSANOTINITIALISED);
394 return(SOCKET_ERROR);
397 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
398 WSASetLastError (WSAENOTSOCK);
399 return(SOCKET_ERROR);
402 ret = getpeername (fd, name, namelen);
406 g_message ("%s: getpeername error: %s", __func__,
410 errnum = errno_to_WSA (errnum, __func__);
411 WSASetLastError (errnum);
413 return(SOCKET_ERROR);
419 int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
421 gpointer handle = GUINT_TO_POINTER (fd);
424 if (startup_count == 0) {
425 WSASetLastError (WSANOTINITIALISED);
426 return(SOCKET_ERROR);
429 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
430 WSASetLastError (WSAENOTSOCK);
431 return(SOCKET_ERROR);
434 ret = getsockname (fd, name, namelen);
438 g_message ("%s: getsockname error: %s", __func__,
442 errnum = errno_to_WSA (errnum, __func__);
443 WSASetLastError (errnum);
445 return(SOCKET_ERROR);
451 int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
454 gpointer handle = GUINT_TO_POINTER (fd);
458 struct _WapiHandle_socket *socket_handle;
461 if (startup_count == 0) {
462 WSASetLastError (WSANOTINITIALISED);
463 return(SOCKET_ERROR);
466 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
467 WSASetLastError (WSAENOTSOCK);
468 return(SOCKET_ERROR);
472 if (level == SOL_SOCKET &&
473 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
475 *optlen = sizeof (tv);
478 ret = getsockopt (fd, level, optname, tmp_val, optlen);
482 g_message ("%s: getsockopt error: %s", __func__,
486 errnum = errno_to_WSA (errnum, __func__);
487 WSASetLastError (errnum);
489 return(SOCKET_ERROR);
492 if (level == SOL_SOCKET &&
493 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
494 *((int *) optval) = tv.tv_sec * 1000 + (tv.tv_usec / 1000); // milli from micro
495 *optlen = sizeof (int);
498 if (optname == SO_ERROR) {
499 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
500 (gpointer *)&socket_handle);
502 g_warning ("%s: error looking up socket handle %p",
505 /* can't extract the last error */
506 *((int *) optval) = errno_to_WSA (*((int *)optval),
509 if (*((int *)optval) != 0) {
510 *((int *) optval) = errno_to_WSA (*((int *)optval),
512 socket_handle->saved_error = *((int *)optval);
514 *((int *)optval) = socket_handle->saved_error;
522 int _wapi_listen(guint32 fd, int backlog)
524 gpointer handle = GUINT_TO_POINTER (fd);
527 if (startup_count == 0) {
528 WSASetLastError (WSANOTINITIALISED);
529 return(SOCKET_ERROR);
532 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
533 WSASetLastError (WSAENOTSOCK);
534 return(SOCKET_ERROR);
537 ret = listen (fd, backlog);
541 g_message ("%s: listen error: %s", __func__, strerror (errno));
544 errnum = errno_to_WSA (errnum, __func__);
545 WSASetLastError (errnum);
547 return(SOCKET_ERROR);
553 int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
555 return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0));
558 int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
559 struct sockaddr *from, socklen_t *fromlen)
561 gpointer handle = GUINT_TO_POINTER (fd);
562 struct _WapiHandle_socket *socket_handle;
566 if (startup_count == 0) {
567 WSASetLastError (WSANOTINITIALISED);
568 return(SOCKET_ERROR);
571 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
572 WSASetLastError (WSAENOTSOCK);
573 return(SOCKET_ERROR);
577 ret = recvfrom (fd, buf, len, recv_flags, from, fromlen);
578 } while (ret == -1 && errno == EINTR &&
579 !_wapi_thread_cur_apc_pending ());
581 if (ret == 0 && len > 0) {
582 /* According to the Linux man page, recvfrom only
583 * returns 0 when the socket has been shut down
584 * cleanly. Turn this into an EINTR to simulate win32
585 * behaviour of returning EINTR when a socket is
586 * closed while the recvfrom is blocking (we use a
587 * shutdown() in socket_close() to trigger this.) See
590 /* Distinguish between the socket being shut down at
591 * the local or remote ends, and reads that request 0
595 /* If this returns FALSE, it means the socket has been
596 * closed locally. If it returns TRUE, but
597 * still_readable != 1 then shutdown
598 * (SHUT_RD|SHUT_RDWR) has been called locally.
600 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
601 (gpointer *)&socket_handle);
602 if (ok == FALSE || socket_handle->still_readable != 1) {
611 g_message ("%s: recv error: %s", __func__, strerror(errno));
614 errnum = errno_to_WSA (errnum, __func__);
615 WSASetLastError (errnum);
617 return(SOCKET_ERROR);
622 int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
624 gpointer handle = GUINT_TO_POINTER (fd);
627 if (startup_count == 0) {
628 WSASetLastError (WSANOTINITIALISED);
629 return(SOCKET_ERROR);
632 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
633 WSASetLastError (WSAENOTSOCK);
634 return(SOCKET_ERROR);
638 ret = send (fd, msg, len, send_flags);
639 } while (ret == -1 && errno == EINTR &&
640 !_wapi_thread_cur_apc_pending ());
645 g_message ("%s: send error: %s", __func__, strerror (errno));
648 errnum = errno_to_WSA (errnum, __func__);
649 WSASetLastError (errnum);
651 return(SOCKET_ERROR);
656 int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
657 const struct sockaddr *to, socklen_t tolen)
659 gpointer handle = GUINT_TO_POINTER (fd);
662 if (startup_count == 0) {
663 WSASetLastError (WSANOTINITIALISED);
664 return(SOCKET_ERROR);
667 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
668 WSASetLastError (WSAENOTSOCK);
669 return(SOCKET_ERROR);
673 ret = sendto (fd, msg, len, send_flags, to, tolen);
674 } while (ret == -1 && errno == EINTR &&
675 !_wapi_thread_cur_apc_pending ());
680 g_message ("%s: send error: %s", __func__, strerror (errno));
683 errnum = errno_to_WSA (errnum, __func__);
684 WSASetLastError (errnum);
686 return(SOCKET_ERROR);
691 int _wapi_setsockopt(guint32 fd, int level, int optname,
692 const void *optval, socklen_t optlen)
694 gpointer handle = GUINT_TO_POINTER (fd);
699 if (startup_count == 0) {
700 WSASetLastError (WSANOTINITIALISED);
701 return(SOCKET_ERROR);
704 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
705 WSASetLastError (WSAENOTSOCK);
706 return(SOCKET_ERROR);
710 if (level == SOL_SOCKET &&
711 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
712 int ms = *((int *) optval);
713 tv.tv_sec = ms / 1000;
714 tv.tv_usec = (ms % 1000) * 1000; // micro from milli
716 optlen = sizeof (tv);
717 #if defined (__linux__)
718 } else if (level == SOL_SOCKET &&
719 (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);
745 #if defined(__FreeBSD__)
746 /* FreeBSD's multicast sockets also need SO_REUSEPORT when SO_REUSEADDR is requested. */
747 if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
749 int type_len = sizeof (type);
751 if (!getsockopt (fd, level, SO_TYPE, &type, &type_len)) {
752 if (type == SOCK_DGRAM)
753 setsockopt (fd, level, SO_REUSEPORT, tmp_val, optlen);
761 int _wapi_shutdown(guint32 fd, int how)
763 struct _WapiHandle_socket *socket_handle;
765 gpointer handle = GUINT_TO_POINTER (fd);
768 if (startup_count == 0) {
769 WSASetLastError (WSANOTINITIALISED);
770 return(SOCKET_ERROR);
773 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
774 WSASetLastError (WSAENOTSOCK);
775 return(SOCKET_ERROR);
778 if (how == SHUT_RD ||
780 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
781 (gpointer *)&socket_handle);
783 g_warning ("%s: error looking up socket handle %p",
785 WSASetLastError (WSAENOTSOCK);
786 return(SOCKET_ERROR);
789 socket_handle->still_readable = 0;
792 ret = shutdown (fd, how);
796 g_message ("%s: shutdown error: %s", __func__,
800 errnum = errno_to_WSA (errnum, __func__);
801 WSASetLastError (errnum);
803 return(SOCKET_ERROR);
809 guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
810 guint32 unused2, guint32 unused3)
812 struct _WapiHandle_socket socket_handle = {0};
816 socket_handle.domain = domain;
817 socket_handle.type = type;
818 socket_handle.protocol = protocol;
819 socket_handle.still_readable = 1;
821 fd = socket (domain, type, protocol);
822 if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
824 /* Retry with protocol == 4 (see bug #54565) */
825 socket_handle.protocol = 4;
826 fd = socket (AF_INET, SOCK_RAW, 4);
832 g_message ("%s: socket error: %s", __func__, strerror (errno));
834 errnum = errno_to_WSA (errnum, __func__);
835 WSASetLastError (errnum);
837 return(INVALID_SOCKET);
840 if (fd >= _wapi_fd_reserve) {
842 g_message ("%s: File descriptor is too big (%d >= %d)",
843 __func__, fd, _wapi_fd_reserve);
846 WSASetLastError (WSASYSCALLFAILURE);
849 return(INVALID_SOCKET);
852 /* .net seems to set this by default for SOCK_STREAM, not for
853 * SOCK_DGRAM (see bug #36322)
855 * It seems winsock has a rather different idea of what
856 * SO_REUSEADDR means. If it's set, then a new socket can be
857 * bound over an existing listening socket. There's a new
858 * windows-specific option called SO_EXCLUSIVEADDRUSE but
859 * using that means the socket MUST be closed properly, or a
860 * denial of service can occur. Luckily for us, winsock
861 * behaves as though any other system would when SO_REUSEADDR
862 * is true, so we don't need to do anything else here. See
868 ret = setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &true,
874 g_message ("%s: Error setting SO_REUSEADDR", __func__);
877 errnum = errno_to_WSA (errnum, __func__);
878 WSASetLastError (errnum);
882 return(INVALID_SOCKET);
887 mono_once (&socket_ops_once, socket_ops_init);
889 handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
890 if (handle == _WAPI_HANDLE_INVALID) {
891 g_warning ("%s: error creating socket handle", __func__);
892 WSASetLastError (WSASYSCALLFAILURE);
894 return(INVALID_SOCKET);
898 g_message ("%s: returning socket handle %p", __func__, handle);
904 struct hostent *_wapi_gethostbyname(const char *hostname)
908 if (startup_count == 0) {
909 WSASetLastError (WSANOTINITIALISED);
913 he = gethostbyname (hostname);
916 g_message ("%s: gethostbyname error: %s", __func__,
922 WSASetLastError (WSAHOST_NOT_FOUND);
924 #if NO_ADDRESS != NO_DATA
928 WSASetLastError (WSANO_DATA);
931 WSASetLastError (WSANO_RECOVERY);
934 WSASetLastError (WSATRY_AGAIN);
937 g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
945 static gboolean socket_disconnect (guint32 fd)
947 struct _WapiHandle_socket *socket_handle;
949 gpointer handle = GUINT_TO_POINTER (fd);
952 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
953 (gpointer *)&socket_handle);
955 g_warning ("%s: error looking up socket handle %p", __func__,
957 WSASetLastError (WSAENOTSOCK);
961 newsock = socket (socket_handle->domain, socket_handle->type,
962 socket_handle->protocol);
967 g_message ("%s: socket error: %s", __func__, strerror (errno));
970 errnum = errno_to_WSA (errnum, __func__);
971 WSASetLastError (errnum);
976 /* According to Stevens "Advanced Programming in the UNIX
977 * Environment: UNIX File I/O" dup2() is atomic so there
978 * should not be a race condition between the old fd being
979 * closed and the new socket fd being copied over
982 ret = dup2 (newsock, fd);
983 } while (ret == -1 && errno == EAGAIN);
989 g_message ("%s: dup2 error: %s", __func__, strerror (errno));
992 errnum = errno_to_WSA (errnum, __func__);
993 WSASetLastError (errnum);
1003 static gboolean wapi_disconnectex (guint32 fd, WapiOverlapped *overlapped,
1004 guint32 flags, guint32 reserved)
1007 g_message ("%s: called on socket %d!", __func__, fd);
1010 if (reserved != 0) {
1011 WSASetLastError (WSAEINVAL);
1015 /* We could check the socket type here and fail unless its
1016 * SOCK_STREAM, SOCK_SEQPACKET or SOCK_RDM (according to msdn)
1017 * if we really wanted to
1020 return(socket_disconnect (fd));
1023 /* NB only supports NULL file handle, NULL buffers and
1024 * TF_DISCONNECT|TF_REUSE_SOCKET flags to disconnect the socket fd.
1025 * Shouldn't actually ever need to be called anyway though, because we
1026 * have DisconnectEx ().
1028 static gboolean wapi_transmitfile (guint32 fd, gpointer file,
1029 guint32 num_write, guint32 num_per_send,
1030 WapiOverlapped *overlapped,
1031 WapiTransmitFileBuffers *buffers,
1032 WapiTransmitFileFlags flags)
1035 g_message ("%s: called on socket %d!", __func__, fd);
1038 g_assert (file == NULL);
1039 g_assert (overlapped == NULL);
1040 g_assert (buffers == NULL);
1041 g_assert (num_write == 0);
1042 g_assert (num_per_send == 0);
1043 g_assert (flags == (TF_DISCONNECT | TF_REUSE_SOCKET));
1045 return(socket_disconnect (fd));
1052 } extension_functions[] = {
1053 {WSAID_DISCONNECTEX, wapi_disconnectex},
1054 {WSAID_TRANSMITFILE, wapi_transmitfile},
1059 WSAIoctl (guint32 fd, gint32 command,
1060 gchar *input, gint i_len,
1061 gchar *output, gint o_len, glong *written,
1062 void *unused1, void *unused2)
1064 gpointer handle = GUINT_TO_POINTER (fd);
1066 gchar *buffer = NULL;
1068 if (startup_count == 0) {
1069 WSASetLastError (WSANOTINITIALISED);
1070 return(SOCKET_ERROR);
1073 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1074 WSASetLastError (WSAENOTSOCK);
1075 return SOCKET_ERROR;
1078 if (command == SIO_GET_EXTENSION_FUNCTION_POINTER) {
1080 WapiGuid *guid = (WapiGuid *)input;
1082 if (i_len < sizeof(WapiGuid)) {
1083 /* As far as I can tell, windows doesn't
1084 * actually set an error here...
1086 WSASetLastError (WSAEINVAL);
1087 return(SOCKET_ERROR);
1090 if (o_len < sizeof(gpointer)) {
1092 WSASetLastError (WSAEINVAL);
1093 return(SOCKET_ERROR);
1096 if (output == NULL) {
1098 WSASetLastError (WSAEINVAL);
1099 return(SOCKET_ERROR);
1102 while(extension_functions[i].func != NULL) {
1103 if (!memcmp (guid, &extension_functions[i].guid,
1104 sizeof(WapiGuid))) {
1105 memcpy (output, &extension_functions[i].func,
1107 *written = sizeof(gpointer);
1114 WSASetLastError (WSAEINVAL);
1115 return(SOCKET_ERROR);
1119 buffer = g_memdup (input, i_len);
1122 ret = ioctl (fd, command, buffer);
1124 gint errnum = errno;
1126 g_message("%s: WSAIoctl error: %s", __func__,
1130 errnum = errno_to_WSA (errnum, __func__);
1131 WSASetLastError (errnum);
1134 return(SOCKET_ERROR);
1137 if (buffer == NULL) {
1140 /* We just copy the buffer to the output. Some ioctls
1141 * don't even output any data, but, well...
1143 * NB windows returns WSAEFAULT if o_len is too small
1145 i_len = (i_len > o_len) ? o_len : i_len;
1147 if (i_len > 0 && output != NULL) {
1148 memcpy (output, buffer, i_len);
1158 int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
1160 gpointer handle = GUINT_TO_POINTER (fd);
1163 if (startup_count == 0) {
1164 WSASetLastError (WSANOTINITIALISED);
1165 return(SOCKET_ERROR);
1168 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1169 WSASetLastError (WSAENOTSOCK);
1170 return(SOCKET_ERROR);
1176 /* This works better than ioctl(...FIONBIO...)
1177 * on Linux (it causes connect to return
1178 * EINPROGRESS, but the ioctl doesn't seem to)
1180 ret = fcntl(fd, F_GETFL, 0);
1182 if (*(gboolean *)arg) {
1187 ret = fcntl(fd, F_SETFL, ret);
1190 #endif /* O_NONBLOCK */
1193 ret = ioctl (fd, command, arg);
1196 WSASetLastError (WSAEINVAL);
1197 return(SOCKET_ERROR);
1201 gint errnum = errno;
1203 g_message ("%s: ioctl error: %s", __func__, strerror (errno));
1206 errnum = errno_to_WSA (errnum, __func__);
1207 WSASetLastError (errnum);
1209 return(SOCKET_ERROR);
1215 int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
1216 fd_set *exceptfds, struct timeval *timeout)
1220 if (startup_count == 0) {
1221 WSASetLastError (WSANOTINITIALISED);
1222 return(SOCKET_ERROR);
1225 for (maxfd = FD_SETSIZE-1; maxfd >= 0; maxfd--) {
1226 if ((readfds && FD_ISSET (maxfd, readfds)) ||
1227 (writefds && FD_ISSET (maxfd, writefds)) ||
1228 (exceptfds && FD_ISSET (maxfd, exceptfds))) {
1234 WSASetLastError (WSAEINVAL);
1235 return(SOCKET_ERROR);
1239 ret = select(maxfd + 1, readfds, writefds, exceptfds,
1241 } while (ret == -1 && errno == EINTR &&
1242 !_wapi_thread_cur_apc_pending ());
1245 gint errnum = errno;
1247 g_message ("%s: select error: %s", __func__, strerror (errno));
1249 errnum = errno_to_WSA (errnum, __func__);
1250 WSASetLastError (errnum);
1252 return(SOCKET_ERROR);
1258 void _wapi_FD_CLR(guint32 fd, fd_set *set)
1260 gpointer handle = GUINT_TO_POINTER (fd);
1262 if (fd >= FD_SETSIZE) {
1263 WSASetLastError (WSAEINVAL);
1267 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1268 WSASetLastError (WSAENOTSOCK);
1275 int _wapi_FD_ISSET(guint32 fd, fd_set *set)
1277 gpointer handle = GUINT_TO_POINTER (fd);
1279 if (fd >= FD_SETSIZE) {
1280 WSASetLastError (WSAEINVAL);
1284 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1285 WSASetLastError (WSAENOTSOCK);
1289 return(FD_ISSET (fd, set));
1292 void _wapi_FD_SET(guint32 fd, fd_set *set)
1294 gpointer handle = GUINT_TO_POINTER (fd);
1296 if (fd >= FD_SETSIZE) {
1297 WSASetLastError (WSAEINVAL);
1301 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1302 WSASetLastError (WSAENOTSOCK);