]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.cpp
fix (harmless) VC7 warnings about auto_ptr assignment
[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 /* GSocket_Select:
1289 * Polls the socket to determine its status. This function will
1290 * check for the events specified in the 'flags' parameter, and
1291 * it will return a mask indicating which operations can be
1292 * performed. This function won't block, regardless of the
1293 * mode (blocking | nonblocking) of the socket.
1294 */
1295 GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
1296 {
1297 assert(this);
1298
1299 GSocketEventFlags result = 0;
1300 fd_set readfds;
1301 fd_set writefds;
1302 fd_set exceptfds;
1303 struct timeval tv;
1304
1305 if (m_fd == -1)
1306 return (GSOCK_LOST_FLAG & flags);
1307
1308 /* Do not use a static struct, Linux can garble it */
1309 tv.tv_sec = 0;
1310 tv.tv_usec = 0;
1311
1312 wxFD_ZERO(&readfds);
1313 wxFD_ZERO(&writefds);
1314 wxFD_ZERO(&exceptfds);
1315 wxFD_SET(m_fd, &readfds);
1316 if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
1317 wxFD_SET(m_fd, &writefds);
1318 wxFD_SET(m_fd, &exceptfds);
1319
1320 /* Check 'sticky' CONNECTION flag first */
1321 result |= GSOCK_CONNECTION_FLAG & m_detected;
1322
1323 /* If we have already detected a LOST event, then don't try
1324 * to do any further processing.
1325 */
1326 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1327 {
1328 m_establishing = false;
1329 return (GSOCK_LOST_FLAG & flags);
1330 }
1331
1332 /* Try select now */
1333 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
1334 {
1335 /* What to do here? */
1336 return (result & flags);
1337 }
1338
1339 /* Check for exceptions and errors */
1340 if (wxFD_ISSET(m_fd, &exceptfds))
1341 {
1342 m_establishing = false;
1343 m_detected = GSOCK_LOST_FLAG;
1344
1345 /* LOST event: Abort any further processing */
1346 return (GSOCK_LOST_FLAG & flags);
1347 }
1348
1349 /* Check for readability */
1350 if (wxFD_ISSET(m_fd, &readfds))
1351 {
1352 result |= GSOCK_INPUT_FLAG;
1353
1354 if (m_server && m_stream)
1355 {
1356 /* This is a TCP server socket that detected a connection.
1357 While the INPUT_FLAG is also set, it doesn't matter on
1358 this kind of sockets, as we can only Accept() from them. */
1359 m_detected |= GSOCK_CONNECTION_FLAG;
1360 }
1361 }
1362
1363 /* Check for writability */
1364 if (wxFD_ISSET(m_fd, &writefds))
1365 {
1366 if (m_establishing && !m_server)
1367 {
1368 int error;
1369 SOCKOPTLEN_T len = sizeof(error);
1370 m_establishing = false;
1371 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1372
1373 if (error)
1374 {
1375 m_detected = GSOCK_LOST_FLAG;
1376
1377 /* LOST event: Abort any further processing */
1378 return (GSOCK_LOST_FLAG & flags);
1379 }
1380 else
1381 {
1382 m_detected |= GSOCK_CONNECTION_FLAG;
1383 }
1384 }
1385 else
1386 {
1387 result |= GSOCK_OUTPUT_FLAG;
1388 }
1389 }
1390
1391 return (result | m_detected) & flags;
1392 }
1393
1394 /* Flags */
1395
1396 /* GSocket_SetNonBlocking:
1397 * Sets the socket to non-blocking mode. All IO calls will return
1398 * immediately.
1399 */
1400 void GSocket::SetNonBlocking(bool non_block)
1401 {
1402 assert(this);
1403
1404 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1405
1406 m_non_blocking = non_block;
1407 }
1408
1409 /* GSocket_SetTimeout:
1410 * Sets the timeout for blocking calls. Time is expressed in
1411 * milliseconds.
1412 */
1413 void GSocket::SetTimeout(unsigned long millisec)
1414 {
1415 assert(this);
1416
1417 m_timeout = millisec;
1418 }
1419
1420 /* GSocket_GetError:
1421 * Returns the last error occurred for this socket. Note that successful
1422 * operations do not clear this back to GSOCK_NOERROR, so use it only
1423 * after an error.
1424 */
1425 GSocketError WXDLLIMPEXP_NET GSocket::GetError()
1426 {
1427 assert(this);
1428
1429 return m_error;
1430 }
1431
1432 /* Callbacks */
1433
1434 /* GSOCK_INPUT:
1435 * There is data to be read in the input buffer. If, after a read
1436 * operation, there is still data available, the callback function will
1437 * be called again.
1438 * GSOCK_OUTPUT:
1439 * The socket is available for writing. That is, the next write call
1440 * won't block. This event is generated only once, when the connection is
1441 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1442 * when the output buffer empties again. This means that the app should
1443 * assume that it can write since the first OUTPUT event, and no more
1444 * OUTPUT events will be generated unless an error occurs.
1445 * GSOCK_CONNECTION:
1446 * Connection successfully established, for client sockets, or incoming
1447 * client connection, for server sockets. Wait for this event (also watch
1448 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1449 * GSOCK_LOST:
1450 * The connection is lost (or a connection request failed); this could
1451 * be due to a failure, or due to the peer closing it gracefully.
1452 */
1453
1454 /* GSocket_SetCallback:
1455 * Enables the callbacks specified by 'flags'. Note that 'flags'
1456 * may be a combination of flags OR'ed toghether, so the same
1457 * callback function can be made to accept different events.
1458 * The callback function must have the following prototype:
1459 *
1460 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1461 */
1462 void GSocket::SetCallback(GSocketEventFlags flags,
1463 GSocketCallback callback, char *cdata)
1464 {
1465 int count;
1466
1467 assert(this);
1468
1469 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1470 {
1471 if ((flags & (1 << count)) != 0)
1472 {
1473 m_cbacks[count] = callback;
1474 m_data[count] = cdata;
1475 }
1476 }
1477 }
1478
1479 /* GSocket_UnsetCallback:
1480 * Disables all callbacks specified by 'flags', which may be a
1481 * combination of flags OR'ed toghether.
1482 */
1483 void GSocket::UnsetCallback(GSocketEventFlags flags)
1484 {
1485 int count;
1486
1487 assert(this);
1488
1489 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1490 {
1491 if ((flags & (1 << count)) != 0)
1492 {
1493 m_cbacks[count] = NULL;
1494 m_data[count] = NULL;
1495 }
1496 }
1497 }
1498
1499 GSocketError GSocket::GetSockOpt(int level, int optname,
1500 void *optval, int *optlen)
1501 {
1502 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
1503 return GSOCK_NOERROR;
1504
1505 return GSOCK_OPTERR;
1506 }
1507
1508 GSocketError GSocket::SetSockOpt(int level, int optname,
1509 const void *optval, int optlen)
1510 {
1511 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
1512 return GSOCK_NOERROR;
1513
1514 return GSOCK_OPTERR;
1515 }
1516
1517 #define CALL_CALLBACK(socket, event) { \
1518 socket->Disable(event); \
1519 if (socket->m_cbacks[event]) \
1520 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1521 }
1522
1523
1524 void GSocket::Enable(GSocketEvent event)
1525 {
1526 if (m_use_events)
1527 {
1528 m_detected &= ~(1 << event);
1529 GSocketManager::Get()->Install_Callback(this, event);
1530 }
1531 }
1532
1533 void GSocket::Disable(GSocketEvent event)
1534 {
1535 if (m_use_events)
1536 {
1537 m_detected |= (1 << event);
1538 GSocketManager::Get()->Uninstall_Callback(this, event);
1539 }
1540 }
1541
1542 /* _GSocket_Input_Timeout:
1543 * For blocking sockets, wait until data is available or
1544 * until timeout ellapses.
1545 */
1546 GSocketError GSocket::Input_Timeout()
1547 {
1548 struct timeval tv;
1549 fd_set readfds;
1550 int ret;
1551
1552 /* Linux select() will overwrite the struct on return */
1553 tv.tv_sec = (m_timeout / 1000);
1554 tv.tv_usec = (m_timeout % 1000) * 1000;
1555
1556 if (!m_non_blocking)
1557 {
1558 wxFD_ZERO(&readfds);
1559 wxFD_SET(m_fd, &readfds);
1560 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
1561 if (ret == 0)
1562 {
1563 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1564 m_error = GSOCK_TIMEDOUT;
1565 return GSOCK_TIMEDOUT;
1566 }
1567
1568 if (ret == -1)
1569 {
1570 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1571 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1572 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1573 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1574 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1575 m_error = GSOCK_TIMEDOUT;
1576 return GSOCK_TIMEDOUT;
1577 }
1578 }
1579
1580 return GSOCK_NOERROR;
1581 }
1582
1583 /* _GSocket_Output_Timeout:
1584 * For blocking sockets, wait until data can be sent without
1585 * blocking or until timeout ellapses.
1586 */
1587 GSocketError GSocket::Output_Timeout()
1588 {
1589 struct timeval tv;
1590 fd_set writefds;
1591 int ret;
1592
1593 /* Linux select() will overwrite the struct on return */
1594 tv.tv_sec = (m_timeout / 1000);
1595 tv.tv_usec = (m_timeout % 1000) * 1000;
1596
1597 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
1598
1599 if (!m_non_blocking)
1600 {
1601 wxFD_ZERO(&writefds);
1602 wxFD_SET(m_fd, &writefds);
1603 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
1604 if (ret == 0)
1605 {
1606 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1607 m_error = GSOCK_TIMEDOUT;
1608 return GSOCK_TIMEDOUT;
1609 }
1610
1611 if (ret == -1)
1612 {
1613 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1614 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1615 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1616 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1617 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1618 m_error = GSOCK_TIMEDOUT;
1619 return GSOCK_TIMEDOUT;
1620 }
1621
1622 if ( ! wxFD_ISSET(m_fd, &writefds) )
1623 {
1624 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1625 }
1626 else
1627 {
1628 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1629 }
1630 }
1631 else
1632 {
1633 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1634 }
1635
1636 return GSOCK_NOERROR;
1637 }
1638
1639 int GSocket::Recv_Stream(char *buffer, int size)
1640 {
1641 int ret;
1642 do
1643 {
1644 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1645 }
1646 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1647
1648 return ret;
1649 }
1650
1651 int GSocket::Recv_Dgram(char *buffer, int size)
1652 {
1653 wxSockAddr from;
1654 WX_SOCKLEN_T fromlen = sizeof(from);
1655 int ret;
1656 GSocketError err;
1657
1658 fromlen = sizeof(from);
1659
1660 do
1661 {
1662 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
1663 }
1664 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1665
1666 if (ret == -1)
1667 return -1;
1668
1669 /* Translate a system address into a GSocket address */
1670 if (!m_peer)
1671 {
1672 m_peer = GAddress_new();
1673 if (!m_peer)
1674 {
1675 m_error = GSOCK_MEMERR;
1676 return -1;
1677 }
1678 }
1679
1680 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
1681 if (err != GSOCK_NOERROR)
1682 {
1683 GAddress_destroy(m_peer);
1684 m_peer = NULL;
1685 m_error = err;
1686 return -1;
1687 }
1688
1689 return ret;
1690 }
1691
1692 int GSocket::Send_Stream(const char *buffer, int size)
1693 {
1694 int ret;
1695
1696 MASK_SIGNAL();
1697
1698 do
1699 {
1700 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1701 }
1702 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1703
1704 UNMASK_SIGNAL();
1705
1706 return ret;
1707 }
1708
1709 int GSocket::Send_Dgram(const char *buffer, int size)
1710 {
1711 struct sockaddr *addr;
1712 int len, ret;
1713 GSocketError err;
1714
1715 if (!m_peer)
1716 {
1717 m_error = GSOCK_INVADDR;
1718 return -1;
1719 }
1720
1721 err = _GAddress_translate_to(m_peer, &addr, &len);
1722 if (err != GSOCK_NOERROR)
1723 {
1724 m_error = err;
1725 return -1;
1726 }
1727
1728 MASK_SIGNAL();
1729
1730 do
1731 {
1732 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1733 }
1734 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1735
1736 UNMASK_SIGNAL();
1737
1738 /* Frees memory allocated from _GAddress_translate_to */
1739 free(addr);
1740
1741 return ret;
1742 }
1743
1744 void GSocket::Detected_Read()
1745 {
1746 char c;
1747
1748 /* Safeguard against straggling call to Detected_Read */
1749 if (m_fd == INVALID_SOCKET)
1750 {
1751 return;
1752 }
1753
1754 /* If we have already detected a LOST event, then don't try
1755 * to do any further processing.
1756 */
1757 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1758 {
1759 m_establishing = false;
1760
1761 CALL_CALLBACK(this, GSOCK_LOST);
1762 Shutdown();
1763 return;
1764 }
1765
1766 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1767
1768 if (num > 0)
1769 {
1770 CALL_CALLBACK(this, GSOCK_INPUT);
1771 }
1772 else
1773 {
1774 if (m_server && m_stream)
1775 {
1776 CALL_CALLBACK(this, GSOCK_CONNECTION);
1777 }
1778 else if (num == 0)
1779 {
1780 if (m_stream)
1781 {
1782 /* graceful shutdown */
1783 CALL_CALLBACK(this, GSOCK_LOST);
1784 Shutdown();
1785 }
1786 else
1787 {
1788 /* Empty datagram received */
1789 CALL_CALLBACK(this, GSOCK_INPUT);
1790 }
1791 }
1792 else
1793 {
1794 /* Do not throw a lost event in cases where the socket isn't really lost */
1795 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
1796 {
1797 CALL_CALLBACK(this, GSOCK_INPUT);
1798 }
1799 else
1800 {
1801 CALL_CALLBACK(this, GSOCK_LOST);
1802 Shutdown();
1803 }
1804 }
1805 }
1806 }
1807
1808 void GSocket::Detected_Write()
1809 {
1810 /* If we have already detected a LOST event, then don't try
1811 * to do any further processing.
1812 */
1813 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1814 {
1815 m_establishing = false;
1816
1817 CALL_CALLBACK(this, GSOCK_LOST);
1818 Shutdown();
1819 return;
1820 }
1821
1822 if (m_establishing && !m_server)
1823 {
1824 int error;
1825 SOCKOPTLEN_T len = sizeof(error);
1826
1827 m_establishing = false;
1828
1829 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1830
1831 if (error)
1832 {
1833 CALL_CALLBACK(this, GSOCK_LOST);
1834 Shutdown();
1835 }
1836 else
1837 {
1838 CALL_CALLBACK(this, GSOCK_CONNECTION);
1839 /* We have to fire this event by hand because CONNECTION (for clients)
1840 * and OUTPUT are internally the same and we just disabled CONNECTION
1841 * events with the above macro.
1842 */
1843 CALL_CALLBACK(this, GSOCK_OUTPUT);
1844 }
1845 }
1846 else
1847 {
1848 CALL_CALLBACK(this, GSOCK_OUTPUT);
1849 }
1850 }
1851
1852 /* Compatibility functions for GSocket */
1853 GSocket *GSocket_new(void)
1854 {
1855 GSocket *newsocket = new GSocket();
1856 if (newsocket->IsOk())
1857 return newsocket;
1858
1859 delete newsocket;
1860
1861 return NULL;
1862 }
1863
1864 /*
1865 * -------------------------------------------------------------------------
1866 * GAddress
1867 * -------------------------------------------------------------------------
1868 */
1869
1870 /* CHECK_ADDRESS verifies that the current address family is either
1871 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1872 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1873 * an appropiate error code.
1874 *
1875 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1876 */
1877 #define CHECK_ADDRESS(address, family) \
1878 { \
1879 if (address->m_family == GSOCK_NOFAMILY) \
1880 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1881 return address->m_error; \
1882 if (address->m_family != GSOCK_##family) \
1883 { \
1884 address->m_error = GSOCK_INVADDR; \
1885 return GSOCK_INVADDR; \
1886 } \
1887 }
1888
1889 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1890 { \
1891 if (address->m_family == GSOCK_NOFAMILY) \
1892 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1893 return retval; \
1894 if (address->m_family != GSOCK_##family) \
1895 { \
1896 address->m_error = GSOCK_INVADDR; \
1897 return retval; \
1898 } \
1899 }
1900
1901
1902 GAddress *GAddress_new(void)
1903 {
1904 GAddress *address;
1905
1906 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1907 return NULL;
1908
1909 address->m_family = GSOCK_NOFAMILY;
1910 address->m_addr = NULL;
1911 address->m_len = 0;
1912
1913 return address;
1914 }
1915
1916 GAddress *GAddress_copy(GAddress *address)
1917 {
1918 GAddress *addr2;
1919
1920 assert(address != NULL);
1921
1922 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1923 return NULL;
1924
1925 memcpy(addr2, address, sizeof(GAddress));
1926
1927 if (address->m_addr && address->m_len > 0)
1928 {
1929 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1930 if (addr2->m_addr == NULL)
1931 {
1932 free(addr2);
1933 return NULL;
1934 }
1935 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1936 }
1937
1938 return addr2;
1939 }
1940
1941 void GAddress_destroy(GAddress *address)
1942 {
1943 assert(address != NULL);
1944
1945 if (address->m_addr)
1946 free(address->m_addr);
1947
1948 free(address);
1949 }
1950
1951 void GAddress_SetFamily(GAddress *address, GAddressType type)
1952 {
1953 assert(address != NULL);
1954
1955 address->m_family = type;
1956 }
1957
1958 GAddressType GAddress_GetFamily(GAddress *address)
1959 {
1960 assert(address != NULL);
1961
1962 return address->m_family;
1963 }
1964
1965 GSocketError _GAddress_translate_from(GAddress *address,
1966 struct sockaddr *addr, int len)
1967 {
1968 address->m_realfamily = addr->sa_family;
1969 switch (addr->sa_family)
1970 {
1971 case AF_INET:
1972 address->m_family = GSOCK_INET;
1973 break;
1974 case AF_UNIX:
1975 address->m_family = GSOCK_UNIX;
1976 break;
1977 #if wxUSE_IPV6
1978 case AF_INET6:
1979 address->m_family = GSOCK_INET6;
1980 break;
1981 #endif // wxUSE_IPV6
1982 default:
1983 {
1984 address->m_error = GSOCK_INVOP;
1985 return GSOCK_INVOP;
1986 }
1987 }
1988
1989 if (address->m_addr)
1990 free(address->m_addr);
1991
1992 address->m_len = len;
1993 address->m_addr = (struct sockaddr *)malloc(len);
1994
1995 if (address->m_addr == NULL)
1996 {
1997 address->m_error = GSOCK_MEMERR;
1998 return GSOCK_MEMERR;
1999 }
2000
2001 memcpy(address->m_addr, addr, len);
2002
2003 return GSOCK_NOERROR;
2004 }
2005
2006 GSocketError _GAddress_translate_to(GAddress *address,
2007 struct sockaddr **addr, int *len)
2008 {
2009 if (!address->m_addr)
2010 {
2011 address->m_error = GSOCK_INVADDR;
2012 return GSOCK_INVADDR;
2013 }
2014
2015 *len = address->m_len;
2016 *addr = (struct sockaddr *)malloc(address->m_len);
2017 if (*addr == NULL)
2018 {
2019 address->m_error = GSOCK_MEMERR;
2020 return GSOCK_MEMERR;
2021 }
2022
2023 memcpy(*addr, address->m_addr, address->m_len);
2024 return GSOCK_NOERROR;
2025 }
2026
2027 /*
2028 * -------------------------------------------------------------------------
2029 * Internet address family
2030 * -------------------------------------------------------------------------
2031 */
2032
2033 GSocketError _GAddress_Init_INET(GAddress *address)
2034 {
2035 address->m_len = sizeof(struct sockaddr_in);
2036 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2037 if (address->m_addr == NULL)
2038 {
2039 address->m_error = GSOCK_MEMERR;
2040 return GSOCK_MEMERR;
2041 }
2042
2043 address->m_family = GSOCK_INET;
2044 address->m_realfamily = PF_INET;
2045 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
2046 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
2047
2048 return GSOCK_NOERROR;
2049 }
2050
2051 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
2052 {
2053 struct hostent *he;
2054 struct in_addr *addr;
2055
2056 assert(address != NULL);
2057
2058 CHECK_ADDRESS(address, INET);
2059
2060 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2061
2062 /* If it is a numeric host name, convert it now */
2063 #if defined(HAVE_INET_ATON)
2064 if (inet_aton(hostname, addr) == 0)
2065 {
2066 #elif defined(HAVE_INET_ADDR)
2067 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
2068 {
2069 #else
2070 /* Use gethostbyname by default */
2071 #ifndef __WXMAC__
2072 int val = 1; /* VA doesn't like constants in conditional expressions */
2073 if (val)
2074 #endif
2075 {
2076 #endif
2077 struct in_addr *array_addr;
2078
2079 /* It is a real name, we solve it */
2080 struct hostent h;
2081 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2082 struct hostent_data buffer;
2083 #else
2084 char buffer[1024];
2085 #endif
2086 int err;
2087 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
2088 if (he == NULL)
2089 {
2090 /* Reset to invalid address */
2091 addr->s_addr = INADDR_NONE;
2092 address->m_error = GSOCK_NOHOST;
2093 return GSOCK_NOHOST;
2094 }
2095
2096 array_addr = (struct in_addr *) *(he->h_addr_list);
2097 addr->s_addr = array_addr[0].s_addr;
2098 }
2099
2100 return GSOCK_NOERROR;
2101 }
2102
2103
2104 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
2105 {
2106 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2107 }
2108
2109 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2110 {
2111 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2112 }
2113
2114 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2115 unsigned long hostaddr)
2116 {
2117 struct in_addr *addr;
2118
2119 assert(address != NULL);
2120
2121 CHECK_ADDRESS(address, INET);
2122
2123 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2124 addr->s_addr = htonl(hostaddr);
2125
2126 return GSOCK_NOERROR;
2127 }
2128
2129 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2130 const char *protocol)
2131 {
2132 struct servent *se;
2133 struct sockaddr_in *addr;
2134
2135 assert(address != NULL);
2136 CHECK_ADDRESS(address, INET);
2137
2138 if (!port)
2139 {
2140 address->m_error = GSOCK_INVPORT;
2141 return GSOCK_INVPORT;
2142 }
2143
2144 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2145 struct servent_data buffer;
2146 #else
2147 char buffer[1024];
2148 #endif
2149 struct servent serv;
2150 se = wxGetservbyname_r(port, protocol, &serv,
2151 (void*)&buffer, sizeof(buffer));
2152 if (!se)
2153 {
2154 /* the cast to int suppresses compiler warnings about subscript having the
2155 type char */
2156 if (isdigit((int)port[0]))
2157 {
2158 int port_int;
2159
2160 port_int = atoi(port);
2161 addr = (struct sockaddr_in *)address->m_addr;
2162 addr->sin_port = htons(port_int);
2163 return GSOCK_NOERROR;
2164 }
2165
2166 address->m_error = GSOCK_INVPORT;
2167 return GSOCK_INVPORT;
2168 }
2169
2170 addr = (struct sockaddr_in *)address->m_addr;
2171 addr->sin_port = se->s_port;
2172
2173 return GSOCK_NOERROR;
2174 }
2175
2176 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2177 {
2178 struct sockaddr_in *addr;
2179
2180 assert(address != NULL);
2181 CHECK_ADDRESS(address, INET);
2182
2183 addr = (struct sockaddr_in *)address->m_addr;
2184 addr->sin_port = htons(port);
2185
2186 return GSOCK_NOERROR;
2187 }
2188
2189 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2190 {
2191 struct hostent *he;
2192 char *addr_buf;
2193 struct sockaddr_in *addr;
2194
2195 assert(address != NULL);
2196 CHECK_ADDRESS(address, INET);
2197
2198 addr = (struct sockaddr_in *)address->m_addr;
2199 addr_buf = (char *)&(addr->sin_addr);
2200
2201 struct hostent temphost;
2202 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2203 struct hostent_data buffer;
2204 #else
2205 char buffer[1024];
2206 #endif
2207 int err;
2208 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2209 (void*)&buffer, sizeof(buffer), &err);
2210 if (he == NULL)
2211 {
2212 address->m_error = GSOCK_NOHOST;
2213 return GSOCK_NOHOST;
2214 }
2215
2216 strncpy(hostname, he->h_name, sbuf);
2217
2218 return GSOCK_NOERROR;
2219 }
2220
2221 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2222 {
2223 struct sockaddr_in *addr;
2224
2225 assert(address != NULL);
2226 CHECK_ADDRESS_RETVAL(address, INET, 0);
2227
2228 addr = (struct sockaddr_in *)address->m_addr;
2229
2230 return ntohl(addr->sin_addr.s_addr);
2231 }
2232
2233 unsigned short GAddress_INET_GetPort(GAddress *address)
2234 {
2235 struct sockaddr_in *addr;
2236
2237 assert(address != NULL);
2238 CHECK_ADDRESS_RETVAL(address, INET, 0);
2239
2240 addr = (struct sockaddr_in *)address->m_addr;
2241 return ntohs(addr->sin_port);
2242 }
2243
2244 #if wxUSE_IPV6
2245 /*
2246 * -------------------------------------------------------------------------
2247 * Internet IPv6 address family
2248 * -------------------------------------------------------------------------
2249 */
2250
2251 GSocketError _GAddress_Init_INET6(GAddress *address)
2252 {
2253 struct in6_addr any_address = IN6ADDR_ANY_INIT;
2254 address->m_len = sizeof(struct sockaddr_in6);
2255 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2256 if (address->m_addr == NULL)
2257 {
2258 address->m_error = GSOCK_MEMERR;
2259 return GSOCK_MEMERR;
2260 }
2261 memset(address->m_addr,0,address->m_len);
2262
2263 address->m_family = GSOCK_INET6;
2264 address->m_realfamily = AF_INET6;
2265 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
2266 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
2267
2268 return GSOCK_NOERROR;
2269 }
2270
2271 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
2272 {
2273 assert(address != NULL);
2274 CHECK_ADDRESS(address, INET6);
2275
2276 addrinfo hints;
2277 memset( & hints, 0, sizeof( hints ) );
2278 hints.ai_family = AF_INET6;
2279 addrinfo * info = 0;
2280 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
2281 {
2282 address->m_error = GSOCK_NOHOST;
2283 return GSOCK_NOHOST;
2284 }
2285
2286 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
2287 freeaddrinfo( info );
2288 return GSOCK_NOERROR;
2289 }
2290
2291 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
2292 {
2293 assert(address != NULL);
2294
2295 CHECK_ADDRESS(address, INET6);
2296
2297 struct in6_addr addr;
2298 memset( & addr, 0, sizeof( addr ) );
2299 return GAddress_INET6_SetHostAddress(address, addr);
2300 }
2301 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
2302 struct in6_addr hostaddr)
2303 {
2304 assert(address != NULL);
2305
2306 CHECK_ADDRESS(address, INET6);
2307
2308 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
2309
2310 return GSOCK_NOERROR;
2311 }
2312
2313 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
2314 const char *protocol)
2315 {
2316 struct servent *se;
2317 struct sockaddr_in6 *addr;
2318
2319 assert(address != NULL);
2320 CHECK_ADDRESS(address, INET6);
2321
2322 if (!port)
2323 {
2324 address->m_error = GSOCK_INVPORT;
2325 return GSOCK_INVPORT;
2326 }
2327
2328 se = getservbyname(port, protocol);
2329 if (!se)
2330 {
2331 if (isdigit(port[0]))
2332 {
2333 int port_int;
2334
2335 port_int = atoi(port);
2336 addr = (struct sockaddr_in6 *)address->m_addr;
2337 addr->sin6_port = htons((u_short) port_int);
2338 return GSOCK_NOERROR;
2339 }
2340
2341 address->m_error = GSOCK_INVPORT;
2342 return GSOCK_INVPORT;
2343 }
2344
2345 addr = (struct sockaddr_in6 *)address->m_addr;
2346 addr->sin6_port = se->s_port;
2347
2348 return GSOCK_NOERROR;
2349 }
2350
2351 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
2352 {
2353 struct sockaddr_in6 *addr;
2354
2355 assert(address != NULL);
2356 CHECK_ADDRESS(address, INET6);
2357
2358 addr = (struct sockaddr_in6 *)address->m_addr;
2359 addr->sin6_port = htons(port);
2360
2361 return GSOCK_NOERROR;
2362 }
2363
2364 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2365 {
2366 struct hostent *he;
2367 char *addr_buf;
2368 struct sockaddr_in6 *addr;
2369
2370 assert(address != NULL);
2371 CHECK_ADDRESS(address, INET6);
2372
2373 addr = (struct sockaddr_in6 *)address->m_addr;
2374 addr_buf = (char *)&(addr->sin6_addr);
2375
2376 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
2377 if (he == NULL)
2378 {
2379 address->m_error = GSOCK_NOHOST;
2380 return GSOCK_NOHOST;
2381 }
2382
2383 strncpy(hostname, he->h_name, sbuf);
2384
2385 return GSOCK_NOERROR;
2386 }
2387
2388 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
2389 {
2390 assert(address != NULL);
2391 assert(hostaddr != NULL);
2392 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2393 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2394 return GSOCK_NOERROR;
2395 }
2396
2397 unsigned short GAddress_INET6_GetPort(GAddress *address)
2398 {
2399 assert(address != NULL);
2400 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2401
2402 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2403 }
2404
2405 #endif // wxUSE_IPV6
2406
2407 /*
2408 * -------------------------------------------------------------------------
2409 * Unix address family
2410 * -------------------------------------------------------------------------
2411 */
2412
2413 #ifndef __VISAGECPP__
2414 GSocketError _GAddress_Init_UNIX(GAddress *address)
2415 {
2416 address->m_len = sizeof(struct sockaddr_un);
2417 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2418 if (address->m_addr == NULL)
2419 {
2420 address->m_error = GSOCK_MEMERR;
2421 return GSOCK_MEMERR;
2422 }
2423
2424 address->m_family = GSOCK_UNIX;
2425 address->m_realfamily = PF_UNIX;
2426 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2427 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2428
2429 return GSOCK_NOERROR;
2430 }
2431
2432 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2433
2434 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2435 {
2436 struct sockaddr_un *addr;
2437
2438 assert(address != NULL);
2439
2440 CHECK_ADDRESS(address, UNIX);
2441
2442 addr = ((struct sockaddr_un *)address->m_addr);
2443 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2444 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2445
2446 return GSOCK_NOERROR;
2447 }
2448
2449 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2450 {
2451 struct sockaddr_un *addr;
2452
2453 assert(address != NULL);
2454 CHECK_ADDRESS(address, UNIX);
2455
2456 addr = (struct sockaddr_un *)address->m_addr;
2457
2458 strncpy(path, addr->sun_path, sbuf);
2459
2460 return GSOCK_NOERROR;
2461 }
2462 #endif /* !defined(__VISAGECPP__) */
2463 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */