]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.cpp
97105ca534aa7a9386492ad38ea7468fa9294b8e
[wxWidgets.git] / src / unix / gsocket.cpp
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
7 * Guilhem Lavaux,
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
11 * CVSID: $Id$
12 * -------------------------------------------------------------------------
13 */
14
15 #if defined(__WATCOMC__)
16 #include "wx/wxprec.h"
17 #include <errno.h>
18 #include <nerrno.h>
19 #endif
20
21 #ifndef __GSOCKET_STANDALONE__
22 #include "wx/defs.h"
23 #include "wx/private/gsocketiohandler.h"
24 #endif
25
26 #if defined(__VISAGECPP__)
27 #define BSD_SELECT /* use Berkeley Sockets select */
28 #endif
29
30 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
31
32 #include <assert.h>
33 #include <sys/types.h>
34 #ifdef __VISAGECPP__
35 #include <string.h>
36 #include <sys/time.h>
37 #include <types.h>
38 #include <netinet/in.h>
39 #endif
40 #include <netdb.h>
41 #include <sys/ioctl.h>
42
43 #ifdef HAVE_SYS_SELECT_H
44 # include <sys/select.h>
45 #endif
46
47 #ifdef __VMS__
48 #include <socket.h>
49 struct sockaddr_un
50 {
51 u_char sun_len; /* sockaddr len including null */
52 u_char sun_family; /* AF_UNIX */
53 char sun_path[108]; /* path name (gag) */
54 };
55 #else
56 #include <sys/socket.h>
57 #include <sys/un.h>
58 #endif
59
60 #ifndef __VISAGECPP__
61 #include <sys/time.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
64 #include <errno.h>
65 #include <string.h>
66 #include <unistd.h>
67 #else
68 #include <nerrno.h>
69 # if __IBMCPP__ < 400
70 #include <machine/endian.h>
71 #include <socket.h>
72 #include <ioctl.h>
73 #include <select.h>
74 #include <unistd.h>
75
76 #define EBADF SOCEBADF
77
78 # ifdef min
79 # undef min
80 # endif
81 # else
82 #include <sys/socket.h>
83 #include <sys/ioctl.h>
84 #include <sys/select.h>
85
86 #define close(a) soclose(a)
87 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
88 int _System bsdselect(int,
89 struct fd_set *,
90 struct fd_set *,
91 struct fd_set *,
92 struct timeval *);
93 int _System soclose(int);
94 # endif
95 #endif
96 #ifdef __EMX__
97 #include <sys/select.h>
98 #endif
99
100 #include <stdio.h>
101 #include <stdlib.h>
102 #include <stddef.h>
103 #include <ctype.h>
104 #ifdef sun
105 # include <sys/filio.h>
106 #endif
107 #ifdef sgi
108 # include <bstring.h>
109 #endif
110 #ifdef _AIX
111 # include <strings.h>
112 #endif
113 #include <signal.h>
114
115 #ifndef WX_SOCKLEN_T
116
117 #ifdef VMS
118 # define WX_SOCKLEN_T unsigned int
119 #else
120 # ifdef __GLIBC__
121 # if __GLIBC__ == 2
122 # define WX_SOCKLEN_T socklen_t
123 # endif
124 # elif defined(__WXMAC__)
125 # define WX_SOCKLEN_T socklen_t
126 # else
127 # define WX_SOCKLEN_T int
128 # endif
129 #endif
130
131 #endif /* SOCKLEN_T */
132
133 #ifndef SOCKOPTLEN_T
134 #define SOCKOPTLEN_T WX_SOCKLEN_T
135 #endif
136
137 /*
138 * MSW defines this, Unices don't.
139 */
140 #ifndef INVALID_SOCKET
141 #define INVALID_SOCKET -1
142 #endif
143
144 /* UnixWare reportedly needs this for FIONBIO definition */
145 #ifdef __UNIXWARE__
146 #include <sys/filio.h>
147 #endif
148
149 /*
150 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
151 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
152 */
153 #ifndef INADDR_NONE
154 #define INADDR_NONE INADDR_BROADCAST
155 #endif
156
157 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
158
159 #define MASK_SIGNAL() {
160 #define UNMASK_SIGNAL() }
161
162 #else
163 extern "C" { typedef void (*wxSigHandler)(int); }
164
165 #define MASK_SIGNAL() \
166 { \
167 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
168
169 #define UNMASK_SIGNAL() \
170 signal(SIGPIPE, old_handler); \
171 }
172
173 #endif
174
175 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
176 the program will "crash" unless it explicitly handles the SIGPIPE.
177 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
178 use SO_NOSIGPIPE (if available), the BSD equivalent. */
179 #ifdef MSG_NOSIGNAL
180 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
181 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
182 # define GSOCKET_MSG_NOSIGNAL 0
183 #endif /* MSG_NOSIGNAL */
184
185 #ifndef __GSOCKET_STANDALONE__
186 # include "wx/unix/gsockunx.h"
187 # include "wx/unix/private.h"
188 # include "wx/gsocket.h"
189 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
190 # include "wx/thread.h"
191 #endif
192 #else
193 # include "gsockunx.h"
194 # include "gsocket.h"
195 # ifndef WXUNUSED
196 # define WXUNUSED(x)
197 # endif
198 #endif /* __GSOCKET_STANDALONE__ */
199
200 #if defined(HAVE_GETHOSTBYNAME)
201 static struct hostent * deepCopyHostent(struct hostent *h,
202 const struct hostent *he,
203 char *buffer, int size, int *err)
204 {
205 /* copy old structure */
206 memcpy(h, he, sizeof(struct hostent));
207
208 /* copy name */
209 int len = strlen(h->h_name);
210 if (len > size)
211 {
212 *err = ENOMEM;
213 return NULL;
214 }
215 memcpy(buffer, h->h_name, len);
216 buffer[len] = '\0';
217 h->h_name = buffer;
218
219 /* track position in the buffer */
220 int pos = len + 1;
221
222 /* reuse len to store address length */
223 len = h->h_length;
224
225 /* ensure pointer alignment */
226 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
227 if(misalign < sizeof(char *))
228 pos += misalign;
229
230 /* leave space for pointer list */
231 char **p = h->h_addr_list, **q;
232 char **h_addr_list = (char **)(buffer + pos);
233 while(*(p++) != 0)
234 pos += sizeof(char *);
235
236 /* copy addresses and fill new pointer list */
237 for (p = h->h_addr_list, q = h_addr_list; *p != 0; p++, q++)
238 {
239 if (size < pos + len)
240 {
241 *err = ENOMEM;
242 return NULL;
243 }
244 memcpy(buffer + pos, *p, len); /* copy content */
245 *q = buffer + pos; /* set copied pointer to copied content */
246 pos += len;
247 }
248 *++q = 0; /* null terminate the pointer list */
249 h->h_addr_list = h_addr_list; /* copy pointer to pointers */
250
251 /* ensure word alignment of pointers */
252 misalign = sizeof(char *) - pos%sizeof(char *);
253 if(misalign < sizeof(char *))
254 pos += misalign;
255
256 /* leave space for pointer list */
257 p = h->h_aliases;
258 char **h_aliases = (char **)(buffer + pos);
259 while(*(p++) != 0)
260 pos += sizeof(char *);
261
262 /* copy aliases and fill new pointer list */
263 for (p = h->h_aliases, q = h_aliases; *p != 0; p++, q++)
264 {
265 len = strlen(*p);
266 if (size <= pos + len)
267 {
268 *err = ENOMEM;
269 return NULL;
270 }
271 memcpy(buffer + pos, *p, len); /* copy content */
272 buffer[pos + len] = '\0';
273 *q = buffer + pos; /* set copied pointer to copied content */
274 pos += len + 1;
275 }
276 *++q = 0; /* null terminate the pointer list */
277 h->h_aliases = h_aliases; /* copy pointer to pointers */
278
279 return h;
280 }
281 #endif
282
283 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
284 static wxMutex nameLock;
285 #endif
286 struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h,
287 void *buffer, int size, int *err)
288
289 {
290 struct hostent *he = NULL;
291 *err = 0;
292 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
293 if (gethostbyname_r(hostname, h, (char*)buffer, size, &he, err))
294 he = NULL;
295 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
296 he = gethostbyname_r(hostname, h, (char*)buffer, size, err);
297 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
298 if (gethostbyname_r(hostname, h, (struct hostent_data*) buffer))
299 {
300 he = NULL;
301 *err = h_errno;
302 }
303 else
304 he = h;
305 #elif defined(HAVE_GETHOSTBYNAME)
306 #if wxUSE_THREADS
307 wxMutexLocker locker(nameLock);
308 #endif
309 he = gethostbyname(hostname);
310 if (!he)
311 *err = h_errno;
312 else
313 he = deepCopyHostent(h, he, (char*)buffer, size, err);
314 #endif
315 return he;
316 }
317
318 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
319 static wxMutex addrLock;
320 #endif
321 struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size,
322 int proto, struct hostent *h,
323 void *buffer, int size, int *err)
324 {
325 struct hostent *he = NULL;
326 *err = 0;
327 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
328 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
329 (char*)buffer, size, &he, err))
330 he = NULL;
331 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
332 he = gethostbyaddr_r(addr_buf, buf_size, proto, h, (char*)buffer, size, err);
333 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
334 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
335 (struct hostent_data*) buffer))
336 {
337 he = NULL;
338 *err = h_errno;
339 }
340 else
341 he = h;
342 #elif defined(HAVE_GETHOSTBYNAME)
343 #if wxUSE_THREADS
344 wxMutexLocker locker(addrLock);
345 #endif
346 he = gethostbyaddr(addr_buf, buf_size, proto);
347 if (!he)
348 *err = h_errno;
349 else
350 he = deepCopyHostent(h, he, (char*)buffer, size, err);
351 #endif
352 return he;
353 }
354
355 #if defined(HAVE_GETSERVBYNAME)
356 static struct servent * deepCopyServent(struct servent *s,
357 const struct servent *se,
358 char *buffer, int size)
359 {
360 /* copy plain old structure */
361 memcpy(s, se, sizeof(struct servent));
362
363 /* copy name */
364 int len = strlen(s->s_name);
365 if (len >= size)
366 {
367 return NULL;
368 }
369 memcpy(buffer, s->s_name, len);
370 buffer[len] = '\0';
371 s->s_name = buffer;
372
373 /* track position in the buffer */
374 int pos = len + 1;
375
376 /* copy protocol */
377 len = strlen(s->s_proto);
378 if (pos + len >= size)
379 {
380 return NULL;
381 }
382 memcpy(buffer + pos, s->s_proto, len);
383 buffer[pos + len] = '\0';
384 s->s_proto = buffer + pos;
385
386 /* track position in the buffer */
387 pos += len + 1;
388
389 /* ensure pointer alignment */
390 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
391 if(misalign < sizeof(char *))
392 pos += misalign;
393
394 /* leave space for pointer list */
395 char **p = s->s_aliases, **q;
396 char **s_aliases = (char **)(buffer + pos);
397 while(*(p++) != 0)
398 pos += sizeof(char *);
399
400 /* copy addresses and fill new pointer list */
401 for (p = s->s_aliases, q = s_aliases; *p != 0; p++, q++){
402 len = strlen(*p);
403 if (size <= pos + len)
404 {
405 return NULL;
406 }
407 memcpy(buffer + pos, *p, len); /* copy content */
408 buffer[pos + len] = '\0';
409 *q = buffer + pos; /* set copied pointer to copied content */
410 pos += len + 1;
411 }
412 *++q = 0; /* null terminate the pointer list */
413 s->s_aliases = s_aliases; /* copy pointer to pointers */
414 return s;
415 }
416 #endif
417
418 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
419 static wxMutex servLock;
420 #endif
421 struct servent *wxGetservbyname_r(const char *port, const char *protocol,
422 struct servent *serv, void *buffer, int size)
423 {
424 struct servent *se = NULL;
425 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
426 if (getservbyname_r(port, protocol, serv, (char*)buffer, size, &se))
427 se = NULL;
428 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
429 se = getservbyname_r(port, protocol, serv, (char*)buffer, size);
430 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
431 if (getservbyname_r(port, protocol, serv, (struct servent_data*) buffer))
432 se = NULL;
433 else
434 se = serv;
435 #elif defined(HAVE_GETSERVBYNAME)
436 #if wxUSE_THREADS
437 wxMutexLocker locker(servLock);
438 #endif
439 se = getservbyname(port, protocol);
440 if (se)
441 se = deepCopyServent(serv, se, (char*)buffer, size);
442 #endif
443 return se;
444 }
445
446 /* debugging helpers */
447 #ifdef __GSOCKET_DEBUG__
448 # define GSocket_Debug(args) printf args
449 #else
450 # define GSocket_Debug(args)
451 #endif /* __GSOCKET_DEBUG__ */
452
453 #if wxUSE_IPV6
454 typedef struct sockaddr_storage wxSockAddr;
455 #else
456 typedef struct sockaddr wxSockAddr;
457 #endif
458
459 /* Table of GUI-related functions. We must call them indirectly because
460 * of wxBase and GUI separation: */
461
462 bool GSocket_Init()
463 {
464 GSocketManager * const manager = GSocketManager::Get();
465 return manager && manager->OnInit();
466 }
467
468 void GSocket_Cleanup()
469 {
470 GSocketManager * const manager = GSocketManager::Get();
471 if ( manager )
472 manager->OnExit();
473 }
474
475 /* Constructors / Destructors for GSocket */
476
477 GSocket::GSocket()
478 {
479 int i;
480
481 m_fd = INVALID_SOCKET;
482 m_handler = NULL;
483
484 for (i=0;i<GSOCK_MAX_EVENT;i++)
485 {
486 m_cbacks[i] = NULL;
487 }
488 m_detected = 0;
489 m_local = NULL;
490 m_peer = NULL;
491 m_error = GSOCK_NOERROR;
492 m_server = false;
493 m_stream = true;
494 m_gui_dependent = NULL;
495 m_non_blocking = false;
496 m_reusable = false;
497 m_broadcast = false;
498 m_dobind = true;
499 m_timeout = 10*60*1000;
500 /* 10 minutes * 60 sec * 1000 millisec */
501 m_establishing = false;
502 m_use_events = false;
503 m_initialRecvBufferSize = -1;
504 m_initialSendBufferSize = -1;
505
506 m_ok = GSocketManager::Get()->Init_Socket(this);
507 }
508
509 void GSocket::Close()
510 {
511 if (m_use_events)
512 DisableEvents();
513
514 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
515 will close the socket during Disable_Events. However, it will only do this
516 if it is being used. That is, it won't do it in a console program. To
517 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
518 if it has closed the socket which indicates to us (at runtime, instead of
519 at compile time as this had been before) that the socket has already
520 been closed.
521 */
522 if(m_fd != INVALID_SOCKET)
523 close(m_fd);
524 m_fd = INVALID_SOCKET;
525 }
526
527 GSocket::~GSocket()
528 {
529 assert(this);
530
531 /* Check that the socket is really shutdowned */
532 if (m_fd != INVALID_SOCKET)
533 Shutdown();
534
535 GSocketManager::Get()->Destroy_Socket(this);
536
537 delete m_handler;
538
539 /* Destroy private addresses */
540 if (m_local)
541 GAddress_destroy(m_local);
542
543 if (m_peer)
544 GAddress_destroy(m_peer);
545
546 }
547
548 /* GSocket_Shutdown:
549 * Disallow further read/write operations on this socket, close
550 * the fd and disable all callbacks.
551 */
552 void GSocket::Shutdown()
553 {
554 int evt;
555
556 assert(this);
557
558 /* Don't allow events to fire after socket has been closed */
559 if (m_use_events)
560 DisableEvents();
561
562 /* If socket has been created, shutdown it */
563 if (m_fd != INVALID_SOCKET)
564 {
565 shutdown(m_fd, 1);
566 Close();
567 }
568
569 /* Disable GUI callbacks */
570 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
571 m_cbacks[evt] = NULL;
572
573 m_detected = GSOCK_LOST_FLAG;
574 }
575
576 /* Address handling */
577
578 /* GSocket_SetLocal:
579 * GSocket_GetLocal:
580 * GSocket_SetPeer:
581 * GSocket_GetPeer:
582 * Set or get the local or peer address for this socket. The 'set'
583 * functions return GSOCK_NOERROR on success, an error code otherwise.
584 * The 'get' functions return a pointer to a GAddress object on success,
585 * or NULL otherwise, in which case they set the error code of the
586 * corresponding GSocket.
587 *
588 * Error codes:
589 * GSOCK_INVSOCK - the socket is not valid.
590 * GSOCK_INVADDR - the address is not valid.
591 */
592 GSocketError GSocket::SetLocal(GAddress *address)
593 {
594 assert(this);
595
596 /* the socket must be initialized, or it must be a server */
597 if ((m_fd != INVALID_SOCKET && !m_server))
598 {
599 m_error = GSOCK_INVSOCK;
600 return GSOCK_INVSOCK;
601 }
602
603 /* check address */
604 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
605 {
606 m_error = GSOCK_INVADDR;
607 return GSOCK_INVADDR;
608 }
609
610 if (m_local)
611 GAddress_destroy(m_local);
612
613 m_local = GAddress_copy(address);
614
615 return GSOCK_NOERROR;
616 }
617
618 GSocketError GSocket::SetPeer(GAddress *address)
619 {
620 assert(this);
621
622 /* check address */
623 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
624 {
625 m_error = GSOCK_INVADDR;
626 return GSOCK_INVADDR;
627 }
628
629 if (m_peer)
630 GAddress_destroy(m_peer);
631
632 m_peer = GAddress_copy(address);
633
634 return GSOCK_NOERROR;
635 }
636
637 GAddress *GSocket::GetLocal()
638 {
639 GAddress *address;
640 wxSockAddr addr;
641 WX_SOCKLEN_T size = sizeof(addr);
642 GSocketError err;
643
644 assert(this);
645
646 /* try to get it from the m_local var first */
647 if (m_local)
648 return GAddress_copy(m_local);
649
650 /* else, if the socket is initialized, try getsockname */
651 if (m_fd == INVALID_SOCKET)
652 {
653 m_error = GSOCK_INVSOCK;
654 return NULL;
655 }
656
657 if (getsockname(m_fd, (sockaddr*)&addr, (WX_SOCKLEN_T *) &size) < 0)
658 {
659 m_error = GSOCK_IOERR;
660 return NULL;
661 }
662
663 /* got a valid address from getsockname, create a GAddress object */
664 address = GAddress_new();
665 if (address == NULL)
666 {
667 m_error = GSOCK_MEMERR;
668 return NULL;
669 }
670
671 err = _GAddress_translate_from(address, (sockaddr*)&addr, size);
672 if (err != GSOCK_NOERROR)
673 {
674 GAddress_destroy(address);
675 m_error = err;
676 return NULL;
677 }
678
679 return address;
680 }
681
682 GAddress *GSocket::GetPeer()
683 {
684 assert(this);
685
686 /* try to get it from the m_peer var */
687 if (m_peer)
688 return GAddress_copy(m_peer);
689
690 return NULL;
691 }
692
693 /* Server specific parts */
694
695 /* GSocket_SetServer:
696 * Sets up this socket as a server. The local address must have been
697 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
698 * Returns GSOCK_NOERROR on success, one of the following otherwise:
699 *
700 * Error codes:
701 * GSOCK_INVSOCK - the socket is in use.
702 * GSOCK_INVADDR - the local address has not been set.
703 * GSOCK_IOERR - low-level error.
704 */
705 GSocketError GSocket::SetServer()
706 {
707 int arg = 1;
708
709 assert(this);
710
711 /* must not be in use */
712 if (m_fd != INVALID_SOCKET)
713 {
714 m_error = GSOCK_INVSOCK;
715 return GSOCK_INVSOCK;
716 }
717
718 /* the local addr must have been set */
719 if (!m_local)
720 {
721 m_error = GSOCK_INVADDR;
722 return GSOCK_INVADDR;
723 }
724
725 /* Initialize all fields */
726 m_stream = true;
727 m_server = true;
728
729 /* Create the socket */
730 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
731
732 if (m_fd == INVALID_SOCKET)
733 {
734 m_error = GSOCK_IOERR;
735 return GSOCK_IOERR;
736 }
737
738 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
739 #ifdef SO_NOSIGPIPE
740 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
741 #endif
742
743 ioctl(m_fd, FIONBIO, &arg);
744 if (m_use_events)
745 EnableEvents();
746
747 /* allow a socket to re-bind if the socket is in the TIME_WAIT
748 state after being previously closed.
749 */
750 if (m_reusable)
751 {
752 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
753 #ifdef SO_REUSEPORT
754 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
755 #endif
756 }
757
758 /* Bind to the local address,
759 * retrieve the actual address bound,
760 * and listen up to 5 connections.
761 */
762 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
763 (getsockname(m_fd,
764 m_local->m_addr,
765 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
766 (listen(m_fd, 5) != 0))
767 {
768 Close();
769 m_error = GSOCK_IOERR;
770 return GSOCK_IOERR;
771 }
772
773 return GSOCK_NOERROR;
774 }
775
776 /* GSocket_WaitConnection:
777 * Waits for an incoming client connection. Returns a pointer to
778 * a GSocket object, or NULL if there was an error, in which case
779 * the last error field will be updated for the calling GSocket.
780 *
781 * Error codes (set in the calling GSocket)
782 * GSOCK_INVSOCK - the socket is not valid or not a server.
783 * GSOCK_TIMEDOUT - timeout, no incoming connections.
784 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
785 * GSOCK_MEMERR - couldn't allocate memory.
786 * GSOCK_IOERR - low-level error.
787 */
788 GSocket *GSocket::WaitConnection()
789 {
790 wxSockAddr from;
791 WX_SOCKLEN_T fromlen = sizeof(from);
792 GSocket *connection;
793 GSocketError err;
794 int arg = 1;
795
796 assert(this);
797
798 /* If the socket has already been created, we exit immediately */
799 if (m_fd == INVALID_SOCKET || !m_server)
800 {
801 m_error = GSOCK_INVSOCK;
802 return NULL;
803 }
804
805 /* Create a GSocket object for the new connection */
806 connection = GSocket_new();
807
808 if (!connection)
809 {
810 m_error = GSOCK_MEMERR;
811 return NULL;
812 }
813
814 /* Wait for a connection (with timeout) */
815 if (Input_Timeout() == GSOCK_TIMEDOUT)
816 {
817 delete connection;
818 /* m_error set by _GSocket_Input_Timeout */
819 return NULL;
820 }
821
822 connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
823
824 /* Reenable CONNECTION events */
825 Enable(GSOCK_CONNECTION);
826
827 if (connection->m_fd == INVALID_SOCKET)
828 {
829 if (errno == EWOULDBLOCK)
830 m_error = GSOCK_WOULDBLOCK;
831 else
832 m_error = GSOCK_IOERR;
833
834 delete connection;
835 return NULL;
836 }
837
838 /* Initialize all fields */
839 connection->m_server = false;
840 connection->m_stream = true;
841
842 /* Setup the peer address field */
843 connection->m_peer = GAddress_new();
844 if (!connection->m_peer)
845 {
846 delete connection;
847 m_error = GSOCK_MEMERR;
848 return NULL;
849 }
850
851 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
852 if (err != GSOCK_NOERROR)
853 {
854 delete connection;
855 m_error = err;
856 return NULL;
857 }
858
859 #if defined(__EMX__) || defined(__VISAGECPP__)
860 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
861 #else
862 ioctl(connection->m_fd, FIONBIO, &arg);
863 #endif
864 if (m_use_events)
865 connection->Notify(true);
866
867 return connection;
868 }
869
870 void GSocket::Notify(bool flag)
871 {
872 if (flag == m_use_events)
873 return;
874 m_use_events = flag;
875 EnableEvents(flag);
876 }
877
878 void GSocket::EnableEvents(bool flag)
879 {
880 if (flag)
881 GSocketManager::Get()->Enable_Events(this);
882 else
883 GSocketManager::Get()->Disable_Events(this);
884 }
885
886 bool GSocket::SetReusable()
887 {
888 /* socket must not be null, and must not be in use/already bound */
889 if (this && m_fd == INVALID_SOCKET)
890 {
891 m_reusable = true;
892
893 return true;
894 }
895
896 return false;
897 }
898
899 bool GSocket::SetBroadcast()
900 {
901 /* socket must not be in use/already bound */
902 if (m_fd == INVALID_SOCKET) {
903 m_broadcast = true;
904 return true;
905 }
906 return false;
907 }
908
909 bool GSocket::DontDoBind()
910 {
911 /* socket must not be in use/already bound */
912 if (m_fd == INVALID_SOCKET) {
913 m_dobind = false;
914 return true;
915 }
916 return false;
917 }
918
919 /* Client specific parts */
920
921 /* GSocket_Connect:
922 * For stream (connection oriented) sockets, GSocket_Connect() tries
923 * to establish a client connection to a server using the peer address
924 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
925 * connection has been successfully established, or one of the error
926 * codes listed below. Note that for nonblocking sockets, a return
927 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
928 * request can be completed later; you should use GSocket_Select()
929 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
930 * corresponding asynchronous events.
931 *
932 * For datagram (non connection oriented) sockets, GSocket_Connect()
933 * just sets the peer address established with GSocket_SetPeer() as
934 * default destination.
935 *
936 * Error codes:
937 * GSOCK_INVSOCK - the socket is in use or not valid.
938 * GSOCK_INVADDR - the peer address has not been established.
939 * GSOCK_TIMEDOUT - timeout, the connection failed.
940 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
941 * GSOCK_MEMERR - couldn't allocate memory.
942 * GSOCK_IOERR - low-level error.
943 */
944 GSocketError GSocket::Connect(GSocketStream stream)
945 {
946 int err, ret;
947 int arg = 1;
948
949 assert(this);
950
951 /* Enable CONNECTION events (needed for nonblocking connections) */
952 Enable(GSOCK_CONNECTION);
953
954 if (m_fd != INVALID_SOCKET)
955 {
956 m_error = GSOCK_INVSOCK;
957 return GSOCK_INVSOCK;
958 }
959
960 if (!m_peer)
961 {
962 m_error = GSOCK_INVADDR;
963 return GSOCK_INVADDR;
964 }
965
966 /* Streamed or dgram socket? */
967 m_stream = (stream == GSOCK_STREAMED);
968 m_server = false;
969 m_establishing = false;
970
971 /* Create the socket */
972 m_fd = socket(m_peer->m_realfamily,
973 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
974
975 if (m_fd == INVALID_SOCKET)
976 {
977 m_error = GSOCK_IOERR;
978 return GSOCK_IOERR;
979 }
980
981 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
982 #ifdef SO_NOSIGPIPE
983 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
984 #endif
985
986 #if defined(__EMX__) || defined(__VISAGECPP__)
987 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
988 #else
989 ioctl(m_fd, FIONBIO, &arg);
990 #endif
991
992 // If the reuse flag is set, use the applicable socket reuse flags(s)
993 if (m_reusable)
994 {
995 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
996 #ifdef SO_REUSEPORT
997 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
998 #endif
999 }
1000
1001 if (m_initialRecvBufferSize >= 0)
1002 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
1003 if (m_initialSendBufferSize >= 0)
1004 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
1005
1006 // If a local address has been set, then we need to bind to it before calling connect
1007 if (m_local && m_local->m_addr)
1008 {
1009 bind(m_fd, m_local->m_addr, m_local->m_len);
1010 }
1011
1012 /* Connect it to the peer address, with a timeout (see below) */
1013 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
1014
1015 /* We only call Enable_Events if we know we aren't shutting down the socket.
1016 * NB: Enable_Events needs to be called whether the socket is blocking or
1017 * non-blocking, it just shouldn't be called prior to knowing there is a
1018 * connection _if_ blocking sockets are being used.
1019 * If connect above returns 0, we are already connected and need to make the
1020 * call to Enable_Events now.
1021 */
1022
1023 if (m_use_events && (m_non_blocking || ret == 0))
1024 EnableEvents();
1025
1026 if (ret == -1)
1027 {
1028 err = errno;
1029
1030 /* If connect failed with EINPROGRESS and the GSocket object
1031 * is in blocking mode, we select() for the specified timeout
1032 * checking for writability to see if the connection request
1033 * completes.
1034 */
1035 if ((err == EINPROGRESS) && (!m_non_blocking))
1036 {
1037 if (Output_Timeout() == GSOCK_TIMEDOUT)
1038 {
1039 Close();
1040 /* m_error is set in _GSocket_Output_Timeout */
1041 return GSOCK_TIMEDOUT;
1042 }
1043 else
1044 {
1045 int error;
1046 SOCKOPTLEN_T len = sizeof(error);
1047
1048 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
1049 if (m_use_events)
1050 EnableEvents();
1051
1052 if (!error)
1053 return GSOCK_NOERROR;
1054 }
1055 }
1056
1057 /* If connect failed with EINPROGRESS and the GSocket object
1058 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1059 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1060 * this way if the connection completes, a GSOCK_CONNECTION
1061 * event will be generated, if enabled.
1062 */
1063 if ((err == EINPROGRESS) && (m_non_blocking))
1064 {
1065 m_establishing = true;
1066 m_error = GSOCK_WOULDBLOCK;
1067 return GSOCK_WOULDBLOCK;
1068 }
1069
1070 /* If connect failed with an error other than EINPROGRESS,
1071 * then the call to GSocket_Connect has failed.
1072 */
1073 Close();
1074 m_error = GSOCK_IOERR;
1075
1076 return GSOCK_IOERR;
1077 }
1078
1079 return GSOCK_NOERROR;
1080 }
1081
1082 /* Datagram sockets */
1083
1084 /* GSocket_SetNonOriented:
1085 * Sets up this socket as a non-connection oriented (datagram) socket.
1086 * Before using this function, the local address must have been set
1087 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1088 * on success, or one of the following otherwise.
1089 *
1090 * Error codes:
1091 * GSOCK_INVSOCK - the socket is in use.
1092 * GSOCK_INVADDR - the local address has not been set.
1093 * GSOCK_IOERR - low-level error.
1094 */
1095 GSocketError GSocket::SetNonOriented()
1096 {
1097 int arg = 1;
1098
1099 assert(this);
1100
1101 if (m_fd != INVALID_SOCKET)
1102 {
1103 m_error = GSOCK_INVSOCK;
1104 return GSOCK_INVSOCK;
1105 }
1106
1107 if (!m_local)
1108 {
1109 m_error = GSOCK_INVADDR;
1110 return GSOCK_INVADDR;
1111 }
1112
1113 /* Initialize all fields */
1114 m_stream = false;
1115 m_server = false;
1116
1117 /* Create the socket */
1118 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
1119
1120 if (m_fd == INVALID_SOCKET)
1121 {
1122 m_error = GSOCK_IOERR;
1123 return GSOCK_IOERR;
1124 }
1125 #if defined(__EMX__) || defined(__VISAGECPP__)
1126 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
1127 #else
1128 ioctl(m_fd, FIONBIO, &arg);
1129 #endif
1130 if (m_use_events)
1131 EnableEvents();
1132
1133 if (m_reusable)
1134 {
1135 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
1136 #ifdef SO_REUSEPORT
1137 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
1138 #endif
1139 }
1140
1141 if (m_broadcast)
1142 {
1143 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
1144 }
1145 if (m_dobind)
1146 {
1147 /* Bind to the local address,
1148 * and retrieve the actual address bound.
1149 */
1150 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
1151 (getsockname(m_fd,
1152 m_local->m_addr,
1153 (WX_SOCKLEN_T *) &m_local->m_len) != 0))
1154 {
1155 Close();
1156 m_error = GSOCK_IOERR;
1157 return GSOCK_IOERR;
1158 }
1159 }
1160 return GSOCK_NOERROR;
1161 }
1162
1163 /* Generic IO */
1164
1165 /* Like recv(), send(), ... */
1166 int GSocket::Read(char *buffer, int size)
1167 {
1168 int ret;
1169
1170 assert(this);
1171
1172 if (m_fd == INVALID_SOCKET || m_server)
1173 {
1174 m_error = GSOCK_INVSOCK;
1175 return -1;
1176 }
1177
1178 /* Disable events during query of socket status */
1179 Disable(GSOCK_INPUT);
1180
1181 /* If the socket is blocking, wait for data (with a timeout) */
1182 if (Input_Timeout() == GSOCK_TIMEDOUT) {
1183 m_error = GSOCK_TIMEDOUT;
1184 /* Don't return here immediately, otherwise socket events would not be
1185 * re-enabled! */
1186 ret = -1;
1187 }
1188 else
1189 {
1190 /* Read the data */
1191 if (m_stream)
1192 ret = Recv_Stream(buffer, size);
1193 else
1194 ret = Recv_Dgram(buffer, size);
1195
1196 /*
1197 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1198 * socket and empty datagrams are possible), then the connection has been
1199 * gracefully closed.
1200 *
1201 * Otherwise, recv has returned an error (-1), in which case we have lost
1202 * the socket only if errno does _not_ indicate that there may be more data
1203 * to read.
1204 */
1205 if ((ret == 0) && m_stream)
1206 {
1207 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1208 if (m_use_events)
1209 {
1210 m_detected = GSOCK_LOST_FLAG;
1211 Detected_Read();
1212 return 0;
1213 }
1214 }
1215 else if (ret == -1)
1216 {
1217 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1218 m_error = GSOCK_WOULDBLOCK;
1219 else
1220 m_error = GSOCK_IOERR;
1221 }
1222 }
1223
1224 /* Enable events again now that we are done processing */
1225 Enable(GSOCK_INPUT);
1226
1227 return ret;
1228 }
1229
1230 int GSocket::Write(const char *buffer, int size)
1231 {
1232 int ret;
1233
1234 assert(this);
1235
1236 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
1237
1238 if (m_fd == INVALID_SOCKET || m_server)
1239 {
1240 m_error = GSOCK_INVSOCK;
1241 return -1;
1242 }
1243
1244 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
1245
1246 /* If the socket is blocking, wait for writability (with a timeout) */
1247 if (Output_Timeout() == GSOCK_TIMEDOUT)
1248 return -1;
1249
1250 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
1251
1252 /* Write the data */
1253 if (m_stream)
1254 ret = Send_Stream(buffer, size);
1255 else
1256 ret = Send_Dgram(buffer, size);
1257
1258 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
1259
1260 if (ret == -1)
1261 {
1262 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1263 {
1264 m_error = GSOCK_WOULDBLOCK;
1265 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1266 }
1267 else
1268 {
1269 m_error = GSOCK_IOERR;
1270 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1271 }
1272
1273 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1274 * in MSW). Once the first OUTPUT event is received, users can assume
1275 * that the socket is writable until a read operation fails. Only then
1276 * will further OUTPUT events be posted.
1277 */
1278 Enable(GSOCK_OUTPUT);
1279
1280 return -1;
1281 }
1282
1283 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
1284
1285 return ret;
1286 }
1287
1288 /* Flags */
1289
1290 /* GSocket_SetNonBlocking:
1291 * Sets the socket to non-blocking mode. All IO calls will return
1292 * immediately.
1293 */
1294 void GSocket::SetNonBlocking(bool non_block)
1295 {
1296 assert(this);
1297
1298 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1299
1300 m_non_blocking = non_block;
1301 }
1302
1303 /* GSocket_SetTimeout:
1304 * Sets the timeout for blocking calls. Time is expressed in
1305 * milliseconds.
1306 */
1307 void GSocket::SetTimeout(unsigned long millisec)
1308 {
1309 assert(this);
1310
1311 m_timeout = millisec;
1312 }
1313
1314 /* GSocket_GetError:
1315 * Returns the last error occurred for this socket. Note that successful
1316 * operations do not clear this back to GSOCK_NOERROR, so use it only
1317 * after an error.
1318 */
1319 GSocketError WXDLLIMPEXP_NET GSocket::GetError()
1320 {
1321 assert(this);
1322
1323 return m_error;
1324 }
1325
1326 /* Callbacks */
1327
1328 /* GSOCK_INPUT:
1329 * There is data to be read in the input buffer. If, after a read
1330 * operation, there is still data available, the callback function will
1331 * be called again.
1332 * GSOCK_OUTPUT:
1333 * The socket is available for writing. That is, the next write call
1334 * won't block. This event is generated only once, when the connection is
1335 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1336 * when the output buffer empties again. This means that the app should
1337 * assume that it can write since the first OUTPUT event, and no more
1338 * OUTPUT events will be generated unless an error occurs.
1339 * GSOCK_CONNECTION:
1340 * Connection successfully established, for client sockets, or incoming
1341 * client connection, for server sockets. Wait for this event (also watch
1342 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1343 * GSOCK_LOST:
1344 * The connection is lost (or a connection request failed); this could
1345 * be due to a failure, or due to the peer closing it gracefully.
1346 */
1347
1348 /* GSocket_SetCallback:
1349 * Enables the callbacks specified by 'flags'. Note that 'flags'
1350 * may be a combination of flags OR'ed toghether, so the same
1351 * callback function can be made to accept different events.
1352 * The callback function must have the following prototype:
1353 *
1354 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1355 */
1356 void GSocket::SetCallback(GSocketEventFlags flags,
1357 GSocketCallback callback, char *cdata)
1358 {
1359 int count;
1360
1361 assert(this);
1362
1363 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1364 {
1365 if ((flags & (1 << count)) != 0)
1366 {
1367 m_cbacks[count] = callback;
1368 m_data[count] = cdata;
1369 }
1370 }
1371 }
1372
1373 /* GSocket_UnsetCallback:
1374 * Disables all callbacks specified by 'flags', which may be a
1375 * combination of flags OR'ed toghether.
1376 */
1377 void GSocket::UnsetCallback(GSocketEventFlags flags)
1378 {
1379 int count;
1380
1381 assert(this);
1382
1383 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1384 {
1385 if ((flags & (1 << count)) != 0)
1386 {
1387 m_cbacks[count] = NULL;
1388 m_data[count] = NULL;
1389 }
1390 }
1391 }
1392
1393 GSocketError GSocket::GetSockOpt(int level, int optname,
1394 void *optval, int *optlen)
1395 {
1396 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
1397 return GSOCK_NOERROR;
1398
1399 return GSOCK_OPTERR;
1400 }
1401
1402 GSocketError GSocket::SetSockOpt(int level, int optname,
1403 const void *optval, int optlen)
1404 {
1405 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
1406 return GSOCK_NOERROR;
1407
1408 return GSOCK_OPTERR;
1409 }
1410
1411 #define CALL_CALLBACK(socket, event) { \
1412 socket->Disable(event); \
1413 if (socket->m_cbacks[event]) \
1414 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1415 }
1416
1417
1418 void GSocket::Enable(GSocketEvent event)
1419 {
1420 if (m_use_events)
1421 {
1422 m_detected &= ~(1 << event);
1423 GSocketManager::Get()->Install_Callback(this, event);
1424 }
1425 }
1426
1427 void GSocket::Disable(GSocketEvent event)
1428 {
1429 if (m_use_events)
1430 {
1431 m_detected |= (1 << event);
1432 GSocketManager::Get()->Uninstall_Callback(this, event);
1433 }
1434 }
1435
1436 /* _GSocket_Input_Timeout:
1437 * For blocking sockets, wait until data is available or
1438 * until timeout ellapses.
1439 */
1440 GSocketError GSocket::Input_Timeout()
1441 {
1442 struct timeval tv;
1443 fd_set readfds;
1444 int ret;
1445
1446 /* Linux select() will overwrite the struct on return */
1447 tv.tv_sec = (m_timeout / 1000);
1448 tv.tv_usec = (m_timeout % 1000) * 1000;
1449
1450 if (!m_non_blocking)
1451 {
1452 wxFD_ZERO(&readfds);
1453 wxFD_SET(m_fd, &readfds);
1454 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
1455 if (ret == 0)
1456 {
1457 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1458 m_error = GSOCK_TIMEDOUT;
1459 return GSOCK_TIMEDOUT;
1460 }
1461
1462 if (ret == -1)
1463 {
1464 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1465 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1466 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1467 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1468 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1469 m_error = GSOCK_TIMEDOUT;
1470 return GSOCK_TIMEDOUT;
1471 }
1472 }
1473
1474 return GSOCK_NOERROR;
1475 }
1476
1477 /* _GSocket_Output_Timeout:
1478 * For blocking sockets, wait until data can be sent without
1479 * blocking or until timeout ellapses.
1480 */
1481 GSocketError GSocket::Output_Timeout()
1482 {
1483 struct timeval tv;
1484 fd_set writefds;
1485 int ret;
1486
1487 /* Linux select() will overwrite the struct on return */
1488 tv.tv_sec = (m_timeout / 1000);
1489 tv.tv_usec = (m_timeout % 1000) * 1000;
1490
1491 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
1492
1493 if (!m_non_blocking)
1494 {
1495 wxFD_ZERO(&writefds);
1496 wxFD_SET(m_fd, &writefds);
1497 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
1498 if (ret == 0)
1499 {
1500 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1501 m_error = GSOCK_TIMEDOUT;
1502 return GSOCK_TIMEDOUT;
1503 }
1504
1505 if (ret == -1)
1506 {
1507 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1508 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1509 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1510 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1511 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1512 m_error = GSOCK_TIMEDOUT;
1513 return GSOCK_TIMEDOUT;
1514 }
1515
1516 if ( ! wxFD_ISSET(m_fd, &writefds) )
1517 {
1518 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1519 }
1520 else
1521 {
1522 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1523 }
1524 }
1525 else
1526 {
1527 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1528 }
1529
1530 return GSOCK_NOERROR;
1531 }
1532
1533 int GSocket::Recv_Stream(char *buffer, int size)
1534 {
1535 int ret;
1536 do
1537 {
1538 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1539 }
1540 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1541
1542 return ret;
1543 }
1544
1545 int GSocket::Recv_Dgram(char *buffer, int size)
1546 {
1547 wxSockAddr from;
1548 WX_SOCKLEN_T fromlen = sizeof(from);
1549 int ret;
1550 GSocketError err;
1551
1552 fromlen = sizeof(from);
1553
1554 do
1555 {
1556 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
1557 }
1558 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1559
1560 if (ret == -1)
1561 return -1;
1562
1563 /* Translate a system address into a GSocket address */
1564 if (!m_peer)
1565 {
1566 m_peer = GAddress_new();
1567 if (!m_peer)
1568 {
1569 m_error = GSOCK_MEMERR;
1570 return -1;
1571 }
1572 }
1573
1574 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
1575 if (err != GSOCK_NOERROR)
1576 {
1577 GAddress_destroy(m_peer);
1578 m_peer = NULL;
1579 m_error = err;
1580 return -1;
1581 }
1582
1583 return ret;
1584 }
1585
1586 int GSocket::Send_Stream(const char *buffer, int size)
1587 {
1588 int ret;
1589
1590 MASK_SIGNAL();
1591
1592 do
1593 {
1594 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1595 }
1596 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1597
1598 UNMASK_SIGNAL();
1599
1600 return ret;
1601 }
1602
1603 int GSocket::Send_Dgram(const char *buffer, int size)
1604 {
1605 struct sockaddr *addr;
1606 int len, ret;
1607 GSocketError err;
1608
1609 if (!m_peer)
1610 {
1611 m_error = GSOCK_INVADDR;
1612 return -1;
1613 }
1614
1615 err = _GAddress_translate_to(m_peer, &addr, &len);
1616 if (err != GSOCK_NOERROR)
1617 {
1618 m_error = err;
1619 return -1;
1620 }
1621
1622 MASK_SIGNAL();
1623
1624 do
1625 {
1626 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1627 }
1628 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1629
1630 UNMASK_SIGNAL();
1631
1632 /* Frees memory allocated from _GAddress_translate_to */
1633 free(addr);
1634
1635 return ret;
1636 }
1637
1638 void GSocket::Detected_Read()
1639 {
1640 char c;
1641
1642 /* Safeguard against straggling call to Detected_Read */
1643 if (m_fd == INVALID_SOCKET)
1644 {
1645 return;
1646 }
1647
1648 /* If we have already detected a LOST event, then don't try
1649 * to do any further processing.
1650 */
1651 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1652 {
1653 m_establishing = false;
1654
1655 CALL_CALLBACK(this, GSOCK_LOST);
1656 Shutdown();
1657 return;
1658 }
1659
1660 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1661
1662 if (num > 0)
1663 {
1664 CALL_CALLBACK(this, GSOCK_INPUT);
1665 }
1666 else
1667 {
1668 if (m_server && m_stream)
1669 {
1670 CALL_CALLBACK(this, GSOCK_CONNECTION);
1671 }
1672 else if (num == 0)
1673 {
1674 if (m_stream)
1675 {
1676 /* graceful shutdown */
1677 CALL_CALLBACK(this, GSOCK_LOST);
1678 Shutdown();
1679 }
1680 else
1681 {
1682 /* Empty datagram received */
1683 CALL_CALLBACK(this, GSOCK_INPUT);
1684 }
1685 }
1686 else
1687 {
1688 /* Do not throw a lost event in cases where the socket isn't really lost */
1689 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
1690 {
1691 CALL_CALLBACK(this, GSOCK_INPUT);
1692 }
1693 else
1694 {
1695 CALL_CALLBACK(this, GSOCK_LOST);
1696 Shutdown();
1697 }
1698 }
1699 }
1700 }
1701
1702 void GSocket::Detected_Write()
1703 {
1704 /* If we have already detected a LOST event, then don't try
1705 * to do any further processing.
1706 */
1707 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1708 {
1709 m_establishing = false;
1710
1711 CALL_CALLBACK(this, GSOCK_LOST);
1712 Shutdown();
1713 return;
1714 }
1715
1716 if (m_establishing && !m_server)
1717 {
1718 int error;
1719 SOCKOPTLEN_T len = sizeof(error);
1720
1721 m_establishing = false;
1722
1723 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1724
1725 if (error)
1726 {
1727 CALL_CALLBACK(this, GSOCK_LOST);
1728 Shutdown();
1729 }
1730 else
1731 {
1732 CALL_CALLBACK(this, GSOCK_CONNECTION);
1733 /* We have to fire this event by hand because CONNECTION (for clients)
1734 * and OUTPUT are internally the same and we just disabled CONNECTION
1735 * events with the above macro.
1736 */
1737 CALL_CALLBACK(this, GSOCK_OUTPUT);
1738 }
1739 }
1740 else
1741 {
1742 CALL_CALLBACK(this, GSOCK_OUTPUT);
1743 }
1744 }
1745
1746 /* Compatibility functions for GSocket */
1747 GSocket *GSocket_new(void)
1748 {
1749 GSocket *newsocket = new GSocket();
1750 if (newsocket->IsOk())
1751 return newsocket;
1752
1753 delete newsocket;
1754
1755 return NULL;
1756 }
1757
1758 /*
1759 * -------------------------------------------------------------------------
1760 * GAddress
1761 * -------------------------------------------------------------------------
1762 */
1763
1764 /* CHECK_ADDRESS verifies that the current address family is either
1765 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1766 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1767 * an appropiate error code.
1768 *
1769 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1770 */
1771 #define CHECK_ADDRESS(address, family) \
1772 { \
1773 if (address->m_family == GSOCK_NOFAMILY) \
1774 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1775 return address->m_error; \
1776 if (address->m_family != GSOCK_##family) \
1777 { \
1778 address->m_error = GSOCK_INVADDR; \
1779 return GSOCK_INVADDR; \
1780 } \
1781 }
1782
1783 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1784 { \
1785 if (address->m_family == GSOCK_NOFAMILY) \
1786 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1787 return retval; \
1788 if (address->m_family != GSOCK_##family) \
1789 { \
1790 address->m_error = GSOCK_INVADDR; \
1791 return retval; \
1792 } \
1793 }
1794
1795
1796 GAddress *GAddress_new(void)
1797 {
1798 GAddress *address;
1799
1800 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1801 return NULL;
1802
1803 address->m_family = GSOCK_NOFAMILY;
1804 address->m_addr = NULL;
1805 address->m_len = 0;
1806
1807 return address;
1808 }
1809
1810 GAddress *GAddress_copy(GAddress *address)
1811 {
1812 GAddress *addr2;
1813
1814 assert(address != NULL);
1815
1816 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1817 return NULL;
1818
1819 memcpy(addr2, address, sizeof(GAddress));
1820
1821 if (address->m_addr && address->m_len > 0)
1822 {
1823 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1824 if (addr2->m_addr == NULL)
1825 {
1826 free(addr2);
1827 return NULL;
1828 }
1829 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1830 }
1831
1832 return addr2;
1833 }
1834
1835 void GAddress_destroy(GAddress *address)
1836 {
1837 assert(address != NULL);
1838
1839 if (address->m_addr)
1840 free(address->m_addr);
1841
1842 free(address);
1843 }
1844
1845 void GAddress_SetFamily(GAddress *address, GAddressType type)
1846 {
1847 assert(address != NULL);
1848
1849 address->m_family = type;
1850 }
1851
1852 GAddressType GAddress_GetFamily(GAddress *address)
1853 {
1854 assert(address != NULL);
1855
1856 return address->m_family;
1857 }
1858
1859 GSocketError _GAddress_translate_from(GAddress *address,
1860 struct sockaddr *addr, int len)
1861 {
1862 address->m_realfamily = addr->sa_family;
1863 switch (addr->sa_family)
1864 {
1865 case AF_INET:
1866 address->m_family = GSOCK_INET;
1867 break;
1868 case AF_UNIX:
1869 address->m_family = GSOCK_UNIX;
1870 break;
1871 #if wxUSE_IPV6
1872 case AF_INET6:
1873 address->m_family = GSOCK_INET6;
1874 break;
1875 #endif // wxUSE_IPV6
1876 default:
1877 {
1878 address->m_error = GSOCK_INVOP;
1879 return GSOCK_INVOP;
1880 }
1881 }
1882
1883 if (address->m_addr)
1884 free(address->m_addr);
1885
1886 address->m_len = len;
1887 address->m_addr = (struct sockaddr *)malloc(len);
1888
1889 if (address->m_addr == NULL)
1890 {
1891 address->m_error = GSOCK_MEMERR;
1892 return GSOCK_MEMERR;
1893 }
1894
1895 memcpy(address->m_addr, addr, len);
1896
1897 return GSOCK_NOERROR;
1898 }
1899
1900 GSocketError _GAddress_translate_to(GAddress *address,
1901 struct sockaddr **addr, int *len)
1902 {
1903 if (!address->m_addr)
1904 {
1905 address->m_error = GSOCK_INVADDR;
1906 return GSOCK_INVADDR;
1907 }
1908
1909 *len = address->m_len;
1910 *addr = (struct sockaddr *)malloc(address->m_len);
1911 if (*addr == NULL)
1912 {
1913 address->m_error = GSOCK_MEMERR;
1914 return GSOCK_MEMERR;
1915 }
1916
1917 memcpy(*addr, address->m_addr, address->m_len);
1918 return GSOCK_NOERROR;
1919 }
1920
1921 /*
1922 * -------------------------------------------------------------------------
1923 * Internet address family
1924 * -------------------------------------------------------------------------
1925 */
1926
1927 GSocketError _GAddress_Init_INET(GAddress *address)
1928 {
1929 address->m_len = sizeof(struct sockaddr_in);
1930 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1931 if (address->m_addr == NULL)
1932 {
1933 address->m_error = GSOCK_MEMERR;
1934 return GSOCK_MEMERR;
1935 }
1936
1937 address->m_family = GSOCK_INET;
1938 address->m_realfamily = PF_INET;
1939 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1940 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1941
1942 return GSOCK_NOERROR;
1943 }
1944
1945 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1946 {
1947 struct hostent *he;
1948 struct in_addr *addr;
1949
1950 assert(address != NULL);
1951
1952 CHECK_ADDRESS(address, INET);
1953
1954 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1955
1956 /* If it is a numeric host name, convert it now */
1957 #if defined(HAVE_INET_ATON)
1958 if (inet_aton(hostname, addr) == 0)
1959 {
1960 #elif defined(HAVE_INET_ADDR)
1961 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
1962 {
1963 #else
1964 /* Use gethostbyname by default */
1965 #ifndef __WXMAC__
1966 int val = 1; /* VA doesn't like constants in conditional expressions */
1967 if (val)
1968 #endif
1969 {
1970 #endif
1971 struct in_addr *array_addr;
1972
1973 /* It is a real name, we solve it */
1974 struct hostent h;
1975 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1976 struct hostent_data buffer;
1977 #else
1978 char buffer[1024];
1979 #endif
1980 int err;
1981 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
1982 if (he == NULL)
1983 {
1984 /* Reset to invalid address */
1985 addr->s_addr = INADDR_NONE;
1986 address->m_error = GSOCK_NOHOST;
1987 return GSOCK_NOHOST;
1988 }
1989
1990 array_addr = (struct in_addr *) *(he->h_addr_list);
1991 addr->s_addr = array_addr[0].s_addr;
1992 }
1993
1994 return GSOCK_NOERROR;
1995 }
1996
1997
1998 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1999 {
2000 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2001 }
2002
2003 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2004 {
2005 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2006 }
2007
2008 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2009 unsigned long hostaddr)
2010 {
2011 struct in_addr *addr;
2012
2013 assert(address != NULL);
2014
2015 CHECK_ADDRESS(address, INET);
2016
2017 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2018 addr->s_addr = htonl(hostaddr);
2019
2020 return GSOCK_NOERROR;
2021 }
2022
2023 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2024 const char *protocol)
2025 {
2026 struct servent *se;
2027 struct sockaddr_in *addr;
2028
2029 assert(address != NULL);
2030 CHECK_ADDRESS(address, INET);
2031
2032 if (!port)
2033 {
2034 address->m_error = GSOCK_INVPORT;
2035 return GSOCK_INVPORT;
2036 }
2037
2038 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2039 struct servent_data buffer;
2040 #else
2041 char buffer[1024];
2042 #endif
2043 struct servent serv;
2044 se = wxGetservbyname_r(port, protocol, &serv,
2045 (void*)&buffer, sizeof(buffer));
2046 if (!se)
2047 {
2048 /* the cast to int suppresses compiler warnings about subscript having the
2049 type char */
2050 if (isdigit((int)port[0]))
2051 {
2052 int port_int;
2053
2054 port_int = atoi(port);
2055 addr = (struct sockaddr_in *)address->m_addr;
2056 addr->sin_port = htons(port_int);
2057 return GSOCK_NOERROR;
2058 }
2059
2060 address->m_error = GSOCK_INVPORT;
2061 return GSOCK_INVPORT;
2062 }
2063
2064 addr = (struct sockaddr_in *)address->m_addr;
2065 addr->sin_port = se->s_port;
2066
2067 return GSOCK_NOERROR;
2068 }
2069
2070 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2071 {
2072 struct sockaddr_in *addr;
2073
2074 assert(address != NULL);
2075 CHECK_ADDRESS(address, INET);
2076
2077 addr = (struct sockaddr_in *)address->m_addr;
2078 addr->sin_port = htons(port);
2079
2080 return GSOCK_NOERROR;
2081 }
2082
2083 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2084 {
2085 struct hostent *he;
2086 char *addr_buf;
2087 struct sockaddr_in *addr;
2088
2089 assert(address != NULL);
2090 CHECK_ADDRESS(address, INET);
2091
2092 addr = (struct sockaddr_in *)address->m_addr;
2093 addr_buf = (char *)&(addr->sin_addr);
2094
2095 struct hostent temphost;
2096 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2097 struct hostent_data buffer;
2098 #else
2099 char buffer[1024];
2100 #endif
2101 int err;
2102 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2103 (void*)&buffer, sizeof(buffer), &err);
2104 if (he == NULL)
2105 {
2106 address->m_error = GSOCK_NOHOST;
2107 return GSOCK_NOHOST;
2108 }
2109
2110 strncpy(hostname, he->h_name, sbuf);
2111
2112 return GSOCK_NOERROR;
2113 }
2114
2115 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2116 {
2117 struct sockaddr_in *addr;
2118
2119 assert(address != NULL);
2120 CHECK_ADDRESS_RETVAL(address, INET, 0);
2121
2122 addr = (struct sockaddr_in *)address->m_addr;
2123
2124 return ntohl(addr->sin_addr.s_addr);
2125 }
2126
2127 unsigned short GAddress_INET_GetPort(GAddress *address)
2128 {
2129 struct sockaddr_in *addr;
2130
2131 assert(address != NULL);
2132 CHECK_ADDRESS_RETVAL(address, INET, 0);
2133
2134 addr = (struct sockaddr_in *)address->m_addr;
2135 return ntohs(addr->sin_port);
2136 }
2137
2138 #if wxUSE_IPV6
2139 /*
2140 * -------------------------------------------------------------------------
2141 * Internet IPv6 address family
2142 * -------------------------------------------------------------------------
2143 */
2144
2145 GSocketError _GAddress_Init_INET6(GAddress *address)
2146 {
2147 struct in6_addr any_address = IN6ADDR_ANY_INIT;
2148 address->m_len = sizeof(struct sockaddr_in6);
2149 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2150 if (address->m_addr == NULL)
2151 {
2152 address->m_error = GSOCK_MEMERR;
2153 return GSOCK_MEMERR;
2154 }
2155 memset(address->m_addr,0,address->m_len);
2156
2157 address->m_family = GSOCK_INET6;
2158 address->m_realfamily = AF_INET6;
2159 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
2160 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
2161
2162 return GSOCK_NOERROR;
2163 }
2164
2165 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
2166 {
2167 assert(address != NULL);
2168 CHECK_ADDRESS(address, INET6);
2169
2170 addrinfo hints;
2171 memset( & hints, 0, sizeof( hints ) );
2172 hints.ai_family = AF_INET6;
2173 addrinfo * info = 0;
2174 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
2175 {
2176 address->m_error = GSOCK_NOHOST;
2177 return GSOCK_NOHOST;
2178 }
2179
2180 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
2181 freeaddrinfo( info );
2182 return GSOCK_NOERROR;
2183 }
2184
2185 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
2186 {
2187 assert(address != NULL);
2188
2189 CHECK_ADDRESS(address, INET6);
2190
2191 struct in6_addr addr;
2192 memset( & addr, 0, sizeof( addr ) );
2193 return GAddress_INET6_SetHostAddress(address, addr);
2194 }
2195 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
2196 struct in6_addr hostaddr)
2197 {
2198 assert(address != NULL);
2199
2200 CHECK_ADDRESS(address, INET6);
2201
2202 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
2203
2204 return GSOCK_NOERROR;
2205 }
2206
2207 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
2208 const char *protocol)
2209 {
2210 struct servent *se;
2211 struct sockaddr_in6 *addr;
2212
2213 assert(address != NULL);
2214 CHECK_ADDRESS(address, INET6);
2215
2216 if (!port)
2217 {
2218 address->m_error = GSOCK_INVPORT;
2219 return GSOCK_INVPORT;
2220 }
2221
2222 se = getservbyname(port, protocol);
2223 if (!se)
2224 {
2225 if (isdigit(port[0]))
2226 {
2227 int port_int;
2228
2229 port_int = atoi(port);
2230 addr = (struct sockaddr_in6 *)address->m_addr;
2231 addr->sin6_port = htons((u_short) port_int);
2232 return GSOCK_NOERROR;
2233 }
2234
2235 address->m_error = GSOCK_INVPORT;
2236 return GSOCK_INVPORT;
2237 }
2238
2239 addr = (struct sockaddr_in6 *)address->m_addr;
2240 addr->sin6_port = se->s_port;
2241
2242 return GSOCK_NOERROR;
2243 }
2244
2245 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
2246 {
2247 struct sockaddr_in6 *addr;
2248
2249 assert(address != NULL);
2250 CHECK_ADDRESS(address, INET6);
2251
2252 addr = (struct sockaddr_in6 *)address->m_addr;
2253 addr->sin6_port = htons(port);
2254
2255 return GSOCK_NOERROR;
2256 }
2257
2258 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2259 {
2260 struct hostent *he;
2261 char *addr_buf;
2262 struct sockaddr_in6 *addr;
2263
2264 assert(address != NULL);
2265 CHECK_ADDRESS(address, INET6);
2266
2267 addr = (struct sockaddr_in6 *)address->m_addr;
2268 addr_buf = (char *)&(addr->sin6_addr);
2269
2270 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
2271 if (he == NULL)
2272 {
2273 address->m_error = GSOCK_NOHOST;
2274 return GSOCK_NOHOST;
2275 }
2276
2277 strncpy(hostname, he->h_name, sbuf);
2278
2279 return GSOCK_NOERROR;
2280 }
2281
2282 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
2283 {
2284 assert(address != NULL);
2285 assert(hostaddr != NULL);
2286 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2287 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2288 return GSOCK_NOERROR;
2289 }
2290
2291 unsigned short GAddress_INET6_GetPort(GAddress *address)
2292 {
2293 assert(address != NULL);
2294 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2295
2296 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2297 }
2298
2299 #endif // wxUSE_IPV6
2300
2301 /*
2302 * -------------------------------------------------------------------------
2303 * Unix address family
2304 * -------------------------------------------------------------------------
2305 */
2306
2307 #ifndef __VISAGECPP__
2308 GSocketError _GAddress_Init_UNIX(GAddress *address)
2309 {
2310 address->m_len = sizeof(struct sockaddr_un);
2311 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2312 if (address->m_addr == NULL)
2313 {
2314 address->m_error = GSOCK_MEMERR;
2315 return GSOCK_MEMERR;
2316 }
2317
2318 address->m_family = GSOCK_UNIX;
2319 address->m_realfamily = PF_UNIX;
2320 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2321 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2322
2323 return GSOCK_NOERROR;
2324 }
2325
2326 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2327
2328 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2329 {
2330 struct sockaddr_un *addr;
2331
2332 assert(address != NULL);
2333
2334 CHECK_ADDRESS(address, UNIX);
2335
2336 addr = ((struct sockaddr_un *)address->m_addr);
2337 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2338 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2339
2340 return GSOCK_NOERROR;
2341 }
2342
2343 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2344 {
2345 struct sockaddr_un *addr;
2346
2347 assert(address != NULL);
2348 CHECK_ADDRESS(address, UNIX);
2349
2350 addr = (struct sockaddr_un *)address->m_addr;
2351
2352 strncpy(path, addr->sun_path, sbuf);
2353
2354 return GSOCK_NOERROR;
2355 }
2356 #endif /* !defined(__VISAGECPP__) */
2357 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */