]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.cpp
DC headers don't need to be in gtk/private.h
[wxWidgets.git] / src / msw / gsocket.cpp
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: src/msw/gsocket.cpp
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
7 * Purpose: GSocket main MSW file
8 * Licence: The wxWindows licence
9 * CVSID: $Id$
10 * -------------------------------------------------------------------------
11 */
12
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifdef _MSC_VER
21 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
22 * warning: conditional expression is constant.
23 */
24 # pragma warning(disable:4115)
25 /* FD_SET,
26 * warning: named type definition in parentheses.
27 */
28 # pragma warning(disable:4127)
29 /* GAddress_UNIX_GetPath,
30 * warning: unreferenced formal parameter.
31 */
32 # pragma warning(disable:4100)
33
34 #ifdef __WXWINCE__
35 /* windows.h results in tons of warnings at max warning level */
36 # ifdef _MSC_VER
37 # pragma warning(push, 1)
38 # endif
39 # include <windows.h>
40 # ifdef _MSC_VER
41 # pragma warning(pop)
42 # pragma warning(disable:4514)
43 # endif
44 #endif
45
46 #endif /* _MSC_VER */
47
48 #if defined(__CYGWIN__)
49 //CYGWIN gives annoying warning about runtime stuff if we don't do this
50 # define USE_SYS_TYPES_FD_SET
51 # include <sys/types.h>
52 #endif
53
54 #include <winsock.h>
55
56 #include "wx/platform.h"
57
58 #if wxUSE_SOCKETS
59
60 #include "wx/gsocket.h"
61
62 #ifdef __WXWINCE__
63 #ifndef isdigit
64 #define isdigit(x) (x > 47 && x < 58)
65 #endif
66 #include "wx/msw/wince/net.h"
67 #endif
68
69 #include <string.h>
70 #include <stdio.h>
71 #include <stdlib.h>
72 #include <stddef.h>
73 #include <ctype.h>
74
75 /* if we use configure for MSW WX_SOCKLEN_T will be already defined */
76 #ifndef WX_SOCKLEN_T
77 # define WX_SOCKLEN_T int
78 #endif
79
80 #if wxUSE_IPV6
81 typedef struct sockaddr_storage wxSockAddr;
82 #else
83 typedef struct sockaddr wxSockAddr;
84 #endif
85
86 bool GSocket_Init()
87 {
88 WSADATA wsaData;
89
90 GSocketManager * const manager = GSocketManager::Get();
91 if ( !manager || !manager->OnInit() )
92 return false;
93
94 /* Initialize WinSocket */
95 return WSAStartup((1 << 8) | 1, &wsaData) == 0;
96 }
97
98 void GSocket_Cleanup()
99 {
100 GSocketManager * const manager = GSocketManager::Get();
101 if ( manager )
102 manager->OnExit();
103
104 /* Cleanup WinSocket */
105 WSACleanup();
106 }
107
108 /* Constructors / Destructors for GSocket */
109
110 GSocket::GSocket()
111 {
112 int i;
113
114 m_fd = INVALID_SOCKET;
115 for (i = 0; i < GSOCK_MAX_EVENT; i++)
116 {
117 m_cbacks[i] = NULL;
118 }
119 m_detected = 0;
120 m_local = NULL;
121 m_peer = NULL;
122 m_error = GSOCK_NOERROR;
123 m_server = false;
124 m_stream = true;
125 m_non_blocking = false;
126 m_timeout.tv_sec = 10 * 60; /* 10 minutes */
127 m_timeout.tv_usec = 0;
128 m_establishing = false;
129 m_reusable = false;
130 m_broadcast = false;
131 m_dobind = true;
132 m_initialRecvBufferSize = -1;
133 m_initialSendBufferSize = -1;
134
135 m_ok = GSocketManager::Get()->Init_Socket(this);
136 }
137
138 void GSocket::Close()
139 {
140 GSocketManager::Get()->Disable_Events(this);
141 closesocket(m_fd);
142 m_fd = INVALID_SOCKET;
143 }
144
145 GSocket::~GSocket()
146 {
147 GSocketManager::Get()->Destroy_Socket(this);
148
149 /* Check that the socket is really shutdowned */
150 if (m_fd != INVALID_SOCKET)
151 Shutdown();
152
153 /* Destroy private addresses */
154 if (m_local)
155 GAddress_destroy(m_local);
156
157 if (m_peer)
158 GAddress_destroy(m_peer);
159 }
160
161 /* GSocket_Shutdown:
162 * Disallow further read/write operations on this socket, close
163 * the fd and disable all callbacks.
164 */
165 void GSocket::Shutdown()
166 {
167 int evt;
168
169 /* If socket has been created, shutdown it */
170 if (m_fd != INVALID_SOCKET)
171 {
172 shutdown(m_fd, 1 /* SD_SEND */);
173 Close();
174 }
175
176 /* Disable GUI callbacks */
177 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
178 m_cbacks[evt] = NULL;
179
180 m_detected = GSOCK_LOST_FLAG;
181 }
182
183 /* Address handling */
184
185 /* GSocket_SetLocal:
186 * GSocket_GetLocal:
187 * GSocket_SetPeer:
188 * GSocket_GetPeer:
189 * Set or get the local or peer address for this socket. The 'set'
190 * functions return GSOCK_NOERROR on success, an error code otherwise.
191 * The 'get' functions return a pointer to a GAddress object on success,
192 * or NULL otherwise, in which case they set the error code of the
193 * corresponding GSocket.
194 *
195 * Error codes:
196 * GSOCK_INVSOCK - the socket is not valid.
197 * GSOCK_INVADDR - the address is not valid.
198 */
199 GSocketError GSocket::SetLocal(GAddress *address)
200 {
201 /* the socket must be initialized, or it must be a server */
202 if (m_fd != INVALID_SOCKET && !m_server)
203 {
204 m_error = GSOCK_INVSOCK;
205 return GSOCK_INVSOCK;
206 }
207
208 /* check address */
209 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
210 {
211 m_error = GSOCK_INVADDR;
212 return GSOCK_INVADDR;
213 }
214
215 if (m_local)
216 GAddress_destroy(m_local);
217
218 m_local = GAddress_copy(address);
219
220 return GSOCK_NOERROR;
221 }
222
223 GSocketError GSocket::SetPeer(GAddress *address)
224 {
225 /* check address */
226 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
227 {
228 m_error = GSOCK_INVADDR;
229 return GSOCK_INVADDR;
230 }
231
232 if (m_peer)
233 GAddress_destroy(m_peer);
234
235 m_peer = GAddress_copy(address);
236
237 return GSOCK_NOERROR;
238 }
239
240 GAddress *GSocket::GetLocal()
241 {
242 GAddress *address;
243 wxSockAddr addr;
244 WX_SOCKLEN_T size = sizeof(addr);
245 GSocketError err;
246
247 /* try to get it from the m_local var first */
248 if (m_local)
249 return GAddress_copy(m_local);
250
251 /* else, if the socket is initialized, try getsockname */
252 if (m_fd == INVALID_SOCKET)
253 {
254 m_error = GSOCK_INVSOCK;
255 return NULL;
256 }
257
258 if (getsockname(m_fd, (sockaddr*)&addr, &size) == SOCKET_ERROR)
259 {
260 m_error = GSOCK_IOERR;
261 return NULL;
262 }
263
264 /* got a valid address from getsockname, create a GAddress object */
265 if ((address = GAddress_new()) == NULL)
266 {
267 m_error = GSOCK_MEMERR;
268 return NULL;
269 }
270
271 if ((err = _GAddress_translate_from(address, (sockaddr*)&addr, size)) != GSOCK_NOERROR)
272 {
273 GAddress_destroy(address);
274 m_error = err;
275 return NULL;
276 }
277
278 return address;
279 }
280
281 GAddress *GSocket::GetPeer()
282 {
283 /* try to get it from the m_peer var */
284 if (m_peer)
285 return GAddress_copy(m_peer);
286
287 return NULL;
288 }
289
290 /* Server specific parts */
291
292 /* GSocket_SetServer:
293 * Sets up this socket as a server. The local address must have been
294 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
295 * Returns GSOCK_NOERROR on success, one of the following otherwise:
296 *
297 * Error codes:
298 * GSOCK_INVSOCK - the socket is in use.
299 * GSOCK_INVADDR - the local address has not been set.
300 * GSOCK_IOERR - low-level error.
301 */
302 GSocketError GSocket::SetServer()
303 {
304 u_long arg = 1;
305
306 /* must not be in use */
307 if (m_fd != INVALID_SOCKET)
308 {
309 m_error = GSOCK_INVSOCK;
310 return GSOCK_INVSOCK;
311 }
312
313 /* the local addr must have been set */
314 if (!m_local)
315 {
316 m_error = GSOCK_INVADDR;
317 return GSOCK_INVADDR;
318 }
319
320 /* Initialize all fields */
321 m_server = true;
322 m_stream = true;
323
324 /* Create the socket */
325 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
326
327 if (m_fd == INVALID_SOCKET)
328 {
329 m_error = GSOCK_IOERR;
330 return GSOCK_IOERR;
331 }
332
333 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
334 GSocketManager::Get()->Enable_Events(this);
335
336 /* allow a socket to re-bind if the socket is in the TIME_WAIT
337 state after being previously closed.
338 */
339 if (m_reusable)
340 {
341 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
342 }
343
344 /* Bind to the local address,
345 * retrieve the actual address bound,
346 * and listen up to 5 connections.
347 */
348 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
349 (getsockname(m_fd,
350 m_local->m_addr,
351 (WX_SOCKLEN_T *)&m_local->m_len) != 0) ||
352 (listen(m_fd, 5) != 0))
353 {
354 Close();
355 m_error = GSOCK_IOERR;
356 return GSOCK_IOERR;
357 }
358
359 return GSOCK_NOERROR;
360 }
361
362 /* GSocket_WaitConnection:
363 * Waits for an incoming client connection. Returns a pointer to
364 * a GSocket object, or NULL if there was an error, in which case
365 * the last error field will be updated for the calling GSocket.
366 *
367 * Error codes (set in the calling GSocket)
368 * GSOCK_INVSOCK - the socket is not valid or not a server.
369 * GSOCK_TIMEDOUT - timeout, no incoming connections.
370 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
371 * GSOCK_MEMERR - couldn't allocate memory.
372 * GSOCK_IOERR - low-level error.
373 */
374 GSocket *GSocket::WaitConnection()
375 {
376 GSocket *connection;
377 wxSockAddr from;
378 WX_SOCKLEN_T fromlen = sizeof(from);
379 GSocketError err;
380 u_long arg = 1;
381
382 /* Reenable CONNECTION events */
383 m_detected &= ~GSOCK_CONNECTION_FLAG;
384
385 /* If the socket has already been created, we exit immediately */
386 if (m_fd == INVALID_SOCKET || !m_server)
387 {
388 m_error = GSOCK_INVSOCK;
389 return NULL;
390 }
391
392 /* Create a GSocket object for the new connection */
393 connection = GSocket_new();
394
395 if (!connection)
396 {
397 m_error = GSOCK_MEMERR;
398 return NULL;
399 }
400
401 /* Wait for a connection (with timeout) */
402 if (Input_Timeout() == GSOCK_TIMEDOUT)
403 {
404 delete connection;
405 /* m_error set by _GSocket_Input_Timeout */
406 return NULL;
407 }
408
409 connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
410
411 if (connection->m_fd == INVALID_SOCKET)
412 {
413 if (WSAGetLastError() == WSAEWOULDBLOCK)
414 m_error = GSOCK_WOULDBLOCK;
415 else
416 m_error = GSOCK_IOERR;
417
418 delete connection;
419 return NULL;
420 }
421
422 /* Initialize all fields */
423 connection->m_server = false;
424 connection->m_stream = true;
425
426 /* Setup the peer address field */
427 connection->m_peer = GAddress_new();
428 if (!connection->m_peer)
429 {
430 delete connection;
431 m_error = GSOCK_MEMERR;
432 return NULL;
433 }
434 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
435 if (err != GSOCK_NOERROR)
436 {
437 GAddress_destroy(connection->m_peer);
438 delete connection;
439 m_error = err;
440 return NULL;
441 }
442
443 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
444 GSocketManager::Get()->Enable_Events(connection);
445
446 return connection;
447 }
448
449 /* GSocket_SetReusable:
450 * Simply sets the m_resuable flag on the socket. GSocket_SetServer will
451 * make the appropriate setsockopt() call.
452 * Implemented as a GSocket function because clients (ie, wxSocketServer)
453 * don't have access to the GSocket struct information.
454 * Returns true if the flag was set correctly, false if an error occurred
455 * (ie, if the parameter was NULL)
456 */
457 bool GSocket::SetReusable()
458 {
459 /* socket must not be null, and must not be in use/already bound */
460 if (this && m_fd == INVALID_SOCKET) {
461 m_reusable = true;
462 return true;
463 }
464 return false;
465 }
466
467 /* GSocket_SetBroadcast:
468 * Simply sets the m_broadcast flag on the socket. GSocket_SetServer will
469 * make the appropriate setsockopt() call.
470 * Implemented as a GSocket function because clients (ie, wxSocketServer)
471 * don't have access to the GSocket struct information.
472 * Returns true if the flag was set correctly, false if an error occurred
473 * (ie, if the parameter was NULL)
474 */
475 bool GSocket::SetBroadcast()
476 {
477 /* socket must not be in use/already bound */
478 if (m_fd == INVALID_SOCKET) {
479 m_broadcast = true;
480 return true;
481 }
482 return false;
483 }
484
485 bool GSocket::DontDoBind()
486 {
487 /* socket must not be in use/already bound */
488 if (m_fd == INVALID_SOCKET) {
489 m_dobind = false;
490 return true;
491 }
492 return false;
493 }
494
495 /* Client specific parts */
496
497 /* GSocket_Connect:
498 * For stream (connection oriented) sockets, GSocket_Connect() tries
499 * to establish a client connection to a server using the peer address
500 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
501 * connection has been successfully established, or one of the error
502 * codes listed below. Note that for nonblocking sockets, a return
503 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
504 * request can be completed later; you should use GSocket_Select()
505 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
506 * corresponding asynchronous events.
507 *
508 * For datagram (non connection oriented) sockets, GSocket_Connect()
509 * just sets the peer address established with GSocket_SetPeer() as
510 * default destination.
511 *
512 * Error codes:
513 * GSOCK_INVSOCK - the socket is in use or not valid.
514 * GSOCK_INVADDR - the peer address has not been established.
515 * GSOCK_TIMEDOUT - timeout, the connection failed.
516 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
517 * GSOCK_MEMERR - couldn't allocate memory.
518 * GSOCK_IOERR - low-level error.
519 */
520 GSocketError GSocket::Connect(GSocketStream stream)
521 {
522 int ret, err;
523 u_long arg = 1;
524
525 /* Enable CONNECTION events (needed for nonblocking connections) */
526 m_detected &= ~GSOCK_CONNECTION_FLAG;
527
528 if (m_fd != INVALID_SOCKET)
529 {
530 m_error = GSOCK_INVSOCK;
531 return GSOCK_INVSOCK;
532 }
533
534 if (!m_peer)
535 {
536 m_error = GSOCK_INVADDR;
537 return GSOCK_INVADDR;
538 }
539
540 /* Streamed or dgram socket? */
541 m_stream = (stream == GSOCK_STREAMED);
542 m_server = false;
543 m_establishing = false;
544
545 /* Create the socket */
546 m_fd = socket(m_peer->m_realfamily,
547 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
548
549 if (m_fd == INVALID_SOCKET)
550 {
551 m_error = GSOCK_IOERR;
552 return GSOCK_IOERR;
553 }
554
555 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
556 GSocketManager::Get()->Enable_Events(this);
557
558 // If the reuse flag is set, use the applicable socket reuse flag
559 if (m_reusable)
560 {
561 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
562 }
563
564 if (m_initialRecvBufferSize >= 0)
565 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
566 if (m_initialSendBufferSize >= 0)
567 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
568
569 // If a local address has been set, then we need to bind to it before calling connect
570 if (m_local && m_local->m_addr)
571 {
572 bind(m_fd, m_local->m_addr, m_local->m_len);
573 }
574
575 /* Connect it to the peer address, with a timeout (see below) */
576 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
577
578 if (ret == SOCKET_ERROR)
579 {
580 err = WSAGetLastError();
581
582 /* If connect failed with EWOULDBLOCK and the GSocket object
583 * is in blocking mode, we select() for the specified timeout
584 * checking for writability to see if the connection request
585 * completes.
586 */
587 if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
588 {
589 err = Connect_Timeout();
590
591 if (err != GSOCK_NOERROR)
592 {
593 Close();
594 /* m_error is set in _GSocket_Connect_Timeout */
595 }
596
597 return (GSocketError) err;
598 }
599
600 /* If connect failed with EWOULDBLOCK and the GSocket object
601 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
602 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
603 * this way if the connection completes, a GSOCK_CONNECTION
604 * event will be generated, if enabled.
605 */
606 if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
607 {
608 m_establishing = true;
609 m_error = GSOCK_WOULDBLOCK;
610 return GSOCK_WOULDBLOCK;
611 }
612
613 /* If connect failed with an error other than EWOULDBLOCK,
614 * then the call to GSocket_Connect() has failed.
615 */
616 Close();
617 m_error = GSOCK_IOERR;
618 return GSOCK_IOERR;
619 }
620
621 return GSOCK_NOERROR;
622 }
623
624 /* Datagram sockets */
625
626 /* GSocket_SetNonOriented:
627 * Sets up this socket as a non-connection oriented (datagram) socket.
628 * Before using this function, the local address must have been set
629 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
630 * on success, or one of the following otherwise.
631 *
632 * Error codes:
633 * GSOCK_INVSOCK - the socket is in use.
634 * GSOCK_INVADDR - the local address has not been set.
635 * GSOCK_IOERR - low-level error.
636 */
637 GSocketError GSocket::SetNonOriented()
638 {
639 u_long arg = 1;
640
641 if (m_fd != INVALID_SOCKET)
642 {
643 m_error = GSOCK_INVSOCK;
644 return GSOCK_INVSOCK;
645 }
646
647 if (!m_local)
648 {
649 m_error = GSOCK_INVADDR;
650 return GSOCK_INVADDR;
651 }
652
653 /* Initialize all fields */
654 m_stream = false;
655 m_server = false;
656
657 /* Create the socket */
658 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
659
660 if (m_fd == INVALID_SOCKET)
661 {
662 m_error = GSOCK_IOERR;
663 return GSOCK_IOERR;
664 }
665
666 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
667 GSocketManager::Get()->Enable_Events(this);
668
669 if (m_reusable)
670 {
671 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
672 }
673 if (m_broadcast)
674 {
675 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
676 }
677 if (m_dobind)
678 {
679 /* Bind to the local address,
680 * and retrieve the actual address bound.
681 */
682 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
683 (getsockname(m_fd,
684 m_local->m_addr,
685 (WX_SOCKLEN_T *)&m_local->m_len) != 0))
686 {
687 Close();
688 m_error = GSOCK_IOERR;
689 return GSOCK_IOERR;
690 }
691 }
692
693 return GSOCK_NOERROR;
694 }
695
696 /* Generic IO */
697
698 /* Like recv(), send(), ... */
699 int GSocket::Read(char *buffer, int size)
700 {
701 int ret;
702
703 /* Reenable INPUT events */
704 m_detected &= ~GSOCK_INPUT_FLAG;
705
706 if (m_fd == INVALID_SOCKET || m_server)
707 {
708 m_error = GSOCK_INVSOCK;
709 return -1;
710 }
711
712 /* If the socket is blocking, wait for data (with a timeout) */
713 if (Input_Timeout() == GSOCK_TIMEDOUT)
714 {
715 m_error = GSOCK_TIMEDOUT;
716 return -1;
717 }
718
719 /* Read the data */
720 if (m_stream)
721 ret = Recv_Stream(buffer, size);
722 else
723 ret = Recv_Dgram(buffer, size);
724
725 if (ret == SOCKET_ERROR)
726 {
727 if (WSAGetLastError() != WSAEWOULDBLOCK)
728 m_error = GSOCK_IOERR;
729 else
730 m_error = GSOCK_WOULDBLOCK;
731 return -1;
732 }
733
734 return ret;
735 }
736
737 int GSocket::Write(const char *buffer, int size)
738 {
739 int ret;
740
741 if (m_fd == INVALID_SOCKET || m_server)
742 {
743 m_error = GSOCK_INVSOCK;
744 return -1;
745 }
746
747 /* If the socket is blocking, wait for writability (with a timeout) */
748 if (Output_Timeout() == GSOCK_TIMEDOUT)
749 return -1;
750
751 /* Write the data */
752 if (m_stream)
753 ret = Send_Stream(buffer, size);
754 else
755 ret = Send_Dgram(buffer, size);
756
757 if (ret == SOCKET_ERROR)
758 {
759 if (WSAGetLastError() != WSAEWOULDBLOCK)
760 m_error = GSOCK_IOERR;
761 else
762 m_error = GSOCK_WOULDBLOCK;
763
764 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
765 * does). Once the first OUTPUT event is received, users can assume
766 * that the socket is writable until a read operation fails. Only then
767 * will further OUTPUT events be posted.
768 */
769 m_detected &= ~GSOCK_OUTPUT_FLAG;
770 return -1;
771 }
772
773 return ret;
774 }
775
776 /* GSocket_Select:
777 * Polls the socket to determine its status. This function will
778 * check for the events specified in the 'flags' parameter, and
779 * it will return a mask indicating which operations can be
780 * performed. This function won't block, regardless of the
781 * mode (blocking | nonblocking) of the socket.
782 */
783 GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
784 {
785 return flags & m_detected;
786 }
787
788 /* Attributes */
789
790 /* GSocket_SetNonBlocking:
791 * Sets the socket to non-blocking mode. All IO calls will return
792 * immediately.
793 */
794 void GSocket::SetNonBlocking(bool non_block)
795 {
796 m_non_blocking = non_block;
797 }
798
799 /* GSocket_SetTimeout:
800 * Sets the timeout for blocking calls. Time is expressed in
801 * milliseconds.
802 */
803 void GSocket::SetTimeout(unsigned long millis)
804 {
805 m_timeout.tv_sec = (millis / 1000);
806 m_timeout.tv_usec = (millis % 1000) * 1000;
807 }
808
809 /* GSocket_GetError:
810 * Returns the last error occurred for this socket. Note that successful
811 * operations do not clear this back to GSOCK_NOERROR, so use it only
812 * after an error.
813 */
814 GSocketError WXDLLIMPEXP_NET GSocket::GetError()
815 {
816 return m_error;
817 }
818
819 /* Callbacks */
820
821 /* GSOCK_INPUT:
822 * There is data to be read in the input buffer. If, after a read
823 * operation, there is still data available, the callback function will
824 * be called again.
825 * GSOCK_OUTPUT:
826 * The socket is available for writing. That is, the next write call
827 * won't block. This event is generated only once, when the connection is
828 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
829 * when the output buffer empties again. This means that the app should
830 * assume that it can write since the first OUTPUT event, and no more
831 * OUTPUT events will be generated unless an error occurs.
832 * GSOCK_CONNECTION:
833 * Connection successfully established, for client sockets, or incoming
834 * client connection, for server sockets. Wait for this event (also watch
835 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
836 * GSOCK_LOST:
837 * The connection is lost (or a connection request failed); this could
838 * be due to a failure, or due to the peer closing it gracefully.
839 */
840
841 /* GSocket_SetCallback:
842 * Enables the callbacks specified by 'flags'. Note that 'flags'
843 * may be a combination of flags OR'ed toghether, so the same
844 * callback function can be made to accept different events.
845 * The callback function must have the following prototype:
846 *
847 * void function(GSocket *socket, GSocketEvent event, char *cdata)
848 */
849 void GSocket::SetCallback(GSocketEventFlags flags,
850 GSocketCallback callback, char *cdata)
851 {
852 int count;
853
854 for (count = 0; count < GSOCK_MAX_EVENT; count++)
855 {
856 if ((flags & (1 << count)) != 0)
857 {
858 m_cbacks[count] = callback;
859 m_data[count] = cdata;
860 }
861 }
862 }
863
864 /* GSocket_UnsetCallback:
865 * Disables all callbacks specified by 'flags', which may be a
866 * combination of flags OR'ed toghether.
867 */
868 void GSocket::UnsetCallback(GSocketEventFlags flags)
869 {
870 int count;
871
872 for (count = 0; count < GSOCK_MAX_EVENT; count++)
873 {
874 if ((flags & (1 << count)) != 0)
875 {
876 m_cbacks[count] = NULL;
877 m_data[count] = NULL;
878 }
879 }
880 }
881
882 GSocketError GSocket::GetSockOpt(int level, int optname,
883 void *optval, int *optlen)
884 {
885 if (getsockopt(m_fd, level, optname, (char*)optval, optlen) == 0)
886 {
887 return GSOCK_NOERROR;
888 }
889 return GSOCK_OPTERR;
890 }
891
892 GSocketError GSocket::SetSockOpt(int level, int optname,
893 const void *optval, int optlen)
894 {
895 if (setsockopt(m_fd, level, optname, (char*)optval, optlen) == 0)
896 {
897 return GSOCK_NOERROR;
898 }
899 return GSOCK_OPTERR;
900 }
901
902 /* Internals (IO) */
903
904 /* _GSocket_Input_Timeout:
905 * For blocking sockets, wait until data is available or
906 * until timeout ellapses.
907 */
908 GSocketError GSocket::Input_Timeout()
909 {
910 fd_set readfds;
911
912 if (!m_non_blocking)
913 {
914 FD_ZERO(&readfds);
915 FD_SET(m_fd, &readfds);
916 if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
917 {
918 m_error = GSOCK_TIMEDOUT;
919 return GSOCK_TIMEDOUT;
920 }
921 }
922 return GSOCK_NOERROR;
923 }
924
925 /* _GSocket_Output_Timeout:
926 * For blocking sockets, wait until data can be sent without
927 * blocking or until timeout ellapses.
928 */
929 GSocketError GSocket::Output_Timeout()
930 {
931 fd_set writefds;
932
933 if (!m_non_blocking)
934 {
935 FD_ZERO(&writefds);
936 FD_SET(m_fd, &writefds);
937 if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
938 {
939 m_error = GSOCK_TIMEDOUT;
940 return GSOCK_TIMEDOUT;
941 }
942 }
943 return GSOCK_NOERROR;
944 }
945
946 /* _GSocket_Connect_Timeout:
947 * For blocking sockets, wait until the connection is
948 * established or fails, or until timeout ellapses.
949 */
950 GSocketError GSocket::Connect_Timeout()
951 {
952 fd_set writefds;
953 fd_set exceptfds;
954
955 FD_ZERO(&writefds);
956 FD_ZERO(&exceptfds);
957 FD_SET(m_fd, &writefds);
958 FD_SET(m_fd, &exceptfds);
959 if (select(0, NULL, &writefds, &exceptfds, &m_timeout) == 0)
960 {
961 m_error = GSOCK_TIMEDOUT;
962 return GSOCK_TIMEDOUT;
963 }
964 if (!FD_ISSET(m_fd, &writefds))
965 {
966 m_error = GSOCK_IOERR;
967 return GSOCK_IOERR;
968 }
969
970 return GSOCK_NOERROR;
971 }
972
973 int GSocket::Recv_Stream(char *buffer, int size)
974 {
975 return recv(m_fd, buffer, size, 0);
976 }
977
978 int GSocket::Recv_Dgram(char *buffer, int size)
979 {
980 wxSockAddr from;
981 WX_SOCKLEN_T fromlen = sizeof(from);
982 int ret;
983 GSocketError err;
984
985 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, &fromlen);
986
987 if (ret == SOCKET_ERROR)
988 return SOCKET_ERROR;
989
990 /* Translate a system address into a GSocket address */
991 if (!m_peer)
992 {
993 m_peer = GAddress_new();
994 if (!m_peer)
995 {
996 m_error = GSOCK_MEMERR;
997 return -1;
998 }
999 }
1000 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
1001 if (err != GSOCK_NOERROR)
1002 {
1003 GAddress_destroy(m_peer);
1004 m_peer = NULL;
1005 m_error = err;
1006 return -1;
1007 }
1008
1009 return ret;
1010 }
1011
1012 int GSocket::Send_Stream(const char *buffer, int size)
1013 {
1014 return send(m_fd, buffer, size, 0);
1015 }
1016
1017 int GSocket::Send_Dgram(const char *buffer, int size)
1018 {
1019 struct sockaddr *addr;
1020 int len, ret;
1021 GSocketError err;
1022
1023 if (!m_peer)
1024 {
1025 m_error = GSOCK_INVADDR;
1026 return -1;
1027 }
1028
1029 err = _GAddress_translate_to(m_peer, &addr, &len);
1030 if (err != GSOCK_NOERROR)
1031 {
1032 m_error = err;
1033 return -1;
1034 }
1035
1036 ret = sendto(m_fd, buffer, size, 0, addr, len);
1037
1038 /* Frees memory allocated by _GAddress_translate_to */
1039 free(addr);
1040
1041 return ret;
1042 }
1043
1044 /* Compatibility functions for GSocket */
1045 GSocket *GSocket_new()
1046 {
1047 GSocket *newsocket = new GSocket();
1048 if(newsocket->IsOk())
1049 return newsocket;
1050 delete newsocket;
1051 return NULL;
1052 }
1053
1054
1055 /*
1056 * -------------------------------------------------------------------------
1057 * GAddress
1058 * -------------------------------------------------------------------------
1059 */
1060
1061 /* CHECK_ADDRESS verifies that the current address family is either
1062 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1063 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1064 * an appropiate error code.
1065 *
1066 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1067 */
1068 #define CHECK_ADDRESS(address, family) \
1069 { \
1070 if (address->m_family == GSOCK_NOFAMILY) \
1071 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1072 return address->m_error; \
1073 if (address->m_family != GSOCK_##family) \
1074 { \
1075 address->m_error = GSOCK_INVADDR; \
1076 return GSOCK_INVADDR; \
1077 } \
1078 }
1079
1080 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1081 { \
1082 if (address->m_family == GSOCK_NOFAMILY) \
1083 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1084 return retval; \
1085 if (address->m_family != GSOCK_##family) \
1086 { \
1087 address->m_error = GSOCK_INVADDR; \
1088 return retval; \
1089 } \
1090 }
1091
1092
1093 GAddress *GAddress_new()
1094 {
1095 GAddress *address;
1096
1097 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1098 return NULL;
1099
1100 address->m_family = GSOCK_NOFAMILY;
1101 address->m_addr = NULL;
1102 address->m_len = 0;
1103
1104 return address;
1105 }
1106
1107 GAddress *GAddress_copy(GAddress *address)
1108 {
1109 GAddress *addr2;
1110
1111 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1112 return NULL;
1113
1114 memcpy(addr2, address, sizeof(GAddress));
1115
1116 if (address->m_addr)
1117 {
1118 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1119 if (addr2->m_addr == NULL)
1120 {
1121 free(addr2);
1122 return NULL;
1123 }
1124 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1125 }
1126
1127 return addr2;
1128 }
1129
1130 void GAddress_destroy(GAddress *address)
1131 {
1132 if (address->m_addr)
1133 free(address->m_addr);
1134
1135 free(address);
1136 }
1137
1138 void GAddress_SetFamily(GAddress *address, GAddressType type)
1139 {
1140 address->m_family = type;
1141 }
1142
1143 GAddressType GAddress_GetFamily(GAddress *address)
1144 {
1145 return address->m_family;
1146 }
1147
1148 GSocketError _GAddress_translate_from(GAddress *address,
1149 struct sockaddr *addr, int len)
1150 {
1151 address->m_realfamily = addr->sa_family;
1152 switch (addr->sa_family)
1153 {
1154 case AF_INET:
1155 address->m_family = GSOCK_INET;
1156 break;
1157 case AF_UNIX:
1158 address->m_family = GSOCK_UNIX;
1159 break;
1160 #if wxUSE_IPV6
1161 case AF_INET6:
1162 address->m_family = GSOCK_INET6;
1163 break;
1164 #endif
1165 default:
1166 {
1167 address->m_error = GSOCK_INVOP;
1168 return GSOCK_INVOP;
1169 }
1170 }
1171
1172 if (address->m_addr)
1173 free(address->m_addr);
1174
1175 address->m_len = len;
1176 address->m_addr = (struct sockaddr *) malloc(len);
1177
1178 if (address->m_addr == NULL)
1179 {
1180 address->m_error = GSOCK_MEMERR;
1181 return GSOCK_MEMERR;
1182 }
1183 memcpy(address->m_addr, addr, len);
1184
1185 return GSOCK_NOERROR;
1186 }
1187
1188 GSocketError _GAddress_translate_to(GAddress *address,
1189 struct sockaddr **addr, int *len)
1190 {
1191 if (!address->m_addr)
1192 {
1193 address->m_error = GSOCK_INVADDR;
1194 return GSOCK_INVADDR;
1195 }
1196
1197 *len = address->m_len;
1198 *addr = (struct sockaddr *) malloc(address->m_len);
1199 if (*addr == NULL)
1200 {
1201 address->m_error = GSOCK_MEMERR;
1202 return GSOCK_MEMERR;
1203 }
1204
1205 memcpy(*addr, address->m_addr, address->m_len);
1206 return GSOCK_NOERROR;
1207 }
1208
1209 /*
1210 * -------------------------------------------------------------------------
1211 * Internet address family
1212 * -------------------------------------------------------------------------
1213 */
1214
1215 GSocketError _GAddress_Init_INET(GAddress *address)
1216 {
1217 address->m_len = sizeof(struct sockaddr_in);
1218 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1219 if (address->m_addr == NULL)
1220 {
1221 address->m_error = GSOCK_MEMERR;
1222 return GSOCK_MEMERR;
1223 }
1224
1225 address->m_family = GSOCK_INET;
1226 address->m_realfamily = AF_INET;
1227 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1228 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1229
1230 return GSOCK_NOERROR;
1231 }
1232
1233 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1234 {
1235 struct hostent *he;
1236 struct in_addr *addr;
1237
1238 CHECK_ADDRESS(address, INET);
1239
1240 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1241
1242 addr->s_addr = inet_addr(hostname);
1243
1244 /* If it is a numeric host name, convert it now */
1245 if (addr->s_addr == INADDR_NONE)
1246 {
1247 struct in_addr *array_addr;
1248
1249 /* It is a real name, we solve it */
1250 if ((he = gethostbyname(hostname)) == NULL)
1251 {
1252 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1253 address->m_error = GSOCK_NOHOST;
1254 return GSOCK_NOHOST;
1255 }
1256 array_addr = (struct in_addr *) *(he->h_addr_list);
1257 addr->s_addr = array_addr[0].s_addr;
1258 }
1259 return GSOCK_NOERROR;
1260 }
1261
1262 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1263 {
1264 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
1265 }
1266
1267 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1268 {
1269 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1270 }
1271
1272 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1273 unsigned long hostaddr)
1274 {
1275 struct in_addr *addr;
1276
1277 CHECK_ADDRESS(address, INET);
1278
1279 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1280 addr->s_addr = htonl(hostaddr);
1281
1282 return GSOCK_NOERROR;
1283 }
1284
1285 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1286 const char *protocol)
1287 {
1288 struct servent *se;
1289 struct sockaddr_in *addr;
1290
1291 CHECK_ADDRESS(address, INET);
1292
1293 if (!port)
1294 {
1295 address->m_error = GSOCK_INVPORT;
1296 return GSOCK_INVPORT;
1297 }
1298
1299 se = getservbyname(port, protocol);
1300 if (!se)
1301 {
1302 if (isdigit(port[0]))
1303 {
1304 int port_int;
1305
1306 port_int = atoi(port);
1307 addr = (struct sockaddr_in *)address->m_addr;
1308 addr->sin_port = htons((u_short) port_int);
1309 return GSOCK_NOERROR;
1310 }
1311
1312 address->m_error = GSOCK_INVPORT;
1313 return GSOCK_INVPORT;
1314 }
1315
1316 addr = (struct sockaddr_in *)address->m_addr;
1317 addr->sin_port = se->s_port;
1318
1319 return GSOCK_NOERROR;
1320 }
1321
1322 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1323 {
1324 struct sockaddr_in *addr;
1325
1326 CHECK_ADDRESS(address, INET);
1327
1328 addr = (struct sockaddr_in *)address->m_addr;
1329 addr->sin_port = htons(port);
1330
1331 return GSOCK_NOERROR;
1332 }
1333
1334 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1335 {
1336 struct hostent *he;
1337 char *addr_buf;
1338 struct sockaddr_in *addr;
1339
1340 CHECK_ADDRESS(address, INET);
1341
1342 addr = (struct sockaddr_in *)address->m_addr;
1343 addr_buf = (char *)&(addr->sin_addr);
1344
1345 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1346 if (he == NULL)
1347 {
1348 address->m_error = GSOCK_NOHOST;
1349 return GSOCK_NOHOST;
1350 }
1351
1352 strncpy(hostname, he->h_name, sbuf);
1353
1354 return GSOCK_NOERROR;
1355 }
1356
1357 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1358 {
1359 struct sockaddr_in *addr;
1360
1361 CHECK_ADDRESS_RETVAL(address, INET, 0);
1362
1363 addr = (struct sockaddr_in *)address->m_addr;
1364
1365 return ntohl(addr->sin_addr.s_addr);
1366 }
1367
1368 unsigned short GAddress_INET_GetPort(GAddress *address)
1369 {
1370 struct sockaddr_in *addr;
1371
1372 CHECK_ADDRESS_RETVAL(address, INET, 0);
1373
1374 addr = (struct sockaddr_in *)address->m_addr;
1375 return ntohs(addr->sin_port);
1376 }
1377
1378
1379 #if wxUSE_IPV6
1380 /*
1381 * -------------------------------------------------------------------------
1382 * Internet IPv6 address family
1383 * -------------------------------------------------------------------------
1384 */
1385 #include "ws2tcpip.h"
1386
1387 #ifdef __VISUALC__
1388 #pragma comment(lib,"ws2_32")
1389 #endif // __VISUALC__
1390
1391 GSocketError _GAddress_Init_INET6(GAddress *address)
1392 {
1393 struct in6_addr any_address = IN6ADDR_ANY_INIT;
1394 address->m_len = sizeof(struct sockaddr_in6);
1395 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1396 if (address->m_addr == NULL)
1397 {
1398 address->m_error = GSOCK_MEMERR;
1399 return GSOCK_MEMERR;
1400 }
1401 memset(address->m_addr,0,address->m_len);
1402
1403 address->m_family = GSOCK_INET6;
1404 address->m_realfamily = AF_INET6;
1405 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
1406 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
1407
1408 return GSOCK_NOERROR;
1409 }
1410
1411 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
1412 {
1413 CHECK_ADDRESS(address, INET6);
1414
1415 addrinfo hints;
1416 memset( & hints, 0, sizeof( hints ) );
1417 hints.ai_family = AF_INET6;
1418 addrinfo * info = 0;
1419 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
1420 {
1421 address->m_error = GSOCK_NOHOST;
1422 return GSOCK_NOHOST;
1423 }
1424
1425 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
1426 freeaddrinfo( info );
1427 return GSOCK_NOERROR;
1428 }
1429
1430 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
1431 {
1432 CHECK_ADDRESS(address, INET6);
1433
1434 struct in6_addr addr;
1435 memset( & addr, 0, sizeof( addr ) );
1436 return GAddress_INET6_SetHostAddress(address, addr);
1437 }
1438 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
1439 struct in6_addr hostaddr)
1440 {
1441 CHECK_ADDRESS(address, INET6);
1442
1443 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
1444
1445 return GSOCK_NOERROR;
1446 }
1447
1448 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
1449 const char *protocol)
1450 {
1451 struct servent *se;
1452 struct sockaddr_in6 *addr;
1453
1454 CHECK_ADDRESS(address, INET6);
1455
1456 if (!port)
1457 {
1458 address->m_error = GSOCK_INVPORT;
1459 return GSOCK_INVPORT;
1460 }
1461
1462 se = getservbyname(port, protocol);
1463 if (!se)
1464 {
1465 if (isdigit(port[0]))
1466 {
1467 int port_int;
1468
1469 port_int = atoi(port);
1470 addr = (struct sockaddr_in6 *)address->m_addr;
1471 addr->sin6_port = htons((u_short) port_int);
1472 return GSOCK_NOERROR;
1473 }
1474
1475 address->m_error = GSOCK_INVPORT;
1476 return GSOCK_INVPORT;
1477 }
1478
1479 addr = (struct sockaddr_in6 *)address->m_addr;
1480 addr->sin6_port = se->s_port;
1481
1482 return GSOCK_NOERROR;
1483 }
1484
1485 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
1486 {
1487 struct sockaddr_in6 *addr;
1488
1489 CHECK_ADDRESS(address, INET6);
1490
1491 addr = (struct sockaddr_in6 *)address->m_addr;
1492 addr->sin6_port = htons(port);
1493
1494 return GSOCK_NOERROR;
1495 }
1496
1497 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1498 {
1499 struct hostent *he;
1500 char *addr_buf;
1501 struct sockaddr_in6 *addr;
1502
1503 CHECK_ADDRESS(address, INET6);
1504
1505 addr = (struct sockaddr_in6 *)address->m_addr;
1506 addr_buf = (char *)&(addr->sin6_addr);
1507
1508 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
1509 if (he == NULL)
1510 {
1511 address->m_error = GSOCK_NOHOST;
1512 return GSOCK_NOHOST;
1513 }
1514
1515 strncpy(hostname, he->h_name, sbuf);
1516
1517 return GSOCK_NOERROR;
1518 }
1519
1520 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
1521 {
1522 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
1523 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
1524 return GSOCK_NOERROR;
1525 }
1526
1527 unsigned short GAddress_INET6_GetPort(GAddress *address)
1528 {
1529 CHECK_ADDRESS_RETVAL(address, INET6, 0);
1530
1531 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
1532 }
1533
1534 #endif // wxUSE_IPV6
1535
1536 /*
1537 * -------------------------------------------------------------------------
1538 * Unix address family
1539 * -------------------------------------------------------------------------
1540 */
1541
1542 GSocketError _GAddress_Init_UNIX(GAddress *address)
1543 {
1544 address->m_error = GSOCK_INVADDR;
1545 return GSOCK_INVADDR;
1546 }
1547
1548 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *WXUNUSED(path))
1549 {
1550 address->m_error = GSOCK_INVADDR;
1551 return GSOCK_INVADDR;
1552 }
1553
1554 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *WXUNUSED(path), size_t WXUNUSED(sbuf))
1555 {
1556 address->m_error = GSOCK_INVADDR;
1557 return GSOCK_INVADDR;
1558 }
1559
1560 #endif // wxUSE_SOCKETS