]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.cpp
disable console targets for WinCE
[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 #include "wx/thread.h" // for wxThread::IsMain() used in assert
25 #endif
26
27 #if defined(__VISAGECPP__)
28 #define BSD_SELECT /* use Berkeley Sockets select */
29 #endif
30
31 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
32
33 #include <assert.h>
34 #include <sys/types.h>
35 #ifdef __VISAGECPP__
36 #include <string.h>
37 #include <sys/time.h>
38 #include <types.h>
39 #include <netinet/in.h>
40 #endif
41 #include <netdb.h>
42 #include <sys/ioctl.h>
43
44 #ifdef HAVE_SYS_SELECT_H
45 # include <sys/select.h>
46 #endif
47
48 #ifdef __VMS__
49 #include <socket.h>
50 struct sockaddr_un
51 {
52 u_char sun_len; /* sockaddr len including null */
53 u_char sun_family; /* AF_UNIX */
54 char sun_path[108]; /* path name (gag) */
55 };
56 #else
57 #include <sys/socket.h>
58 #include <sys/un.h>
59 #endif
60
61 #ifndef __VISAGECPP__
62 #include <sys/time.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
65 #include <errno.h>
66 #include <string.h>
67 #include <unistd.h>
68 #else
69 #include <nerrno.h>
70 # if __IBMCPP__ < 400
71 #include <machine/endian.h>
72 #include <socket.h>
73 #include <ioctl.h>
74 #include <select.h>
75 #include <unistd.h>
76
77 #define EBADF SOCEBADF
78
79 # ifdef min
80 # undef min
81 # endif
82 # else
83 #include <sys/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/select.h>
86
87 #define close(a) soclose(a)
88 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
89 int _System bsdselect(int,
90 struct fd_set *,
91 struct fd_set *,
92 struct fd_set *,
93 struct timeval *);
94 int _System soclose(int);
95 # endif
96 #endif
97 #ifdef __EMX__
98 #include <sys/select.h>
99 #endif
100
101 #include <stdio.h>
102 #include <stdlib.h>
103 #include <stddef.h>
104 #include <ctype.h>
105 #ifdef sun
106 # include <sys/filio.h>
107 #endif
108 #ifdef sgi
109 # include <bstring.h>
110 #endif
111 #ifdef _AIX
112 # include <strings.h>
113 #endif
114 #include <signal.h>
115
116 #ifndef WX_SOCKLEN_T
117
118 #ifdef VMS
119 # define WX_SOCKLEN_T unsigned int
120 #else
121 # ifdef __GLIBC__
122 # if __GLIBC__ == 2
123 # define WX_SOCKLEN_T socklen_t
124 # endif
125 # elif defined(__WXMAC__)
126 # define WX_SOCKLEN_T socklen_t
127 # else
128 # define WX_SOCKLEN_T int
129 # endif
130 #endif
131
132 #endif /* SOCKLEN_T */
133
134 #ifndef SOCKOPTLEN_T
135 #define SOCKOPTLEN_T WX_SOCKLEN_T
136 #endif
137
138 /*
139 * MSW defines this, Unices don't.
140 */
141 #ifndef INVALID_SOCKET
142 #define INVALID_SOCKET -1
143 #endif
144
145 /* UnixWare reportedly needs this for FIONBIO definition */
146 #ifdef __UNIXWARE__
147 #include <sys/filio.h>
148 #endif
149
150 /*
151 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
152 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
153 */
154 #ifndef INADDR_NONE
155 #define INADDR_NONE INADDR_BROADCAST
156 #endif
157
158 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
159
160 #define MASK_SIGNAL() {
161 #define UNMASK_SIGNAL() }
162
163 #else
164 extern "C" { typedef void (*wxSigHandler)(int); }
165
166 #define MASK_SIGNAL() \
167 { \
168 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
169
170 #define UNMASK_SIGNAL() \
171 signal(SIGPIPE, old_handler); \
172 }
173
174 #endif
175
176 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
177 the program will "crash" unless it explicitly handles the SIGPIPE.
178 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
179 use SO_NOSIGPIPE (if available), the BSD equivalent. */
180 #ifdef MSG_NOSIGNAL
181 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
182 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
183 # define GSOCKET_MSG_NOSIGNAL 0
184 #endif /* MSG_NOSIGNAL */
185
186 #ifndef __GSOCKET_STANDALONE__
187 # include "wx/unix/gsockunx.h"
188 # include "wx/unix/private.h"
189 # include "wx/gsocket.h"
190 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
191 # include "wx/thread.h"
192 #endif
193 #else
194 # include "gsockunx.h"
195 # include "gsocket.h"
196 # ifndef WXUNUSED
197 # define WXUNUSED(x)
198 # endif
199 #endif /* __GSOCKET_STANDALONE__ */
200
201 #if defined(HAVE_GETHOSTBYNAME)
202 static struct hostent * deepCopyHostent(struct hostent *h,
203 const struct hostent *he,
204 char *buffer, int size, int *err)
205 {
206 /* copy old structure */
207 memcpy(h, he, sizeof(struct hostent));
208
209 /* copy name */
210 int len = strlen(h->h_name);
211 if (len > size)
212 {
213 *err = ENOMEM;
214 return NULL;
215 }
216 memcpy(buffer, h->h_name, len);
217 buffer[len] = '\0';
218 h->h_name = buffer;
219
220 /* track position in the buffer */
221 int pos = len + 1;
222
223 /* reuse len to store address length */
224 len = h->h_length;
225
226 /* ensure pointer alignment */
227 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
228 if(misalign < sizeof(char *))
229 pos += misalign;
230
231 /* leave space for pointer list */
232 char **p = h->h_addr_list, **q;
233 char **h_addr_list = (char **)(buffer + pos);
234 while(*(p++) != 0)
235 pos += sizeof(char *);
236
237 /* copy addresses and fill new pointer list */
238 for (p = h->h_addr_list, q = h_addr_list; *p != 0; p++, q++)
239 {
240 if (size < pos + len)
241 {
242 *err = ENOMEM;
243 return NULL;
244 }
245 memcpy(buffer + pos, *p, len); /* copy content */
246 *q = buffer + pos; /* set copied pointer to copied content */
247 pos += len;
248 }
249 *++q = 0; /* null terminate the pointer list */
250 h->h_addr_list = h_addr_list; /* copy pointer to pointers */
251
252 /* ensure word alignment of pointers */
253 misalign = sizeof(char *) - pos%sizeof(char *);
254 if(misalign < sizeof(char *))
255 pos += misalign;
256
257 /* leave space for pointer list */
258 p = h->h_aliases;
259 char **h_aliases = (char **)(buffer + pos);
260 while(*(p++) != 0)
261 pos += sizeof(char *);
262
263 /* copy aliases and fill new pointer list */
264 for (p = h->h_aliases, q = h_aliases; *p != 0; p++, q++)
265 {
266 len = strlen(*p);
267 if (size <= pos + len)
268 {
269 *err = ENOMEM;
270 return NULL;
271 }
272 memcpy(buffer + pos, *p, len); /* copy content */
273 buffer[pos + len] = '\0';
274 *q = buffer + pos; /* set copied pointer to copied content */
275 pos += len + 1;
276 }
277 *++q = 0; /* null terminate the pointer list */
278 h->h_aliases = h_aliases; /* copy pointer to pointers */
279
280 return h;
281 }
282 #endif
283
284 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
285 static wxMutex nameLock;
286 #endif
287 struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h,
288 void *buffer, int size, int *err)
289
290 {
291 struct hostent *he = NULL;
292 *err = 0;
293 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
294 if (gethostbyname_r(hostname, h, (char*)buffer, size, &he, err))
295 he = NULL;
296 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
297 he = gethostbyname_r(hostname, h, (char*)buffer, size, err);
298 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
299 if (gethostbyname_r(hostname, h, (struct hostent_data*) buffer))
300 {
301 he = NULL;
302 *err = h_errno;
303 }
304 else
305 he = h;
306 #elif defined(HAVE_GETHOSTBYNAME)
307 #if wxUSE_THREADS
308 wxMutexLocker locker(nameLock);
309 #endif
310 he = gethostbyname(hostname);
311 if (!he)
312 *err = h_errno;
313 else
314 he = deepCopyHostent(h, he, (char*)buffer, size, err);
315 #endif
316 return he;
317 }
318
319 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
320 static wxMutex addrLock;
321 #endif
322 struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size,
323 int proto, struct hostent *h,
324 void *buffer, int size, int *err)
325 {
326 struct hostent *he = NULL;
327 *err = 0;
328 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
329 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
330 (char*)buffer, size, &he, err))
331 he = NULL;
332 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
333 he = gethostbyaddr_r(addr_buf, buf_size, proto, h, (char*)buffer, size, err);
334 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
335 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
336 (struct hostent_data*) buffer))
337 {
338 he = NULL;
339 *err = h_errno;
340 }
341 else
342 he = h;
343 #elif defined(HAVE_GETHOSTBYNAME)
344 #if wxUSE_THREADS
345 wxMutexLocker locker(addrLock);
346 #endif
347 he = gethostbyaddr(addr_buf, buf_size, proto);
348 if (!he)
349 *err = h_errno;
350 else
351 he = deepCopyHostent(h, he, (char*)buffer, size, err);
352 #endif
353 return he;
354 }
355
356 #if defined(HAVE_GETSERVBYNAME)
357 static struct servent * deepCopyServent(struct servent *s,
358 const struct servent *se,
359 char *buffer, int size)
360 {
361 /* copy plain old structure */
362 memcpy(s, se, sizeof(struct servent));
363
364 /* copy name */
365 int len = strlen(s->s_name);
366 if (len >= size)
367 {
368 return NULL;
369 }
370 memcpy(buffer, s->s_name, len);
371 buffer[len] = '\0';
372 s->s_name = buffer;
373
374 /* track position in the buffer */
375 int pos = len + 1;
376
377 /* copy protocol */
378 len = strlen(s->s_proto);
379 if (pos + len >= size)
380 {
381 return NULL;
382 }
383 memcpy(buffer + pos, s->s_proto, len);
384 buffer[pos + len] = '\0';
385 s->s_proto = buffer + pos;
386
387 /* track position in the buffer */
388 pos += len + 1;
389
390 /* ensure pointer alignment */
391 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
392 if(misalign < sizeof(char *))
393 pos += misalign;
394
395 /* leave space for pointer list */
396 char **p = s->s_aliases, **q;
397 char **s_aliases = (char **)(buffer + pos);
398 while(*(p++) != 0)
399 pos += sizeof(char *);
400
401 /* copy addresses and fill new pointer list */
402 for (p = s->s_aliases, q = s_aliases; *p != 0; p++, q++){
403 len = strlen(*p);
404 if (size <= pos + len)
405 {
406 return NULL;
407 }
408 memcpy(buffer + pos, *p, len); /* copy content */
409 buffer[pos + len] = '\0';
410 *q = buffer + pos; /* set copied pointer to copied content */
411 pos += len + 1;
412 }
413 *++q = 0; /* null terminate the pointer list */
414 s->s_aliases = s_aliases; /* copy pointer to pointers */
415 return s;
416 }
417 #endif
418
419 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
420 static wxMutex servLock;
421 #endif
422 struct servent *wxGetservbyname_r(const char *port, const char *protocol,
423 struct servent *serv, void *buffer, int size)
424 {
425 struct servent *se = NULL;
426 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
427 if (getservbyname_r(port, protocol, serv, (char*)buffer, size, &se))
428 se = NULL;
429 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
430 se = getservbyname_r(port, protocol, serv, (char*)buffer, size);
431 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
432 if (getservbyname_r(port, protocol, serv, (struct servent_data*) buffer))
433 se = NULL;
434 else
435 se = serv;
436 #elif defined(HAVE_GETSERVBYNAME)
437 #if wxUSE_THREADS
438 wxMutexLocker locker(servLock);
439 #endif
440 se = getservbyname(port, protocol);
441 if (se)
442 se = deepCopyServent(serv, se, (char*)buffer, size);
443 #endif
444 return se;
445 }
446
447 /* debugging helpers */
448 #ifdef __GSOCKET_DEBUG__
449 # define GSocket_Debug(args) printf args
450 #else
451 # define GSocket_Debug(args)
452 #endif /* __GSOCKET_DEBUG__ */
453
454 #if wxUSE_IPV6
455 typedef struct sockaddr_storage wxSockAddr;
456 #else
457 typedef struct sockaddr wxSockAddr;
458 #endif
459
460 /* Table of GUI-related functions. We must call them indirectly because
461 * of wxBase and GUI separation: */
462
463 bool GSocket_Init()
464 {
465 GSocketManager * const manager = GSocketManager::Get();
466 return manager && manager->OnInit();
467 }
468
469 void GSocket_Cleanup()
470 {
471 GSocketManager * const manager = GSocketManager::Get();
472 if ( manager )
473 manager->OnExit();
474 }
475
476 /* Constructors / Destructors for GSocket */
477
478 GSocket::GSocket()
479 {
480 int i;
481
482 m_fd = INVALID_SOCKET;
483 m_handler = NULL;
484
485 for (i=0;i<GSOCK_MAX_EVENT;i++)
486 {
487 m_cbacks[i] = NULL;
488 }
489 m_detected = 0;
490 m_local = NULL;
491 m_peer = NULL;
492 m_error = GSOCK_NOERROR;
493 m_server = false;
494 m_stream = true;
495 m_gui_dependent = NULL;
496 m_non_blocking = false;
497 m_reusable = false;
498 m_broadcast = false;
499 m_dobind = true;
500 m_timeout = 10*60*1000;
501 /* 10 minutes * 60 sec * 1000 millisec */
502 m_establishing = false;
503 m_use_events = false;
504 m_initialRecvBufferSize = -1;
505 m_initialSendBufferSize = -1;
506
507 m_ok = GSocketManager::Get()->Init_Socket(this);
508 }
509
510 void GSocket::Close()
511 {
512 if (m_use_events)
513 DisableEvents();
514
515 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
516 will close the socket during Disable_Events. However, it will only do this
517 if it is being used. That is, it won't do it in a console program. To
518 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
519 if it has closed the socket which indicates to us (at runtime, instead of
520 at compile time as this had been before) that the socket has already
521 been closed.
522 */
523 if(m_fd != INVALID_SOCKET)
524 close(m_fd);
525 m_fd = INVALID_SOCKET;
526 }
527
528 GSocket::~GSocket()
529 {
530 assert(this);
531
532 /* Check that the socket is really shutdowned */
533 if (m_fd != INVALID_SOCKET)
534 Shutdown();
535
536 GSocketManager::Get()->Destroy_Socket(this);
537
538 delete m_handler;
539
540 /* Destroy private addresses */
541 if (m_local)
542 GAddress_destroy(m_local);
543
544 if (m_peer)
545 GAddress_destroy(m_peer);
546
547 }
548
549 /* GSocket_Shutdown:
550 * Disallow further read/write operations on this socket, close
551 * the fd and disable all callbacks.
552 */
553 void GSocket::Shutdown()
554 {
555 int evt;
556
557 assert(this);
558
559 /* Don't allow events to fire after socket has been closed */
560 if (m_use_events)
561 DisableEvents();
562
563 /* If socket has been created, shutdown it */
564 if (m_fd != INVALID_SOCKET)
565 {
566 shutdown(m_fd, 1);
567 Close();
568 }
569
570 /* Disable GUI callbacks */
571 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
572 m_cbacks[evt] = NULL;
573
574 m_detected = GSOCK_LOST_FLAG;
575 }
576
577 /* Address handling */
578
579 /* GSocket_SetLocal:
580 * GSocket_GetLocal:
581 * GSocket_SetPeer:
582 * GSocket_GetPeer:
583 * Set or get the local or peer address for this socket. The 'set'
584 * functions return GSOCK_NOERROR on success, an error code otherwise.
585 * The 'get' functions return a pointer to a GAddress object on success,
586 * or NULL otherwise, in which case they set the error code of the
587 * corresponding GSocket.
588 *
589 * Error codes:
590 * GSOCK_INVSOCK - the socket is not valid.
591 * GSOCK_INVADDR - the address is not valid.
592 */
593 GSocketError GSocket::SetLocal(GAddress *address)
594 {
595 assert(this);
596
597 /* the socket must be initialized, or it must be a server */
598 if ((m_fd != INVALID_SOCKET && !m_server))
599 {
600 m_error = GSOCK_INVSOCK;
601 return GSOCK_INVSOCK;
602 }
603
604 /* check address */
605 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
606 {
607 m_error = GSOCK_INVADDR;
608 return GSOCK_INVADDR;
609 }
610
611 if (m_local)
612 GAddress_destroy(m_local);
613
614 m_local = GAddress_copy(address);
615
616 return GSOCK_NOERROR;
617 }
618
619 GSocketError GSocket::SetPeer(GAddress *address)
620 {
621 assert(this);
622
623 /* check address */
624 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
625 {
626 m_error = GSOCK_INVADDR;
627 return GSOCK_INVADDR;
628 }
629
630 if (m_peer)
631 GAddress_destroy(m_peer);
632
633 m_peer = GAddress_copy(address);
634
635 return GSOCK_NOERROR;
636 }
637
638 GAddress *GSocket::GetLocal()
639 {
640 GAddress *address;
641 wxSockAddr addr;
642 WX_SOCKLEN_T size = sizeof(addr);
643 GSocketError err;
644
645 assert(this);
646
647 /* try to get it from the m_local var first */
648 if (m_local)
649 return GAddress_copy(m_local);
650
651 /* else, if the socket is initialized, try getsockname */
652 if (m_fd == INVALID_SOCKET)
653 {
654 m_error = GSOCK_INVSOCK;
655 return NULL;
656 }
657
658 if (getsockname(m_fd, (sockaddr*)&addr, (WX_SOCKLEN_T *) &size) < 0)
659 {
660 m_error = GSOCK_IOERR;
661 return NULL;
662 }
663
664 /* got a valid address from getsockname, create a GAddress object */
665 address = GAddress_new();
666 if (address == NULL)
667 {
668 m_error = GSOCK_MEMERR;
669 return NULL;
670 }
671
672 err = _GAddress_translate_from(address, (sockaddr*)&addr, size);
673 if (err != GSOCK_NOERROR)
674 {
675 GAddress_destroy(address);
676 m_error = err;
677 return NULL;
678 }
679
680 return address;
681 }
682
683 GAddress *GSocket::GetPeer()
684 {
685 assert(this);
686
687 /* try to get it from the m_peer var */
688 if (m_peer)
689 return GAddress_copy(m_peer);
690
691 return NULL;
692 }
693
694 /* Server specific parts */
695
696 /* GSocket_SetServer:
697 * Sets up this socket as a server. The local address must have been
698 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
699 * Returns GSOCK_NOERROR on success, one of the following otherwise:
700 *
701 * Error codes:
702 * GSOCK_INVSOCK - the socket is in use.
703 * GSOCK_INVADDR - the local address has not been set.
704 * GSOCK_IOERR - low-level error.
705 */
706 GSocketError GSocket::SetServer()
707 {
708 int arg = 1;
709
710 assert(this);
711
712 /* must not be in use */
713 if (m_fd != INVALID_SOCKET)
714 {
715 m_error = GSOCK_INVSOCK;
716 return GSOCK_INVSOCK;
717 }
718
719 /* the local addr must have been set */
720 if (!m_local)
721 {
722 m_error = GSOCK_INVADDR;
723 return GSOCK_INVADDR;
724 }
725
726 /* Initialize all fields */
727 m_stream = true;
728 m_server = true;
729
730 /* Create the socket */
731 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
732
733 if (m_fd == INVALID_SOCKET)
734 {
735 m_error = GSOCK_IOERR;
736 return GSOCK_IOERR;
737 }
738
739 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
740 #ifdef SO_NOSIGPIPE
741 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
742 #endif
743
744 ioctl(m_fd, FIONBIO, &arg);
745 if (m_use_events)
746 EnableEvents();
747
748 /* allow a socket to re-bind if the socket is in the TIME_WAIT
749 state after being previously closed.
750 */
751 if (m_reusable)
752 {
753 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
754 #ifdef SO_REUSEPORT
755 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
756 #endif
757 }
758
759 /* Bind to the local address,
760 * retrieve the actual address bound,
761 * and listen up to 5 connections.
762 */
763 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
764 (getsockname(m_fd,
765 m_local->m_addr,
766 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
767 (listen(m_fd, 5) != 0))
768 {
769 Close();
770 m_error = GSOCK_IOERR;
771 return GSOCK_IOERR;
772 }
773
774 return GSOCK_NOERROR;
775 }
776
777 /* GSocket_WaitConnection:
778 * Waits for an incoming client connection. Returns a pointer to
779 * a GSocket object, or NULL if there was an error, in which case
780 * the last error field will be updated for the calling GSocket.
781 *
782 * Error codes (set in the calling GSocket)
783 * GSOCK_INVSOCK - the socket is not valid or not a server.
784 * GSOCK_TIMEDOUT - timeout, no incoming connections.
785 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
786 * GSOCK_MEMERR - couldn't allocate memory.
787 * GSOCK_IOERR - low-level error.
788 */
789 GSocket *GSocket::WaitConnection()
790 {
791 wxSockAddr from;
792 WX_SOCKLEN_T fromlen = sizeof(from);
793 GSocket *connection;
794 GSocketError err;
795 int arg = 1;
796
797 assert(this);
798
799 /* If the socket has already been created, we exit immediately */
800 if (m_fd == INVALID_SOCKET || !m_server)
801 {
802 m_error = GSOCK_INVSOCK;
803 return NULL;
804 }
805
806 /* Create a GSocket object for the new connection */
807 connection = GSocket_new();
808
809 if (!connection)
810 {
811 m_error = GSOCK_MEMERR;
812 return NULL;
813 }
814
815 /* Wait for a connection (with timeout) */
816 if (Input_Timeout() == GSOCK_TIMEDOUT)
817 {
818 delete connection;
819 /* m_error set by _GSocket_Input_Timeout */
820 return NULL;
821 }
822
823 connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
824
825 /* Reenable CONNECTION events */
826 Enable(GSOCK_CONNECTION);
827
828 if (connection->m_fd == INVALID_SOCKET)
829 {
830 if (errno == EWOULDBLOCK)
831 m_error = GSOCK_WOULDBLOCK;
832 else
833 m_error = GSOCK_IOERR;
834
835 delete connection;
836 return NULL;
837 }
838
839 /* Initialize all fields */
840 connection->m_server = false;
841 connection->m_stream = true;
842
843 /* Setup the peer address field */
844 connection->m_peer = GAddress_new();
845 if (!connection->m_peer)
846 {
847 delete connection;
848 m_error = GSOCK_MEMERR;
849 return NULL;
850 }
851
852 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
853 if (err != GSOCK_NOERROR)
854 {
855 delete connection;
856 m_error = err;
857 return NULL;
858 }
859
860 #if defined(__EMX__) || defined(__VISAGECPP__)
861 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
862 #else
863 ioctl(connection->m_fd, FIONBIO, &arg);
864 #endif
865 if (m_use_events)
866 connection->Notify(true);
867
868 return connection;
869 }
870
871 void GSocket::Notify(bool flag)
872 {
873 if (flag == m_use_events)
874 return;
875 #if wxUSE_THREADS
876 // it is not safe to attach or detach i/o descriptor in child thread
877 wxASSERT_MSG( wxThread::IsMain(), "should be called in main thread only" );
878 #endif
879 m_use_events = flag;
880 EnableEvents(flag);
881 }
882
883 void GSocket::EnableEvents(bool flag)
884 {
885 if (flag)
886 GSocketManager::Get()->Enable_Events(this);
887 else
888 GSocketManager::Get()->Disable_Events(this);
889 }
890
891 bool GSocket::SetReusable()
892 {
893 /* socket must not be null, and must not be in use/already bound */
894 if (this && m_fd == INVALID_SOCKET)
895 {
896 m_reusable = true;
897
898 return true;
899 }
900
901 return false;
902 }
903
904 bool GSocket::SetBroadcast()
905 {
906 /* socket must not be in use/already bound */
907 if (m_fd == INVALID_SOCKET) {
908 m_broadcast = true;
909 return true;
910 }
911 return false;
912 }
913
914 bool GSocket::DontDoBind()
915 {
916 /* socket must not be in use/already bound */
917 if (m_fd == INVALID_SOCKET) {
918 m_dobind = false;
919 return true;
920 }
921 return false;
922 }
923
924 /* Client specific parts */
925
926 /* GSocket_Connect:
927 * For stream (connection oriented) sockets, GSocket_Connect() tries
928 * to establish a client connection to a server using the peer address
929 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
930 * connection has been successfully established, or one of the error
931 * codes listed below. Note that for nonblocking sockets, a return
932 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
933 * request can be completed later; you should use GSocket_Select()
934 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
935 * corresponding asynchronous events.
936 *
937 * For datagram (non connection oriented) sockets, GSocket_Connect()
938 * just sets the peer address established with GSocket_SetPeer() as
939 * default destination.
940 *
941 * Error codes:
942 * GSOCK_INVSOCK - the socket is in use or not valid.
943 * GSOCK_INVADDR - the peer address has not been established.
944 * GSOCK_TIMEDOUT - timeout, the connection failed.
945 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
946 * GSOCK_MEMERR - couldn't allocate memory.
947 * GSOCK_IOERR - low-level error.
948 */
949 GSocketError GSocket::Connect(GSocketStream stream)
950 {
951 int err, ret;
952 int arg = 1;
953
954 assert(this);
955
956 /* Enable CONNECTION events (needed for nonblocking connections) */
957 Enable(GSOCK_CONNECTION);
958
959 if (m_fd != INVALID_SOCKET)
960 {
961 m_error = GSOCK_INVSOCK;
962 return GSOCK_INVSOCK;
963 }
964
965 if (!m_peer)
966 {
967 m_error = GSOCK_INVADDR;
968 return GSOCK_INVADDR;
969 }
970
971 /* Streamed or dgram socket? */
972 m_stream = (stream == GSOCK_STREAMED);
973 m_server = false;
974 m_establishing = false;
975
976 /* Create the socket */
977 m_fd = socket(m_peer->m_realfamily,
978 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
979
980 if (m_fd == INVALID_SOCKET)
981 {
982 m_error = GSOCK_IOERR;
983 return GSOCK_IOERR;
984 }
985
986 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
987 #ifdef SO_NOSIGPIPE
988 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
989 #endif
990
991 #if defined(__EMX__) || defined(__VISAGECPP__)
992 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
993 #else
994 ioctl(m_fd, FIONBIO, &arg);
995 #endif
996
997 // If the reuse flag is set, use the applicable socket reuse flags(s)
998 if (m_reusable)
999 {
1000 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
1001 #ifdef SO_REUSEPORT
1002 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
1003 #endif
1004 }
1005
1006 if (m_initialRecvBufferSize >= 0)
1007 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
1008 if (m_initialSendBufferSize >= 0)
1009 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
1010
1011 // If a local address has been set, then we need to bind to it before calling connect
1012 if (m_local && m_local->m_addr)
1013 {
1014 bind(m_fd, m_local->m_addr, m_local->m_len);
1015 }
1016
1017 /* Connect it to the peer address, with a timeout (see below) */
1018 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
1019
1020 /* We only call Enable_Events if we know we aren't shutting down the socket.
1021 * NB: Enable_Events needs to be called whether the socket is blocking or
1022 * non-blocking, it just shouldn't be called prior to knowing there is a
1023 * connection _if_ blocking sockets are being used.
1024 * If connect above returns 0, we are already connected and need to make the
1025 * call to Enable_Events now.
1026 */
1027
1028 if (m_use_events && (m_non_blocking || ret == 0))
1029 EnableEvents();
1030
1031 if (ret == -1)
1032 {
1033 err = errno;
1034
1035 /* If connect failed with EINPROGRESS and the GSocket object
1036 * is in blocking mode, we select() for the specified timeout
1037 * checking for writability to see if the connection request
1038 * completes.
1039 */
1040 if ((err == EINPROGRESS) && (!m_non_blocking))
1041 {
1042 if (Output_Timeout() == GSOCK_TIMEDOUT)
1043 {
1044 Close();
1045 /* m_error is set in _GSocket_Output_Timeout */
1046 return GSOCK_TIMEDOUT;
1047 }
1048 else
1049 {
1050 int error;
1051 SOCKOPTLEN_T len = sizeof(error);
1052
1053 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
1054 if (m_use_events)
1055 EnableEvents();
1056
1057 if (!error)
1058 return GSOCK_NOERROR;
1059 }
1060 }
1061
1062 /* If connect failed with EINPROGRESS and the GSocket object
1063 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1064 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1065 * this way if the connection completes, a GSOCK_CONNECTION
1066 * event will be generated, if enabled.
1067 */
1068 if ((err == EINPROGRESS) && (m_non_blocking))
1069 {
1070 m_establishing = true;
1071 m_error = GSOCK_WOULDBLOCK;
1072 return GSOCK_WOULDBLOCK;
1073 }
1074
1075 /* If connect failed with an error other than EINPROGRESS,
1076 * then the call to GSocket_Connect has failed.
1077 */
1078 Close();
1079 m_error = GSOCK_IOERR;
1080
1081 return GSOCK_IOERR;
1082 }
1083
1084 return GSOCK_NOERROR;
1085 }
1086
1087 /* Datagram sockets */
1088
1089 /* GSocket_SetNonOriented:
1090 * Sets up this socket as a non-connection oriented (datagram) socket.
1091 * Before using this function, the local address must have been set
1092 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1093 * on success, or one of the following otherwise.
1094 *
1095 * Error codes:
1096 * GSOCK_INVSOCK - the socket is in use.
1097 * GSOCK_INVADDR - the local address has not been set.
1098 * GSOCK_IOERR - low-level error.
1099 */
1100 GSocketError GSocket::SetNonOriented()
1101 {
1102 int arg = 1;
1103
1104 assert(this);
1105
1106 if (m_fd != INVALID_SOCKET)
1107 {
1108 m_error = GSOCK_INVSOCK;
1109 return GSOCK_INVSOCK;
1110 }
1111
1112 if (!m_local)
1113 {
1114 m_error = GSOCK_INVADDR;
1115 return GSOCK_INVADDR;
1116 }
1117
1118 /* Initialize all fields */
1119 m_stream = false;
1120 m_server = false;
1121
1122 /* Create the socket */
1123 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
1124
1125 if (m_fd == INVALID_SOCKET)
1126 {
1127 m_error = GSOCK_IOERR;
1128 return GSOCK_IOERR;
1129 }
1130 #if defined(__EMX__) || defined(__VISAGECPP__)
1131 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
1132 #else
1133 ioctl(m_fd, FIONBIO, &arg);
1134 #endif
1135 if (m_use_events)
1136 EnableEvents();
1137
1138 if (m_reusable)
1139 {
1140 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
1141 #ifdef SO_REUSEPORT
1142 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
1143 #endif
1144 }
1145
1146 if (m_broadcast)
1147 {
1148 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
1149 }
1150 if (m_dobind)
1151 {
1152 /* Bind to the local address,
1153 * and retrieve the actual address bound.
1154 */
1155 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
1156 (getsockname(m_fd,
1157 m_local->m_addr,
1158 (WX_SOCKLEN_T *) &m_local->m_len) != 0))
1159 {
1160 Close();
1161 m_error = GSOCK_IOERR;
1162 return GSOCK_IOERR;
1163 }
1164 }
1165 return GSOCK_NOERROR;
1166 }
1167
1168 /* Generic IO */
1169
1170 /* Like recv(), send(), ... */
1171 int GSocket::Read(char *buffer, int size)
1172 {
1173 int ret;
1174
1175 assert(this);
1176
1177 if (m_fd == INVALID_SOCKET || m_server)
1178 {
1179 m_error = GSOCK_INVSOCK;
1180 return -1;
1181 }
1182
1183 /* Disable events during query of socket status */
1184 Disable(GSOCK_INPUT);
1185
1186 /* If the socket is blocking, wait for data (with a timeout) */
1187 if (Input_Timeout() == GSOCK_TIMEDOUT) {
1188 m_error = GSOCK_TIMEDOUT;
1189 /* Don't return here immediately, otherwise socket events would not be
1190 * re-enabled! */
1191 ret = -1;
1192 }
1193 else
1194 {
1195 /* Read the data */
1196 if (m_stream)
1197 ret = Recv_Stream(buffer, size);
1198 else
1199 ret = Recv_Dgram(buffer, size);
1200
1201 /* If recv returned zero, then the connection has been gracefully closed.
1202 * Otherwise, recv has returned an error (-1), in which case we have lost the
1203 * socket only if errno does _not_ indicate that there may be more data to read.
1204 */
1205 if (ret == 0)
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 /* graceful shutdown */
1781 CALL_CALLBACK(this, GSOCK_LOST);
1782 Shutdown();
1783 }
1784 else
1785 {
1786 /* Do not throw a lost event in cases where the socket isn't really lost */
1787 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
1788 {
1789 CALL_CALLBACK(this, GSOCK_INPUT);
1790 }
1791 else
1792 {
1793 CALL_CALLBACK(this, GSOCK_LOST);
1794 Shutdown();
1795 }
1796 }
1797 }
1798 }
1799
1800 void GSocket::Detected_Write()
1801 {
1802 /* If we have already detected a LOST event, then don't try
1803 * to do any further processing.
1804 */
1805 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1806 {
1807 m_establishing = false;
1808
1809 CALL_CALLBACK(this, GSOCK_LOST);
1810 Shutdown();
1811 return;
1812 }
1813
1814 if (m_establishing && !m_server)
1815 {
1816 int error;
1817 SOCKOPTLEN_T len = sizeof(error);
1818
1819 m_establishing = false;
1820
1821 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1822
1823 if (error)
1824 {
1825 CALL_CALLBACK(this, GSOCK_LOST);
1826 Shutdown();
1827 }
1828 else
1829 {
1830 CALL_CALLBACK(this, GSOCK_CONNECTION);
1831 /* We have to fire this event by hand because CONNECTION (for clients)
1832 * and OUTPUT are internally the same and we just disabled CONNECTION
1833 * events with the above macro.
1834 */
1835 CALL_CALLBACK(this, GSOCK_OUTPUT);
1836 }
1837 }
1838 else
1839 {
1840 CALL_CALLBACK(this, GSOCK_OUTPUT);
1841 }
1842 }
1843
1844 /* Compatibility functions for GSocket */
1845 GSocket *GSocket_new(void)
1846 {
1847 GSocket *newsocket = new GSocket();
1848 if (newsocket->IsOk())
1849 return newsocket;
1850
1851 delete newsocket;
1852
1853 return NULL;
1854 }
1855
1856 /*
1857 * -------------------------------------------------------------------------
1858 * GAddress
1859 * -------------------------------------------------------------------------
1860 */
1861
1862 /* CHECK_ADDRESS verifies that the current address family is either
1863 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1864 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1865 * an appropiate error code.
1866 *
1867 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1868 */
1869 #define CHECK_ADDRESS(address, family) \
1870 { \
1871 if (address->m_family == GSOCK_NOFAMILY) \
1872 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1873 return address->m_error; \
1874 if (address->m_family != GSOCK_##family) \
1875 { \
1876 address->m_error = GSOCK_INVADDR; \
1877 return GSOCK_INVADDR; \
1878 } \
1879 }
1880
1881 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1882 { \
1883 if (address->m_family == GSOCK_NOFAMILY) \
1884 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1885 return retval; \
1886 if (address->m_family != GSOCK_##family) \
1887 { \
1888 address->m_error = GSOCK_INVADDR; \
1889 return retval; \
1890 } \
1891 }
1892
1893
1894 GAddress *GAddress_new(void)
1895 {
1896 GAddress *address;
1897
1898 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1899 return NULL;
1900
1901 address->m_family = GSOCK_NOFAMILY;
1902 address->m_addr = NULL;
1903 address->m_len = 0;
1904
1905 return address;
1906 }
1907
1908 GAddress *GAddress_copy(GAddress *address)
1909 {
1910 GAddress *addr2;
1911
1912 assert(address != NULL);
1913
1914 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1915 return NULL;
1916
1917 memcpy(addr2, address, sizeof(GAddress));
1918
1919 if (address->m_addr && address->m_len > 0)
1920 {
1921 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1922 if (addr2->m_addr == NULL)
1923 {
1924 free(addr2);
1925 return NULL;
1926 }
1927 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1928 }
1929
1930 return addr2;
1931 }
1932
1933 void GAddress_destroy(GAddress *address)
1934 {
1935 assert(address != NULL);
1936
1937 if (address->m_addr)
1938 free(address->m_addr);
1939
1940 free(address);
1941 }
1942
1943 void GAddress_SetFamily(GAddress *address, GAddressType type)
1944 {
1945 assert(address != NULL);
1946
1947 address->m_family = type;
1948 }
1949
1950 GAddressType GAddress_GetFamily(GAddress *address)
1951 {
1952 assert(address != NULL);
1953
1954 return address->m_family;
1955 }
1956
1957 GSocketError _GAddress_translate_from(GAddress *address,
1958 struct sockaddr *addr, int len)
1959 {
1960 address->m_realfamily = addr->sa_family;
1961 switch (addr->sa_family)
1962 {
1963 case AF_INET:
1964 address->m_family = GSOCK_INET;
1965 break;
1966 case AF_UNIX:
1967 address->m_family = GSOCK_UNIX;
1968 break;
1969 #if wxUSE_IPV6
1970 case AF_INET6:
1971 address->m_family = GSOCK_INET6;
1972 break;
1973 #endif // wxUSE_IPV6
1974 default:
1975 {
1976 address->m_error = GSOCK_INVOP;
1977 return GSOCK_INVOP;
1978 }
1979 }
1980
1981 if (address->m_addr)
1982 free(address->m_addr);
1983
1984 address->m_len = len;
1985 address->m_addr = (struct sockaddr *)malloc(len);
1986
1987 if (address->m_addr == NULL)
1988 {
1989 address->m_error = GSOCK_MEMERR;
1990 return GSOCK_MEMERR;
1991 }
1992
1993 memcpy(address->m_addr, addr, len);
1994
1995 return GSOCK_NOERROR;
1996 }
1997
1998 GSocketError _GAddress_translate_to(GAddress *address,
1999 struct sockaddr **addr, int *len)
2000 {
2001 if (!address->m_addr)
2002 {
2003 address->m_error = GSOCK_INVADDR;
2004 return GSOCK_INVADDR;
2005 }
2006
2007 *len = address->m_len;
2008 *addr = (struct sockaddr *)malloc(address->m_len);
2009 if (*addr == NULL)
2010 {
2011 address->m_error = GSOCK_MEMERR;
2012 return GSOCK_MEMERR;
2013 }
2014
2015 memcpy(*addr, address->m_addr, address->m_len);
2016 return GSOCK_NOERROR;
2017 }
2018
2019 /*
2020 * -------------------------------------------------------------------------
2021 * Internet address family
2022 * -------------------------------------------------------------------------
2023 */
2024
2025 GSocketError _GAddress_Init_INET(GAddress *address)
2026 {
2027 address->m_len = sizeof(struct sockaddr_in);
2028 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2029 if (address->m_addr == NULL)
2030 {
2031 address->m_error = GSOCK_MEMERR;
2032 return GSOCK_MEMERR;
2033 }
2034
2035 address->m_family = GSOCK_INET;
2036 address->m_realfamily = PF_INET;
2037 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
2038 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
2039
2040 return GSOCK_NOERROR;
2041 }
2042
2043 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
2044 {
2045 struct hostent *he;
2046 struct in_addr *addr;
2047
2048 assert(address != NULL);
2049
2050 CHECK_ADDRESS(address, INET);
2051
2052 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2053
2054 /* If it is a numeric host name, convert it now */
2055 #if defined(HAVE_INET_ATON)
2056 if (inet_aton(hostname, addr) == 0)
2057 {
2058 #elif defined(HAVE_INET_ADDR)
2059 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
2060 {
2061 #else
2062 /* Use gethostbyname by default */
2063 #ifndef __WXMAC__
2064 int val = 1; /* VA doesn't like constants in conditional expressions */
2065 if (val)
2066 #endif
2067 {
2068 #endif
2069 struct in_addr *array_addr;
2070
2071 /* It is a real name, we solve it */
2072 struct hostent h;
2073 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2074 struct hostent_data buffer;
2075 #else
2076 char buffer[1024];
2077 #endif
2078 int err;
2079 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
2080 if (he == NULL)
2081 {
2082 /* Reset to invalid address */
2083 addr->s_addr = INADDR_NONE;
2084 address->m_error = GSOCK_NOHOST;
2085 return GSOCK_NOHOST;
2086 }
2087
2088 array_addr = (struct in_addr *) *(he->h_addr_list);
2089 addr->s_addr = array_addr[0].s_addr;
2090 }
2091
2092 return GSOCK_NOERROR;
2093 }
2094
2095
2096 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
2097 {
2098 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2099 }
2100
2101 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2102 {
2103 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2104 }
2105
2106 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2107 unsigned long hostaddr)
2108 {
2109 struct in_addr *addr;
2110
2111 assert(address != NULL);
2112
2113 CHECK_ADDRESS(address, INET);
2114
2115 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2116 addr->s_addr = htonl(hostaddr);
2117
2118 return GSOCK_NOERROR;
2119 }
2120
2121 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2122 const char *protocol)
2123 {
2124 struct servent *se;
2125 struct sockaddr_in *addr;
2126
2127 assert(address != NULL);
2128 CHECK_ADDRESS(address, INET);
2129
2130 if (!port)
2131 {
2132 address->m_error = GSOCK_INVPORT;
2133 return GSOCK_INVPORT;
2134 }
2135
2136 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2137 struct servent_data buffer;
2138 #else
2139 char buffer[1024];
2140 #endif
2141 struct servent serv;
2142 se = wxGetservbyname_r(port, protocol, &serv,
2143 (void*)&buffer, sizeof(buffer));
2144 if (!se)
2145 {
2146 /* the cast to int suppresses compiler warnings about subscript having the
2147 type char */
2148 if (isdigit((int)port[0]))
2149 {
2150 int port_int;
2151
2152 port_int = atoi(port);
2153 addr = (struct sockaddr_in *)address->m_addr;
2154 addr->sin_port = htons(port_int);
2155 return GSOCK_NOERROR;
2156 }
2157
2158 address->m_error = GSOCK_INVPORT;
2159 return GSOCK_INVPORT;
2160 }
2161
2162 addr = (struct sockaddr_in *)address->m_addr;
2163 addr->sin_port = se->s_port;
2164
2165 return GSOCK_NOERROR;
2166 }
2167
2168 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2169 {
2170 struct sockaddr_in *addr;
2171
2172 assert(address != NULL);
2173 CHECK_ADDRESS(address, INET);
2174
2175 addr = (struct sockaddr_in *)address->m_addr;
2176 addr->sin_port = htons(port);
2177
2178 return GSOCK_NOERROR;
2179 }
2180
2181 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2182 {
2183 struct hostent *he;
2184 char *addr_buf;
2185 struct sockaddr_in *addr;
2186
2187 assert(address != NULL);
2188 CHECK_ADDRESS(address, INET);
2189
2190 addr = (struct sockaddr_in *)address->m_addr;
2191 addr_buf = (char *)&(addr->sin_addr);
2192
2193 struct hostent temphost;
2194 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2195 struct hostent_data buffer;
2196 #else
2197 char buffer[1024];
2198 #endif
2199 int err;
2200 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2201 (void*)&buffer, sizeof(buffer), &err);
2202 if (he == NULL)
2203 {
2204 address->m_error = GSOCK_NOHOST;
2205 return GSOCK_NOHOST;
2206 }
2207
2208 strncpy(hostname, he->h_name, sbuf);
2209
2210 return GSOCK_NOERROR;
2211 }
2212
2213 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2214 {
2215 struct sockaddr_in *addr;
2216
2217 assert(address != NULL);
2218 CHECK_ADDRESS_RETVAL(address, INET, 0);
2219
2220 addr = (struct sockaddr_in *)address->m_addr;
2221
2222 return ntohl(addr->sin_addr.s_addr);
2223 }
2224
2225 unsigned short GAddress_INET_GetPort(GAddress *address)
2226 {
2227 struct sockaddr_in *addr;
2228
2229 assert(address != NULL);
2230 CHECK_ADDRESS_RETVAL(address, INET, 0);
2231
2232 addr = (struct sockaddr_in *)address->m_addr;
2233 return ntohs(addr->sin_port);
2234 }
2235
2236 #if wxUSE_IPV6
2237 /*
2238 * -------------------------------------------------------------------------
2239 * Internet IPv6 address family
2240 * -------------------------------------------------------------------------
2241 */
2242
2243 GSocketError _GAddress_Init_INET6(GAddress *address)
2244 {
2245 struct in6_addr any_address = IN6ADDR_ANY_INIT;
2246 address->m_len = sizeof(struct sockaddr_in6);
2247 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2248 if (address->m_addr == NULL)
2249 {
2250 address->m_error = GSOCK_MEMERR;
2251 return GSOCK_MEMERR;
2252 }
2253 memset(address->m_addr,0,address->m_len);
2254
2255 address->m_family = GSOCK_INET6;
2256 address->m_realfamily = AF_INET6;
2257 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
2258 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
2259
2260 return GSOCK_NOERROR;
2261 }
2262
2263 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
2264 {
2265 assert(address != NULL);
2266 CHECK_ADDRESS(address, INET6);
2267
2268 addrinfo hints;
2269 memset( & hints, 0, sizeof( hints ) );
2270 hints.ai_family = AF_INET6;
2271 addrinfo * info = 0;
2272 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
2273 {
2274 address->m_error = GSOCK_NOHOST;
2275 return GSOCK_NOHOST;
2276 }
2277
2278 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
2279 freeaddrinfo( info );
2280 return GSOCK_NOERROR;
2281 }
2282
2283 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
2284 {
2285 assert(address != NULL);
2286
2287 CHECK_ADDRESS(address, INET6);
2288
2289 struct in6_addr addr;
2290 memset( & addr, 0, sizeof( addr ) );
2291 return GAddress_INET6_SetHostAddress(address, addr);
2292 }
2293 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
2294 struct in6_addr hostaddr)
2295 {
2296 assert(address != NULL);
2297
2298 CHECK_ADDRESS(address, INET6);
2299
2300 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
2301
2302 return GSOCK_NOERROR;
2303 }
2304
2305 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
2306 const char *protocol)
2307 {
2308 struct servent *se;
2309 struct sockaddr_in6 *addr;
2310
2311 assert(address != NULL);
2312 CHECK_ADDRESS(address, INET6);
2313
2314 if (!port)
2315 {
2316 address->m_error = GSOCK_INVPORT;
2317 return GSOCK_INVPORT;
2318 }
2319
2320 se = getservbyname(port, protocol);
2321 if (!se)
2322 {
2323 if (isdigit(port[0]))
2324 {
2325 int port_int;
2326
2327 port_int = atoi(port);
2328 addr = (struct sockaddr_in6 *)address->m_addr;
2329 addr->sin6_port = htons((u_short) port_int);
2330 return GSOCK_NOERROR;
2331 }
2332
2333 address->m_error = GSOCK_INVPORT;
2334 return GSOCK_INVPORT;
2335 }
2336
2337 addr = (struct sockaddr_in6 *)address->m_addr;
2338 addr->sin6_port = se->s_port;
2339
2340 return GSOCK_NOERROR;
2341 }
2342
2343 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
2344 {
2345 struct sockaddr_in6 *addr;
2346
2347 assert(address != NULL);
2348 CHECK_ADDRESS(address, INET6);
2349
2350 addr = (struct sockaddr_in6 *)address->m_addr;
2351 addr->sin6_port = htons(port);
2352
2353 return GSOCK_NOERROR;
2354 }
2355
2356 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2357 {
2358 struct hostent *he;
2359 char *addr_buf;
2360 struct sockaddr_in6 *addr;
2361
2362 assert(address != NULL);
2363 CHECK_ADDRESS(address, INET6);
2364
2365 addr = (struct sockaddr_in6 *)address->m_addr;
2366 addr_buf = (char *)&(addr->sin6_addr);
2367
2368 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
2369 if (he == NULL)
2370 {
2371 address->m_error = GSOCK_NOHOST;
2372 return GSOCK_NOHOST;
2373 }
2374
2375 strncpy(hostname, he->h_name, sbuf);
2376
2377 return GSOCK_NOERROR;
2378 }
2379
2380 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
2381 {
2382 assert(address != NULL);
2383 assert(hostaddr != NULL);
2384 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2385 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2386 return GSOCK_NOERROR;
2387 }
2388
2389 unsigned short GAddress_INET6_GetPort(GAddress *address)
2390 {
2391 assert(address != NULL);
2392 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2393
2394 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2395 }
2396
2397 #endif // wxUSE_IPV6
2398
2399 /*
2400 * -------------------------------------------------------------------------
2401 * Unix address family
2402 * -------------------------------------------------------------------------
2403 */
2404
2405 #ifndef __VISAGECPP__
2406 GSocketError _GAddress_Init_UNIX(GAddress *address)
2407 {
2408 address->m_len = sizeof(struct sockaddr_un);
2409 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2410 if (address->m_addr == NULL)
2411 {
2412 address->m_error = GSOCK_MEMERR;
2413 return GSOCK_MEMERR;
2414 }
2415
2416 address->m_family = GSOCK_UNIX;
2417 address->m_realfamily = PF_UNIX;
2418 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2419 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2420
2421 return GSOCK_NOERROR;
2422 }
2423
2424 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2425
2426 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2427 {
2428 struct sockaddr_un *addr;
2429
2430 assert(address != NULL);
2431
2432 CHECK_ADDRESS(address, UNIX);
2433
2434 addr = ((struct sockaddr_un *)address->m_addr);
2435 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2436 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2437
2438 return GSOCK_NOERROR;
2439 }
2440
2441 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2442 {
2443 struct sockaddr_un *addr;
2444
2445 assert(address != NULL);
2446 CHECK_ADDRESS(address, UNIX);
2447
2448 addr = (struct sockaddr_un *)address->m_addr;
2449
2450 strncpy(path, addr->sun_path, sbuf);
2451
2452 return GSOCK_NOERROR;
2453 }
2454 #endif /* !defined(__VISAGECPP__) */
2455 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */