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>
38 #include <netinet/in.h>
39 #include <netinet/tcp.h>
41 #include <arpa/inet.h>
45 static guint32 startup_count=0;
47 static void socket_close (gpointer handle, gpointer data);
49 struct _WapiHandleOps _wapi_socket_ops = {
50 socket_close, /* close */
54 NULL, /* special_wait */
58 static mono_once_t socket_ops_once=MONO_ONCE_INIT;
60 static void socket_ops_init (void)
62 /* No capabilities to register */
65 static void socket_close (gpointer handle, gpointer data)
68 struct _WapiHandle_socket *socket_handle = (struct _WapiHandle_socket *)data;
71 g_message ("%s: closing socket handle %p", __func__, handle);
74 if (startup_count == 0) {
75 WSASetLastError (WSANOTINITIALISED);
79 /* Shutdown the socket for reading, to interrupt any potential
80 * receives that may be blocking for data. See bug 75705.
82 shutdown (GPOINTER_TO_UINT (handle), SHUT_RD);
85 ret = close (GPOINTER_TO_UINT(handle));
86 } while (ret == -1 && errno == EINTR &&
87 !_wapi_thread_cur_apc_pending ());
92 g_message ("%s: close error: %s", __func__, strerror (errno));
94 errnum = errno_to_WSA (errnum, __func__);
95 WSASetLastError (errnum);
98 socket_handle->saved_error = 0;
101 int WSAStartup(guint32 requested, WapiWSAData *data)
107 /* Insist on v2.0+ */
108 if (requested < MAKEWORD(2,0)) {
109 return(WSAVERNOTSUPPORTED);
114 /* I've no idea what is the minor version of the spec I read */
115 data->wHighVersion = MAKEWORD(2,2);
117 data->wVersion = requested < data->wHighVersion? requested:
121 g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
124 strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
125 strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
131 cleanup_close (gpointer handle, gpointer data)
133 _wapi_handle_ops_close (handle, NULL);
140 g_message ("%s: cleaning up", __func__);
143 if (--startup_count) {
148 _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
152 void WSASetLastError(int error)
154 SetLastError (error);
157 int WSAGetLastError(void)
159 return(GetLastError ());
162 int closesocket(guint32 fd)
164 gpointer handle = GUINT_TO_POINTER (fd);
166 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
167 WSASetLastError (WSAENOTSOCK);
171 _wapi_handle_unref (handle);
175 guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
177 gpointer handle = GUINT_TO_POINTER (fd);
179 struct _WapiHandle_socket *socket_handle;
180 struct _WapiHandle_socket new_socket_handle = {0};
184 if (startup_count == 0) {
185 WSASetLastError (WSANOTINITIALISED);
186 return(INVALID_SOCKET);
189 if (addr != NULL && *addrlen < sizeof(struct sockaddr)) {
190 WSASetLastError (WSAEFAULT);
191 return(INVALID_SOCKET);
194 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
195 WSASetLastError (WSAENOTSOCK);
196 return(INVALID_SOCKET);
199 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
200 (gpointer *)&socket_handle);
202 g_warning ("%s: error looking up socket handle %p",
204 WSASetLastError (WSAENOTSOCK);
205 return(INVALID_SOCKET);
209 new_fd = accept (fd, addr, addrlen);
210 } while (new_fd == -1 && errno == EINTR &&
211 !_wapi_thread_cur_apc_pending());
216 g_message ("%s: accept error: %s", __func__, strerror(errno));
219 errnum = errno_to_WSA (errnum, __func__);
220 WSASetLastError (errnum);
222 return(INVALID_SOCKET);
225 if (new_fd >= _wapi_fd_reserve) {
227 g_message ("%s: File descriptor is too big", __func__);
230 WSASetLastError (WSASYSCALLFAILURE);
234 return(INVALID_SOCKET);
237 new_socket_handle.domain = socket_handle->domain;
238 new_socket_handle.type = socket_handle->type;
239 new_socket_handle.protocol = socket_handle->protocol;
240 new_socket_handle.still_readable = 1;
242 new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd,
244 if(new_handle == _WAPI_HANDLE_INVALID) {
245 g_warning ("%s: error creating socket handle", __func__);
246 WSASetLastError (ERROR_GEN_FAILURE);
247 return(INVALID_SOCKET);
251 g_message ("%s: returning newly accepted socket handle %p with",
252 __func__, new_handle);
258 int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
260 gpointer handle = GUINT_TO_POINTER (fd);
263 if (startup_count == 0) {
264 WSASetLastError (WSANOTINITIALISED);
265 return(SOCKET_ERROR);
268 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
269 WSASetLastError (WSAENOTSOCK);
270 return(SOCKET_ERROR);
273 ret = bind (fd, my_addr, addrlen);
277 g_message ("%s: bind error: %s", __func__, strerror(errno));
279 errnum = errno_to_WSA (errnum, __func__);
280 WSASetLastError (errnum);
282 return(SOCKET_ERROR);
287 int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
290 gpointer handle = GUINT_TO_POINTER (fd);
291 struct _WapiHandle_socket *socket_handle;
295 if (startup_count == 0) {
296 WSASetLastError (WSANOTINITIALISED);
297 return(SOCKET_ERROR);
300 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
301 WSASetLastError (WSAENOTSOCK);
302 return(SOCKET_ERROR);
305 if (connect (fd, serv_addr, addrlen) == -1) {
312 if (errno != EINTR) {
314 g_message ("%s: connect error: %s", __func__,
318 errnum = errno_to_WSA (errnum, __func__);
319 if (errnum == WSAEINPROGRESS)
320 errnum = WSAEWOULDBLOCK; /* see bug #73053 */
322 WSASetLastError (errnum);
325 * On solaris x86 getsockopt (SO_ERROR) is not set after
326 * connect () fails so we need to save this error.
328 * But don't do this for EWOULDBLOCK (bug 317315)
330 if (errnum != WSAEWOULDBLOCK) {
331 ok = _wapi_lookup_handle (handle,
333 (gpointer *)&socket_handle);
335 /* ECONNRESET means the socket was closed by another thread */
336 if (errnum != WSAECONNRESET)
337 g_warning ("%s: error looking up socket handle %p", __func__, handle);
339 socket_handle->saved_error = errnum;
342 return(SOCKET_ERROR);
346 fds.events = POLLOUT;
347 while (poll (&fds, 1, -1) == -1 &&
348 !_wapi_thread_cur_apc_pending ()) {
349 if (errno != EINTR) {
350 errnum = errno_to_WSA (errno, __func__);
353 g_message ("%s: connect poll error: %s",
354 __func__, strerror (errno));
357 WSASetLastError (errnum);
358 return(SOCKET_ERROR);
362 len = sizeof(so_error);
363 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &so_error,
365 errnum = errno_to_WSA (errno, __func__);
368 g_message ("%s: connect getsockopt error: %s",
369 __func__, strerror (errno));
372 WSASetLastError (errnum);
373 return(SOCKET_ERROR);
377 errnum = errno_to_WSA (so_error, __func__);
379 /* Need to save this socket error */
380 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
381 (gpointer *)&socket_handle);
383 g_warning ("%s: error looking up socket handle %p", __func__, handle);
385 socket_handle->saved_error = errnum;
389 g_message ("%s: connect getsockopt returned error: %s",
390 __func__, strerror (so_error));
393 WSASetLastError (errnum);
394 return(SOCKET_ERROR);
401 int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
403 gpointer handle = GUINT_TO_POINTER (fd);
406 if (startup_count == 0) {
407 WSASetLastError (WSANOTINITIALISED);
408 return(SOCKET_ERROR);
411 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
412 WSASetLastError (WSAENOTSOCK);
413 return(SOCKET_ERROR);
416 ret = getpeername (fd, name, namelen);
420 g_message ("%s: getpeername error: %s", __func__,
424 errnum = errno_to_WSA (errnum, __func__);
425 WSASetLastError (errnum);
427 return(SOCKET_ERROR);
433 int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
435 gpointer handle = GUINT_TO_POINTER (fd);
438 if (startup_count == 0) {
439 WSASetLastError (WSANOTINITIALISED);
440 return(SOCKET_ERROR);
443 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
444 WSASetLastError (WSAENOTSOCK);
445 return(SOCKET_ERROR);
448 ret = getsockname (fd, name, namelen);
452 g_message ("%s: getsockname error: %s", __func__,
456 errnum = errno_to_WSA (errnum, __func__);
457 WSASetLastError (errnum);
459 return(SOCKET_ERROR);
465 int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
468 gpointer handle = GUINT_TO_POINTER (fd);
472 struct _WapiHandle_socket *socket_handle;
475 if (startup_count == 0) {
476 WSASetLastError (WSANOTINITIALISED);
477 return(SOCKET_ERROR);
480 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
481 WSASetLastError (WSAENOTSOCK);
482 return(SOCKET_ERROR);
486 if (level == SOL_SOCKET &&
487 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
489 *optlen = sizeof (tv);
492 ret = getsockopt (fd, level, optname, tmp_val, optlen);
496 g_message ("%s: getsockopt error: %s", __func__,
500 errnum = errno_to_WSA (errnum, __func__);
501 WSASetLastError (errnum);
503 return(SOCKET_ERROR);
506 if (level == SOL_SOCKET &&
507 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
508 *((int *) optval) = tv.tv_sec * 1000 + (tv.tv_usec / 1000); // milli from micro
509 *optlen = sizeof (int);
512 if (optname == SO_ERROR) {
513 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
514 (gpointer *)&socket_handle);
516 g_warning ("%s: error looking up socket handle %p",
519 /* can't extract the last error */
520 *((int *) optval) = errno_to_WSA (*((int *)optval),
523 if (*((int *)optval) != 0) {
524 *((int *) optval) = errno_to_WSA (*((int *)optval),
526 socket_handle->saved_error = *((int *)optval);
528 *((int *)optval) = socket_handle->saved_error;
536 int _wapi_listen(guint32 fd, int backlog)
538 gpointer handle = GUINT_TO_POINTER (fd);
541 if (startup_count == 0) {
542 WSASetLastError (WSANOTINITIALISED);
543 return(SOCKET_ERROR);
546 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
547 WSASetLastError (WSAENOTSOCK);
548 return(SOCKET_ERROR);
551 ret = listen (fd, backlog);
555 g_message ("%s: listen error: %s", __func__, strerror (errno));
558 errnum = errno_to_WSA (errnum, __func__);
559 WSASetLastError (errnum);
561 return(SOCKET_ERROR);
567 int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
569 return(_wapi_recvfrom (fd, buf, len, recv_flags, NULL, 0));
572 int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
573 struct sockaddr *from, socklen_t *fromlen)
575 gpointer handle = GUINT_TO_POINTER (fd);
576 struct _WapiHandle_socket *socket_handle;
580 if (startup_count == 0) {
581 WSASetLastError (WSANOTINITIALISED);
582 return(SOCKET_ERROR);
585 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
586 WSASetLastError (WSAENOTSOCK);
587 return(SOCKET_ERROR);
591 ret = recvfrom (fd, buf, len, recv_flags, from, fromlen);
592 } while (ret == -1 && errno == EINTR &&
593 !_wapi_thread_cur_apc_pending ());
595 if (ret == 0 && len > 0) {
596 /* According to the Linux man page, recvfrom only
597 * returns 0 when the socket has been shut down
598 * cleanly. Turn this into an EINTR to simulate win32
599 * behaviour of returning EINTR when a socket is
600 * closed while the recvfrom is blocking (we use a
601 * shutdown() in socket_close() to trigger this.) See
604 /* Distinguish between the socket being shut down at
605 * the local or remote ends, and reads that request 0
609 /* If this returns FALSE, it means the socket has been
610 * closed locally. If it returns TRUE, but
611 * still_readable != 1 then shutdown
612 * (SHUT_RD|SHUT_RDWR) has been called locally.
614 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
615 (gpointer *)&socket_handle);
616 if (ok == FALSE || socket_handle->still_readable != 1) {
625 g_message ("%s: recv error: %s", __func__, strerror(errno));
628 errnum = errno_to_WSA (errnum, __func__);
629 WSASetLastError (errnum);
631 return(SOCKET_ERROR);
637 _wapi_recvmsg(guint32 fd, struct msghdr *msg, int recv_flags)
639 gpointer handle = GUINT_TO_POINTER (fd);
640 struct _WapiHandle_socket *socket_handle;
644 if (startup_count == 0) {
645 WSASetLastError (WSANOTINITIALISED);
646 return(SOCKET_ERROR);
649 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
650 WSASetLastError (WSAENOTSOCK);
651 return(SOCKET_ERROR);
655 ret = recvmsg (fd, msg, recv_flags);
656 } while (ret == -1 && errno == EINTR &&
657 !_wapi_thread_cur_apc_pending ());
660 /* see _wapi_recvfrom */
661 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
662 (gpointer *)&socket_handle);
663 if (ok == FALSE || socket_handle->still_readable != 1) {
672 g_message ("%s: recvmsg error: %s", __func__, strerror(errno));
675 errnum = errno_to_WSA (errnum, __func__);
676 WSASetLastError (errnum);
678 return(SOCKET_ERROR);
683 int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
685 gpointer handle = GUINT_TO_POINTER (fd);
688 if (startup_count == 0) {
689 WSASetLastError (WSANOTINITIALISED);
690 return(SOCKET_ERROR);
693 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
694 WSASetLastError (WSAENOTSOCK);
695 return(SOCKET_ERROR);
699 ret = send (fd, msg, len, send_flags);
700 } while (ret == -1 && errno == EINTR &&
701 !_wapi_thread_cur_apc_pending ());
706 g_message ("%s: send error: %s", __func__, strerror (errno));
709 errnum = errno_to_WSA (errnum, __func__);
710 WSASetLastError (errnum);
712 return(SOCKET_ERROR);
717 int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
718 const struct sockaddr *to, socklen_t tolen)
720 gpointer handle = GUINT_TO_POINTER (fd);
723 if (startup_count == 0) {
724 WSASetLastError (WSANOTINITIALISED);
725 return(SOCKET_ERROR);
728 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
729 WSASetLastError (WSAENOTSOCK);
730 return(SOCKET_ERROR);
734 ret = sendto (fd, msg, len, send_flags, to, tolen);
735 } while (ret == -1 && errno == EINTR &&
736 !_wapi_thread_cur_apc_pending ());
741 g_message ("%s: send error: %s", __func__, strerror (errno));
744 errnum = errno_to_WSA (errnum, __func__);
745 WSASetLastError (errnum);
747 return(SOCKET_ERROR);
753 _wapi_sendmsg(guint32 fd, const struct msghdr *msg, int send_flags)
755 gpointer handle = GUINT_TO_POINTER (fd);
758 if (startup_count == 0) {
759 WSASetLastError (WSANOTINITIALISED);
760 return(SOCKET_ERROR);
763 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
764 WSASetLastError (WSAENOTSOCK);
765 return(SOCKET_ERROR);
769 ret = sendmsg (fd, msg, send_flags);
770 } while (ret == -1 && errno == EINTR &&
771 !_wapi_thread_cur_apc_pending ());
776 g_message ("%s: sendmsg error: %s", __func__, strerror (errno));
779 errnum = errno_to_WSA (errnum, __func__);
780 WSASetLastError (errnum);
782 return(SOCKET_ERROR);
787 int _wapi_setsockopt(guint32 fd, int level, int optname,
788 const void *optval, socklen_t optlen)
790 gpointer handle = GUINT_TO_POINTER (fd);
795 if (startup_count == 0) {
796 WSASetLastError (WSANOTINITIALISED);
797 return(SOCKET_ERROR);
800 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
801 WSASetLastError (WSAENOTSOCK);
802 return(SOCKET_ERROR);
806 if (level == SOL_SOCKET &&
807 (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
808 int ms = *((int *) optval);
809 tv.tv_sec = ms / 1000;
810 tv.tv_usec = (ms % 1000) * 1000; // micro from milli
812 optlen = sizeof (tv);
813 #if defined (__linux__)
814 } else if (level == SOL_SOCKET &&
815 (optname == SO_SNDBUF || optname == SO_RCVBUF)) {
816 /* According to socket(7) the Linux kernel doubles the
817 * buffer sizes "to allow space for bookkeeping
820 int bufsize = *((int *) optval);
827 ret = setsockopt (fd, level, optname, tmp_val, optlen);
831 g_message ("%s: setsockopt error: %s", __func__,
835 errnum = errno_to_WSA (errnum, __func__);
836 WSASetLastError (errnum);
838 return(SOCKET_ERROR);
841 #if defined (SO_REUSEPORT)
842 /* BSD's and MacOS X multicast sockets also need SO_REUSEPORT when SO_REUSEADDR is requested. */
843 if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
845 int type_len = sizeof (type);
847 if (!getsockopt (fd, level, SO_TYPE, &type, &type_len)) {
848 if (type == SOCK_DGRAM)
849 setsockopt (fd, level, SO_REUSEPORT, tmp_val, optlen);
857 int _wapi_shutdown(guint32 fd, int how)
859 struct _WapiHandle_socket *socket_handle;
861 gpointer handle = GUINT_TO_POINTER (fd);
864 if (startup_count == 0) {
865 WSASetLastError (WSANOTINITIALISED);
866 return(SOCKET_ERROR);
869 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
870 WSASetLastError (WSAENOTSOCK);
871 return(SOCKET_ERROR);
874 if (how == SHUT_RD ||
876 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
877 (gpointer *)&socket_handle);
879 g_warning ("%s: error looking up socket handle %p",
881 WSASetLastError (WSAENOTSOCK);
882 return(SOCKET_ERROR);
885 socket_handle->still_readable = 0;
888 ret = shutdown (fd, how);
892 g_message ("%s: shutdown error: %s", __func__,
896 errnum = errno_to_WSA (errnum, __func__);
897 WSASetLastError (errnum);
899 return(SOCKET_ERROR);
905 guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
906 guint32 unused2, guint32 unused3)
908 struct _WapiHandle_socket socket_handle = {0};
912 socket_handle.domain = domain;
913 socket_handle.type = type;
914 socket_handle.protocol = protocol;
915 socket_handle.still_readable = 1;
917 fd = socket (domain, type, protocol);
918 if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
920 /* Retry with protocol == 4 (see bug #54565) */
921 socket_handle.protocol = 4;
922 fd = socket (AF_INET, SOCK_RAW, 4);
928 g_message ("%s: socket error: %s", __func__, strerror (errno));
930 errnum = errno_to_WSA (errnum, __func__);
931 WSASetLastError (errnum);
933 return(INVALID_SOCKET);
936 if (fd >= _wapi_fd_reserve) {
938 g_message ("%s: File descriptor is too big (%d >= %d)",
939 __func__, fd, _wapi_fd_reserve);
942 WSASetLastError (WSASYSCALLFAILURE);
945 return(INVALID_SOCKET);
948 /* .net seems to set this by default for SOCK_STREAM, not for
949 * SOCK_DGRAM (see bug #36322)
951 * It seems winsock has a rather different idea of what
952 * SO_REUSEADDR means. If it's set, then a new socket can be
953 * bound over an existing listening socket. There's a new
954 * windows-specific option called SO_EXCLUSIVEADDRUSE but
955 * using that means the socket MUST be closed properly, or a
956 * denial of service can occur. Luckily for us, winsock
957 * behaves as though any other system would when SO_REUSEADDR
958 * is true, so we don't need to do anything else here. See
964 ret = setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &true,
970 g_message ("%s: Error setting SO_REUSEADDR", __func__);
973 errnum = errno_to_WSA (errnum, __func__);
974 WSASetLastError (errnum);
978 return(INVALID_SOCKET);
983 mono_once (&socket_ops_once, socket_ops_init);
985 handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
986 if (handle == _WAPI_HANDLE_INVALID) {
987 g_warning ("%s: error creating socket handle", __func__);
988 WSASetLastError (WSASYSCALLFAILURE);
990 return(INVALID_SOCKET);
994 g_message ("%s: returning socket handle %p", __func__, handle);
1000 struct hostent *_wapi_gethostbyname(const char *hostname)
1004 if (startup_count == 0) {
1005 WSASetLastError (WSANOTINITIALISED);
1009 he = gethostbyname (hostname);
1012 g_message ("%s: gethostbyname error: %s", __func__,
1013 strerror (h_errno));
1017 case HOST_NOT_FOUND:
1018 WSASetLastError (WSAHOST_NOT_FOUND);
1020 #if NO_ADDRESS != NO_DATA
1024 WSASetLastError (WSANO_DATA);
1027 WSASetLastError (WSANO_RECOVERY);
1030 WSASetLastError (WSATRY_AGAIN);
1033 g_warning ("%s: Need to translate %d into winsock error", __func__, h_errno);
1041 static gboolean socket_disconnect (guint32 fd)
1043 struct _WapiHandle_socket *socket_handle;
1045 gpointer handle = GUINT_TO_POINTER (fd);
1048 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
1049 (gpointer *)&socket_handle);
1051 g_warning ("%s: error looking up socket handle %p", __func__,
1053 WSASetLastError (WSAENOTSOCK);
1057 newsock = socket (socket_handle->domain, socket_handle->type,
1058 socket_handle->protocol);
1059 if (newsock == -1) {
1060 gint errnum = errno;
1063 g_message ("%s: socket error: %s", __func__, strerror (errno));
1066 errnum = errno_to_WSA (errnum, __func__);
1067 WSASetLastError (errnum);
1072 /* According to Stevens "Advanced Programming in the UNIX
1073 * Environment: UNIX File I/O" dup2() is atomic so there
1074 * should not be a race condition between the old fd being
1075 * closed and the new socket fd being copied over
1078 ret = dup2 (newsock, fd);
1079 } while (ret == -1 && errno == EAGAIN);
1082 gint errnum = errno;
1085 g_message ("%s: dup2 error: %s", __func__, strerror (errno));
1088 errnum = errno_to_WSA (errnum, __func__);
1089 WSASetLastError (errnum);
1099 static gboolean wapi_disconnectex (guint32 fd, WapiOverlapped *overlapped,
1100 guint32 flags, guint32 reserved)
1103 g_message ("%s: called on socket %d!", __func__, fd);
1106 if (reserved != 0) {
1107 WSASetLastError (WSAEINVAL);
1111 /* We could check the socket type here and fail unless its
1112 * SOCK_STREAM, SOCK_SEQPACKET or SOCK_RDM (according to msdn)
1113 * if we really wanted to
1116 return(socket_disconnect (fd));
1119 /* NB only supports NULL file handle, NULL buffers and
1120 * TF_DISCONNECT|TF_REUSE_SOCKET flags to disconnect the socket fd.
1121 * Shouldn't actually ever need to be called anyway though, because we
1122 * have DisconnectEx ().
1124 static gboolean wapi_transmitfile (guint32 fd, gpointer file,
1125 guint32 num_write, guint32 num_per_send,
1126 WapiOverlapped *overlapped,
1127 WapiTransmitFileBuffers *buffers,
1128 WapiTransmitFileFlags flags)
1131 g_message ("%s: called on socket %d!", __func__, fd);
1134 g_assert (file == NULL);
1135 g_assert (overlapped == NULL);
1136 g_assert (buffers == NULL);
1137 g_assert (num_write == 0);
1138 g_assert (num_per_send == 0);
1139 g_assert (flags == (TF_DISCONNECT | TF_REUSE_SOCKET));
1141 return(socket_disconnect (fd));
1148 } extension_functions[] = {
1149 {WSAID_DISCONNECTEX, wapi_disconnectex},
1150 {WSAID_TRANSMITFILE, wapi_transmitfile},
1155 WSAIoctl (guint32 fd, gint32 command,
1156 gchar *input, gint i_len,
1157 gchar *output, gint o_len, glong *written,
1158 void *unused1, void *unused2)
1160 gpointer handle = GUINT_TO_POINTER (fd);
1162 gchar *buffer = NULL;
1164 if (startup_count == 0) {
1165 WSASetLastError (WSANOTINITIALISED);
1166 return(SOCKET_ERROR);
1169 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1170 WSASetLastError (WSAENOTSOCK);
1171 return SOCKET_ERROR;
1174 if (command == SIO_GET_EXTENSION_FUNCTION_POINTER) {
1176 WapiGuid *guid = (WapiGuid *)input;
1178 if (i_len < sizeof(WapiGuid)) {
1179 /* As far as I can tell, windows doesn't
1180 * actually set an error here...
1182 WSASetLastError (WSAEINVAL);
1183 return(SOCKET_ERROR);
1186 if (o_len < sizeof(gpointer)) {
1188 WSASetLastError (WSAEINVAL);
1189 return(SOCKET_ERROR);
1192 if (output == NULL) {
1194 WSASetLastError (WSAEINVAL);
1195 return(SOCKET_ERROR);
1198 while(extension_functions[i].func != NULL) {
1199 if (!memcmp (guid, &extension_functions[i].guid,
1200 sizeof(WapiGuid))) {
1201 memcpy (output, &extension_functions[i].func,
1203 *written = sizeof(gpointer);
1210 WSASetLastError (WSAEINVAL);
1211 return(SOCKET_ERROR);
1215 buffer = g_memdup (input, i_len);
1218 ret = ioctl (fd, command, buffer);
1220 gint errnum = errno;
1222 g_message("%s: WSAIoctl error: %s", __func__,
1226 errnum = errno_to_WSA (errnum, __func__);
1227 WSASetLastError (errnum);
1230 return(SOCKET_ERROR);
1233 if (buffer == NULL) {
1236 /* We just copy the buffer to the output. Some ioctls
1237 * don't even output any data, but, well...
1239 * NB windows returns WSAEFAULT if o_len is too small
1241 i_len = (i_len > o_len) ? o_len : i_len;
1243 if (i_len > 0 && output != NULL) {
1244 memcpy (output, buffer, i_len);
1254 int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
1256 gpointer handle = GUINT_TO_POINTER (fd);
1259 if (startup_count == 0) {
1260 WSASetLastError (WSANOTINITIALISED);
1261 return(SOCKET_ERROR);
1264 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1265 WSASetLastError (WSAENOTSOCK);
1266 return(SOCKET_ERROR);
1272 /* This works better than ioctl(...FIONBIO...)
1273 * on Linux (it causes connect to return
1274 * EINPROGRESS, but the ioctl doesn't seem to)
1276 ret = fcntl(fd, F_GETFL, 0);
1278 if (*(gboolean *)arg) {
1283 ret = fcntl(fd, F_SETFL, ret);
1286 #endif /* O_NONBLOCK */
1289 ret = ioctl (fd, command, arg);
1292 WSASetLastError (WSAEINVAL);
1293 return(SOCKET_ERROR);
1297 gint errnum = errno;
1299 g_message ("%s: ioctl error: %s", __func__, strerror (errno));
1302 errnum = errno_to_WSA (errnum, __func__);
1303 WSASetLastError (errnum);
1305 return(SOCKET_ERROR);
1311 int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
1312 fd_set *exceptfds, struct timeval *timeout)
1316 if (startup_count == 0) {
1317 WSASetLastError (WSANOTINITIALISED);
1318 return(SOCKET_ERROR);
1321 for (maxfd = FD_SETSIZE-1; maxfd >= 0; maxfd--) {
1322 if ((readfds && FD_ISSET (maxfd, readfds)) ||
1323 (writefds && FD_ISSET (maxfd, writefds)) ||
1324 (exceptfds && FD_ISSET (maxfd, exceptfds))) {
1330 WSASetLastError (WSAEINVAL);
1331 return(SOCKET_ERROR);
1335 ret = select(maxfd + 1, readfds, writefds, exceptfds,
1337 } while (ret == -1 && errno == EINTR &&
1338 !_wapi_thread_cur_apc_pending ());
1341 gint errnum = errno;
1343 g_message ("%s: select error: %s", __func__, strerror (errno));
1345 errnum = errno_to_WSA (errnum, __func__);
1346 WSASetLastError (errnum);
1348 return(SOCKET_ERROR);
1354 void _wapi_FD_CLR(guint32 fd, fd_set *set)
1356 gpointer handle = GUINT_TO_POINTER (fd);
1358 if (fd >= FD_SETSIZE) {
1359 WSASetLastError (WSAEINVAL);
1363 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1364 WSASetLastError (WSAENOTSOCK);
1371 int _wapi_FD_ISSET(guint32 fd, fd_set *set)
1373 gpointer handle = GUINT_TO_POINTER (fd);
1375 if (fd >= FD_SETSIZE) {
1376 WSASetLastError (WSAEINVAL);
1380 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1381 WSASetLastError (WSAENOTSOCK);
1385 return(FD_ISSET (fd, set));
1388 void _wapi_FD_SET(guint32 fd, fd_set *set)
1390 gpointer handle = GUINT_TO_POINTER (fd);
1392 if (fd >= FD_SETSIZE) {
1393 WSASetLastError (WSAEINVAL);
1397 if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
1398 WSASetLastError (WSAENOTSOCK);
1406 wsabuf_to_msghdr (WapiWSABuf *buffers, guint32 count, struct msghdr *hdr)
1410 memset (hdr, 0, sizeof (struct msghdr));
1411 hdr->msg_iovlen = count;
1412 hdr->msg_iov = g_new0 (struct iovec, count);
1413 for (i = 0; i < count; i++) {
1414 hdr->msg_iov [i].iov_base = buffers [i].buf;
1415 hdr->msg_iov [i].iov_len = buffers [i].len;
1420 msghdr_iov_free (struct msghdr *hdr)
1422 g_free (hdr->msg_iov);
1425 int WSARecv (guint32 fd, WapiWSABuf *buffers, guint32 count, guint32 *received,
1426 guint32 *flags, WapiOverlapped *overlapped,
1427 WapiOverlappedCB *complete)
1432 g_assert (overlapped == NULL);
1433 g_assert (complete == NULL);
1435 wsabuf_to_msghdr (buffers, count, &hdr);
1436 ret = _wapi_recvmsg (fd, &hdr, *flags);
1437 msghdr_iov_free (&hdr);
1439 if(ret == SOCKET_ERROR) {
1444 *flags = hdr.msg_flags;
1449 int WSASend (guint32 fd, WapiWSABuf *buffers, guint32 count, guint32 *sent,
1450 guint32 flags, WapiOverlapped *overlapped,
1451 WapiOverlappedCB *complete)
1456 g_assert (overlapped == NULL);
1457 g_assert (complete == NULL);
1459 wsabuf_to_msghdr (buffers, count, &hdr);
1460 ret = _wapi_sendmsg (fd, &hdr, flags);
1461 msghdr_iov_free (&hdr);
1463 if(ret == SOCKET_ERROR)