]> git.saurik.com Git - wxWidgets.git/blame - src/unix/gsocket.cpp
prevent memory leak
[wxWidgets.git] / src / unix / gsocket.cpp
CommitLineData
97e6ee04 1/* -------------------------------------------------------------------------
99d80019
JS
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$
97e6ee04
DE
12 * -------------------------------------------------------------------------
13 */
14
7e1e6965
WS
15#if defined(__WATCOMC__)
16#include "wx/wxprec.h"
17#include <errno.h>
18#include <nerrno.h>
19#endif
20
ba2a81d7 21#ifndef __GSOCKET_STANDALONE__
0beb8735 22#include "wx/defs.h"
5e1eac14 23#include "wx/private/gsocketiohandler.h"
2804f77d 24#include "wx/thread.h" // for wxThread::IsMain() used in assert
ba2a81d7 25#endif
97e6ee04
DE
26
27#if defined(__VISAGECPP__)
1aa7b427 28#define BSD_SELECT /* use Berkeley Sockets select */
97e6ee04
DE
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
bc023abb
MW
44#ifdef HAVE_SYS_SELECT_H
45# include <sys/select.h>
46#endif
47
97e6ee04
DE
48#ifdef __VMS__
49#include <socket.h>
50struct 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)
89int _System bsdselect(int,
90 struct fd_set *,
91 struct fd_set *,
92 struct fd_set *,
93 struct timeval *);
94int _System soclose(int);
95# endif
96#endif
ebdab982
SN
97#ifdef __EMX__
98#include <sys/select.h>
99#endif
100
97e6ee04
DE
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
d1f8e97b
SN
111#ifdef _AIX
112# include <strings.h>
113#endif
97e6ee04
DE
114#include <signal.h>
115
9e03e02d 116#ifndef WX_SOCKLEN_T
97e6ee04
DE
117
118#ifdef VMS
9e03e02d 119# define WX_SOCKLEN_T unsigned int
97e6ee04
DE
120#else
121# ifdef __GLIBC__
122# if __GLIBC__ == 2
9e03e02d 123# define WX_SOCKLEN_T socklen_t
97e6ee04 124# endif
fcbd7e5a 125# elif defined(__WXMAC__)
9e03e02d 126# define WX_SOCKLEN_T socklen_t
97e6ee04 127# else
9e03e02d 128# define WX_SOCKLEN_T int
97e6ee04
DE
129# endif
130#endif
131
132#endif /* SOCKLEN_T */
133
ddc1a35f 134#ifndef SOCKOPTLEN_T
9e03e02d 135#define SOCKOPTLEN_T WX_SOCKLEN_T
ddc1a35f
DE
136#endif
137
97e6ee04
DE
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
7e1e6965 158#if defined(__VISAGECPP__) || defined(__WATCOMC__)
97e6ee04 159
7e1e6965
WS
160 #define MASK_SIGNAL() {
161 #define UNMASK_SIGNAL() }
162
163#else
defbeca1 164 extern "C" { typedef void (*wxSigHandler)(int); }
7e1e6965
WS
165
166 #define MASK_SIGNAL() \
167 { \
defbeca1 168 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
7e1e6965
WS
169
170 #define UNMASK_SIGNAL() \
171 signal(SIGPIPE, old_handler); \
172 }
173
174#endif
97e6ee04 175
e400d27d
KH
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. */
bb154f79
KH
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 */
97e6ee04
DE
185
186#ifndef __GSOCKET_STANDALONE__
187# include "wx/unix/gsockunx.h"
17a1ebd1 188# include "wx/unix/private.h"
97e6ee04 189# include "wx/gsocket.h"
71b4a9b8
SN
190#if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
191# include "wx/thread.h"
192#endif
97e6ee04
DE
193#else
194# include "gsockunx.h"
195# include "gsocket.h"
5fb9aa56
WS
196# ifndef WXUNUSED
197# define WXUNUSED(x)
198# endif
97e6ee04
DE
199#endif /* __GSOCKET_STANDALONE__ */
200
71b4a9b8
SN
201#if defined(HAVE_GETHOSTBYNAME)
202static struct hostent * deepCopyHostent(struct hostent *h,
203 const struct hostent *he,
204 char *buffer, int size, int *err)
205{
2887cb4e 206 /* copy old structure */
71b4a9b8 207 memcpy(h, he, sizeof(struct hostent));
2887cb4e
SN
208
209 /* copy name */
71b4a9b8
SN
210 int len = strlen(h->h_name);
211 if (len > size)
2887cb4e
SN
212 {
213 *err = ENOMEM;
214 return NULL;
215 }
71b4a9b8
SN
216 memcpy(buffer, h->h_name, len);
217 buffer[len] = '\0';
218 h->h_name = buffer;
2887cb4e
SN
219
220 /* track position in the buffer */
221 int pos = len + 1;
222
223 /* reuse len to store address length */
71b4a9b8 224 len = h->h_length;
2887cb4e
SN
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 {
71b4a9b8
SN
242 *err = ENOMEM;
243 return NULL;
244 }
2887cb4e
SN
245 memcpy(buffer + pos, *p, len); /* copy content */
246 *q = buffer + pos; /* set copied pointer to copied content */
247 pos += len;
71b4a9b8 248 }
2887cb4e
SN
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;
01ba4b67 256
2887cb4e
SN
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 *);
01ba4b67 262
2887cb4e
SN
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;
71b4a9b8 276 }
2887cb4e
SN
277 *++q = 0; /* null terminate the pointer list */
278 h->h_aliases = h_aliases; /* copy pointer to pointers */
279
71b4a9b8
SN
280 return h;
281}
282#endif
283
2887cb4e
SN
284#if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
285static wxMutex nameLock;
286#endif
71b4a9b8
SN
287struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h,
288 void *buffer, int size, int *err)
289
290{
539ae551 291 struct hostent *he = NULL;
71b4a9b8
SN
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
71b4a9b8
SN
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
2887cb4e
SN
319#if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
320static wxMutex addrLock;
321#endif
71b4a9b8
SN
322struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size,
323 int proto, struct hostent *h,
324 void *buffer, int size, int *err)
325{
539ae551 326 struct hostent *he = NULL;
71b4a9b8
SN
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
71b4a9b8
SN
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
f0b805fa 356#if defined(HAVE_GETSERVBYNAME)
71b4a9b8
SN
357static struct servent * deepCopyServent(struct servent *s,
358 const struct servent *se,
359 char *buffer, int size)
360{
2887cb4e 361 /* copy plain old structure */
71b4a9b8 362 memcpy(s, se, sizeof(struct servent));
2887cb4e
SN
363
364 /* copy name */
71b4a9b8 365 int len = strlen(s->s_name);
2887cb4e
SN
366 if (len >= size)
367 {
368 return NULL;
369 }
71b4a9b8
SN
370 memcpy(buffer, s->s_name, len);
371 buffer[len] = '\0';
372 s->s_name = buffer;
2887cb4e
SN
373
374 /* track position in the buffer */
375 int pos = len + 1;
376
377 /* copy protocol */
71b4a9b8 378 len = strlen(s->s_proto);
2887cb4e
SN
379 if (pos + len >= size)
380 {
381 return NULL;
71b4a9b8 382 }
2887cb4e
SN
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;
01ba4b67 394
2887cb4e
SN
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 *);
01ba4b67 400
2887cb4e
SN
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 */
71b4a9b8
SN
415 return s;
416}
417#endif
418
2887cb4e
SN
419#if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
420static wxMutex servLock;
421#endif
71b4a9b8
SN
422struct servent *wxGetservbyname_r(const char *port, const char *protocol,
423 struct servent *serv, void *buffer, int size)
424{
539ae551 425 struct servent *se = NULL;
71b4a9b8
SN
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
71b4a9b8
SN
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
97e6ee04
DE
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
8575ff50
VZ
454#if wxUSE_IPV6
455typedef struct sockaddr_storage wxSockAddr;
456#else
457typedef struct sockaddr wxSockAddr;
458#endif
459
ba2a81d7
DE
460/* Table of GUI-related functions. We must call them indirectly because
461 * of wxBase and GUI separation: */
444cb1fd 462
2804f77d 463bool GSocket_Init()
985acf87 464{
2804f77d
VZ
465 GSocketManager * const manager = GSocketManager::Get();
466 return manager && manager->OnInit();
97e6ee04
DE
467}
468
2804f77d 469void GSocket_Cleanup()
97e6ee04 470{
2804f77d
VZ
471 GSocketManager * const manager = GSocketManager::Get();
472 if ( manager )
473 manager->OnExit();
97e6ee04
DE
474}
475
ba2a81d7
DE
476/* Constructors / Destructors for GSocket */
477
478GSocket::GSocket()
97e6ee04 479{
09e6e5ec 480 int i;
97e6ee04 481
09e6e5ec 482 m_fd = INVALID_SOCKET;
5e1eac14
VZ
483 m_handler = NULL;
484
97e6ee04
DE
485 for (i=0;i<GSOCK_MAX_EVENT;i++)
486 {
09e6e5ec 487 m_cbacks[i] = NULL;
97e6ee04 488 }
09e6e5ec
DE
489 m_detected = 0;
490 m_local = NULL;
491 m_peer = NULL;
492 m_error = GSOCK_NOERROR;
948c96ef
DE
493 m_server = false;
494 m_stream = true;
09e6e5ec 495 m_gui_dependent = NULL;
948c96ef 496 m_non_blocking = false;
1eef64d8 497 m_reusable = false;
60edcf45
VZ
498 m_broadcast = false;
499 m_dobind = true;
09e6e5ec 500 m_timeout = 10*60*1000;
97e6ee04 501 /* 10 minutes * 60 sec * 1000 millisec */
948c96ef 502 m_establishing = false;
2804f77d 503 m_use_events = false;
8c029a5b
VZ
504 m_initialRecvBufferSize = -1;
505 m_initialSendBufferSize = -1;
97e6ee04 506
2804f77d 507 m_ok = GSocketManager::Get()->Init_Socket(this);
97e6ee04
DE
508}
509
ba2a81d7 510void GSocket::Close()
97e6ee04 511{
2804f77d
VZ
512 if (m_use_events)
513 DisableEvents();
dd6c8be6
DE
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);
09e6e5ec 525 m_fd = INVALID_SOCKET;
97e6ee04
DE
526}
527
ba2a81d7 528GSocket::~GSocket()
97e6ee04 529{
ba2a81d7
DE
530 assert(this);
531
532 /* Check that the socket is really shutdowned */
533 if (m_fd != INVALID_SOCKET)
534 Shutdown();
535
2804f77d 536 GSocketManager::Get()->Destroy_Socket(this);
ba2a81d7 537
5e1eac14
VZ
538 delete m_handler;
539
97e6ee04 540 /* Destroy private addresses */
09e6e5ec
DE
541 if (m_local)
542 GAddress_destroy(m_local);
97e6ee04 543
09e6e5ec
DE
544 if (m_peer)
545 GAddress_destroy(m_peer);
2804f77d 546
97e6ee04
DE
547}
548
549/* GSocket_Shutdown:
550 * Disallow further read/write operations on this socket, close
551 * the fd and disable all callbacks.
552 */
ba2a81d7 553void GSocket::Shutdown()
97e6ee04
DE
554{
555 int evt;
556
09e6e5ec 557 assert(this);
97e6ee04 558
c3b501e1 559 /* Don't allow events to fire after socket has been closed */
2804f77d
VZ
560 if (m_use_events)
561 DisableEvents();
c3b501e1 562
97e6ee04 563 /* If socket has been created, shutdown it */
09e6e5ec 564 if (m_fd != INVALID_SOCKET)
97e6ee04 565 {
cd632a86 566 shutdown(m_fd, 1);
09e6e5ec 567 Close();
97e6ee04
DE
568 }
569
570 /* Disable GUI callbacks */
571 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
09e6e5ec 572 m_cbacks[evt] = NULL;
97e6ee04 573
09e6e5ec 574 m_detected = GSOCK_LOST_FLAG;
97e6ee04
DE
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 */
ba2a81d7 593GSocketError GSocket::SetLocal(GAddress *address)
97e6ee04 594{
09e6e5ec 595 assert(this);
97e6ee04
DE
596
597 /* the socket must be initialized, or it must be a server */
09e6e5ec 598 if ((m_fd != INVALID_SOCKET && !m_server))
97e6ee04 599 {
09e6e5ec 600 m_error = GSOCK_INVSOCK;
97e6ee04
DE
601 return GSOCK_INVSOCK;
602 }
603
604 /* check address */
605 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
606 {
09e6e5ec 607 m_error = GSOCK_INVADDR;
97e6ee04
DE
608 return GSOCK_INVADDR;
609 }
610
09e6e5ec
DE
611 if (m_local)
612 GAddress_destroy(m_local);
97e6ee04 613
09e6e5ec 614 m_local = GAddress_copy(address);
97e6ee04
DE
615
616 return GSOCK_NOERROR;
617}
618
ba2a81d7 619GSocketError GSocket::SetPeer(GAddress *address)
97e6ee04 620{
09e6e5ec 621 assert(this);
97e6ee04
DE
622
623 /* check address */
624 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
625 {
09e6e5ec 626 m_error = GSOCK_INVADDR;
97e6ee04
DE
627 return GSOCK_INVADDR;
628 }
629
09e6e5ec
DE
630 if (m_peer)
631 GAddress_destroy(m_peer);
97e6ee04 632
09e6e5ec 633 m_peer = GAddress_copy(address);
97e6ee04
DE
634
635 return GSOCK_NOERROR;
636}
637
ba2a81d7 638GAddress *GSocket::GetLocal()
97e6ee04
DE
639{
640 GAddress *address;
8575ff50 641 wxSockAddr addr;
9e03e02d 642 WX_SOCKLEN_T size = sizeof(addr);
97e6ee04
DE
643 GSocketError err;
644
09e6e5ec 645 assert(this);
97e6ee04
DE
646
647 /* try to get it from the m_local var first */
09e6e5ec
DE
648 if (m_local)
649 return GAddress_copy(m_local);
97e6ee04
DE
650
651 /* else, if the socket is initialized, try getsockname */
09e6e5ec 652 if (m_fd == INVALID_SOCKET)
97e6ee04 653 {
09e6e5ec 654 m_error = GSOCK_INVSOCK;
97e6ee04
DE
655 return NULL;
656 }
657
8575ff50 658 if (getsockname(m_fd, (sockaddr*)&addr, (WX_SOCKLEN_T *) &size) < 0)
97e6ee04 659 {
09e6e5ec 660 m_error = GSOCK_IOERR;
97e6ee04
DE
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 {
09e6e5ec 668 m_error = GSOCK_MEMERR;
97e6ee04
DE
669 return NULL;
670 }
671
8575ff50 672 err = _GAddress_translate_from(address, (sockaddr*)&addr, size);
97e6ee04
DE
673 if (err != GSOCK_NOERROR)
674 {
675 GAddress_destroy(address);
09e6e5ec 676 m_error = err;
97e6ee04
DE
677 return NULL;
678 }
679
680 return address;
681}
682
ba2a81d7 683GAddress *GSocket::GetPeer()
97e6ee04 684{
09e6e5ec 685 assert(this);
97e6ee04
DE
686
687 /* try to get it from the m_peer var */
09e6e5ec
DE
688 if (m_peer)
689 return GAddress_copy(m_peer);
97e6ee04
DE
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:
b082b524 700 *
97e6ee04
DE
701 * Error codes:
702 * GSOCK_INVSOCK - the socket is in use.
703 * GSOCK_INVADDR - the local address has not been set.
b082b524 704 * GSOCK_IOERR - low-level error.
97e6ee04 705 */
ba2a81d7 706GSocketError GSocket::SetServer()
97e6ee04
DE
707{
708 int arg = 1;
709
09e6e5ec 710 assert(this);
97e6ee04
DE
711
712 /* must not be in use */
09e6e5ec 713 if (m_fd != INVALID_SOCKET)
97e6ee04 714 {
09e6e5ec 715 m_error = GSOCK_INVSOCK;
97e6ee04
DE
716 return GSOCK_INVSOCK;
717 }
718
719 /* the local addr must have been set */
09e6e5ec 720 if (!m_local)
97e6ee04 721 {
09e6e5ec 722 m_error = GSOCK_INVADDR;
97e6ee04
DE
723 return GSOCK_INVADDR;
724 }
725
726 /* Initialize all fields */
948c96ef
DE
727 m_stream = true;
728 m_server = true;
97e6ee04
DE
729
730 /* Create the socket */
09e6e5ec 731 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
97e6ee04 732
09e6e5ec 733 if (m_fd == INVALID_SOCKET)
97e6ee04 734 {
09e6e5ec 735 m_error = GSOCK_IOERR;
97e6ee04
DE
736 return GSOCK_IOERR;
737 }
bb154f79
KH
738
739 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
740#ifdef SO_NOSIGPIPE
01ba4b67 741 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
742#endif
743
09e6e5ec 744 ioctl(m_fd, FIONBIO, &arg);
2804f77d
VZ
745 if (m_use_events)
746 EnableEvents();
97e6ee04
DE
747
748 /* allow a socket to re-bind if the socket is in the TIME_WAIT
749 state after being previously closed.
750 */
ba2a81d7 751 if (m_reusable)
c232b3cd 752 {
01ba4b67 753 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 754#ifdef SO_REUSEPORT
01ba4b67 755 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
756#endif
757 }
97e6ee04
DE
758
759 /* Bind to the local address,
760 * retrieve the actual address bound,
761 * and listen up to 5 connections.
762 */
09e6e5ec
DE
763 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
764 (getsockname(m_fd,
765 m_local->m_addr,
9e03e02d 766 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
09e6e5ec 767 (listen(m_fd, 5) != 0))
97e6ee04 768 {
09e6e5ec
DE
769 Close();
770 m_error = GSOCK_IOERR;
97e6ee04
DE
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.
b082b524 787 * GSOCK_IOERR - low-level error.
97e6ee04 788 */
ba2a81d7 789GSocket *GSocket::WaitConnection()
97e6ee04 790{
8575ff50 791 wxSockAddr from;
9e03e02d 792 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
793 GSocket *connection;
794 GSocketError err;
795 int arg = 1;
796
09e6e5ec 797 assert(this);
97e6ee04 798
97e6ee04 799 /* If the socket has already been created, we exit immediately */
09e6e5ec 800 if (m_fd == INVALID_SOCKET || !m_server)
97e6ee04 801 {
09e6e5ec 802 m_error = GSOCK_INVSOCK;
97e6ee04
DE
803 return NULL;
804 }
805
806 /* Create a GSocket object for the new connection */
444cb1fd 807 connection = GSocket_new();
97e6ee04 808
444cb1fd 809 if (!connection)
97e6ee04 810 {
09e6e5ec 811 m_error = GSOCK_MEMERR;
97e6ee04
DE
812 return NULL;
813 }
814
815 /* Wait for a connection (with timeout) */
09e6e5ec 816 if (Input_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 817 {
85431efa 818 delete connection;
09e6e5ec 819 /* m_error set by _GSocket_Input_Timeout */
97e6ee04
DE
820 return NULL;
821 }
822
8575ff50 823 connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
97e6ee04 824
bb154f79
KH
825 /* Reenable CONNECTION events */
826 Enable(GSOCK_CONNECTION);
bb154f79 827
97e6ee04
DE
828 if (connection->m_fd == INVALID_SOCKET)
829 {
830 if (errno == EWOULDBLOCK)
09e6e5ec 831 m_error = GSOCK_WOULDBLOCK;
97e6ee04 832 else
09e6e5ec 833 m_error = GSOCK_IOERR;
97e6ee04 834
85431efa 835 delete connection;
97e6ee04
DE
836 return NULL;
837 }
838
839 /* Initialize all fields */
948c96ef
DE
840 connection->m_server = false;
841 connection->m_stream = true;
97e6ee04
DE
842
843 /* Setup the peer address field */
844 connection->m_peer = GAddress_new();
845 if (!connection->m_peer)
846 {
85431efa 847 delete connection;
09e6e5ec 848 m_error = GSOCK_MEMERR;
97e6ee04
DE
849 return NULL;
850 }
1aa7b427 851
8575ff50 852 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
97e6ee04
DE
853 if (err != GSOCK_NOERROR)
854 {
85431efa 855 delete connection;
09e6e5ec 856 m_error = err;
97e6ee04
DE
857 return NULL;
858 }
1aa7b427 859
97e6ee04
DE
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
2804f77d
VZ
865 if (m_use_events)
866 connection->Notify(true);
97e6ee04
DE
867
868 return connection;
869}
870
2804f77d
VZ
871void GSocket::Notify(bool flag)
872{
873 if (flag == m_use_events)
874 return;
2ada746f 875#if wxUSE_THREADS
2804f77d
VZ
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" );
2ada746f 878#endif
2804f77d
VZ
879 m_use_events = flag;
880 EnableEvents(flag);
881}
882
883void GSocket::EnableEvents(bool flag)
884{
885 if (flag)
886 GSocketManager::Get()->Enable_Events(this);
887 else
888 GSocketManager::Get()->Disable_Events(this);
889}
890
948c96ef 891bool GSocket::SetReusable()
b082b524
DE
892{
893 /* socket must not be null, and must not be in use/already bound */
1aa7b427
DS
894 if (this && m_fd == INVALID_SOCKET)
895 {
948c96ef 896 m_reusable = true;
1aa7b427 897
948c96ef 898 return true;
b082b524 899 }
1aa7b427 900
948c96ef 901 return false;
b082b524
DE
902}
903
60edcf45
VZ
904bool 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
914bool 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
97e6ee04
DE
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
d6922577 930 * connection has been successfully established, or one of the error
97e6ee04
DE
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.
b082b524 947 * GSOCK_IOERR - low-level error.
97e6ee04 948 */
ba2a81d7 949GSocketError GSocket::Connect(GSocketStream stream)
97e6ee04
DE
950{
951 int err, ret;
952 int arg = 1;
953
09e6e5ec 954 assert(this);
97e6ee04
DE
955
956 /* Enable CONNECTION events (needed for nonblocking connections) */
09e6e5ec 957 Enable(GSOCK_CONNECTION);
97e6ee04 958
09e6e5ec 959 if (m_fd != INVALID_SOCKET)
97e6ee04 960 {
09e6e5ec 961 m_error = GSOCK_INVSOCK;
97e6ee04
DE
962 return GSOCK_INVSOCK;
963 }
964
09e6e5ec 965 if (!m_peer)
97e6ee04 966 {
09e6e5ec 967 m_error = GSOCK_INVADDR;
97e6ee04
DE
968 return GSOCK_INVADDR;
969 }
970
971 /* Streamed or dgram socket? */
09e6e5ec 972 m_stream = (stream == GSOCK_STREAMED);
948c96ef
DE
973 m_server = false;
974 m_establishing = false;
97e6ee04
DE
975
976 /* Create the socket */
09e6e5ec
DE
977 m_fd = socket(m_peer->m_realfamily,
978 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
97e6ee04 979
09e6e5ec 980 if (m_fd == INVALID_SOCKET)
97e6ee04 981 {
09e6e5ec 982 m_error = GSOCK_IOERR;
97e6ee04
DE
983 return GSOCK_IOERR;
984 }
bb154f79
KH
985
986 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
987#ifdef SO_NOSIGPIPE
01ba4b67 988 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
989#endif
990
97e6ee04 991#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 992 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 993#else
09e6e5ec 994 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 995#endif
97e6ee04 996
c232b3cd
KH
997 // If the reuse flag is set, use the applicable socket reuse flags(s)
998 if (m_reusable)
999 {
01ba4b67 1000 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 1001#ifdef SO_REUSEPORT
01ba4b67 1002 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
1003#endif
1004 }
1005
8c029a5b
VZ
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
c232b3cd
KH
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
97e6ee04 1017 /* Connect it to the peer address, with a timeout (see below) */
09e6e5ec 1018 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
97e6ee04 1019
0d34c30e
KH
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
17a1ebd1 1025 * call to Enable_Events now.
a3687636 1026 */
17a1ebd1 1027
2804f77d
VZ
1028 if (m_use_events && (m_non_blocking || ret == 0))
1029 EnableEvents();
bb154f79 1030
97e6ee04
DE
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 */
09e6e5ec 1040 if ((err == EINPROGRESS) && (!m_non_blocking))
97e6ee04 1041 {
09e6e5ec 1042 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 1043 {
09e6e5ec
DE
1044 Close();
1045 /* m_error is set in _GSocket_Output_Timeout */
97e6ee04
DE
1046 return GSOCK_TIMEDOUT;
1047 }
1048 else
1049 {
1050 int error;
ddc1a35f 1051 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1052
f71bb8ef 1053 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
2804f77d
VZ
1054 if (m_use_events)
1055 EnableEvents();
bb154f79 1056
97e6ee04
DE
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 */
09e6e5ec 1068 if ((err == EINPROGRESS) && (m_non_blocking))
97e6ee04 1069 {
948c96ef 1070 m_establishing = true;
09e6e5ec 1071 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
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 */
09e6e5ec
DE
1078 Close();
1079 m_error = GSOCK_IOERR;
1aa7b427 1080
97e6ee04
DE
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 */
ba2a81d7 1100GSocketError GSocket::SetNonOriented()
97e6ee04
DE
1101{
1102 int arg = 1;
1103
09e6e5ec 1104 assert(this);
97e6ee04 1105
09e6e5ec 1106 if (m_fd != INVALID_SOCKET)
97e6ee04 1107 {
09e6e5ec 1108 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1109 return GSOCK_INVSOCK;
1110 }
1111
09e6e5ec 1112 if (!m_local)
97e6ee04 1113 {
09e6e5ec 1114 m_error = GSOCK_INVADDR;
97e6ee04
DE
1115 return GSOCK_INVADDR;
1116 }
1117
1118 /* Initialize all fields */
948c96ef
DE
1119 m_stream = false;
1120 m_server = false;
97e6ee04
DE
1121
1122 /* Create the socket */
09e6e5ec 1123 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
97e6ee04 1124
09e6e5ec 1125 if (m_fd == INVALID_SOCKET)
97e6ee04 1126 {
09e6e5ec 1127 m_error = GSOCK_IOERR;
97e6ee04
DE
1128 return GSOCK_IOERR;
1129 }
1130#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 1131 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 1132#else
09e6e5ec 1133 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 1134#endif
2804f77d
VZ
1135 if (m_use_events)
1136 EnableEvents();
97e6ee04 1137
01ba4b67
VZ
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
60edcf45 1146 if (m_broadcast)
97e6ee04 1147 {
60edcf45
VZ
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 }
97e6ee04 1164 }
97e6ee04
DE
1165 return GSOCK_NOERROR;
1166}
1167
1168/* Generic IO */
1169
1170/* Like recv(), send(), ... */
ba2a81d7 1171int GSocket::Read(char *buffer, int size)
97e6ee04
DE
1172{
1173 int ret;
1174
09e6e5ec 1175 assert(this);
97e6ee04 1176
09e6e5ec 1177 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1178 {
09e6e5ec 1179 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1180 return -1;
1181 }
1182
9d715960
DE
1183 /* Disable events during query of socket status */
1184 Disable(GSOCK_INPUT);
b082b524 1185
97e6ee04 1186 /* If the socket is blocking, wait for data (with a timeout) */
976abb72
VZ
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! */
9d715960 1191 ret = -1;
976abb72 1192 }
1aa7b427
DS
1193 else
1194 {
9d715960
DE
1195 /* Read the data */
1196 if (m_stream)
1197 ret = Recv_Stream(buffer, size);
1198 else
1199 ret = Recv_Dgram(buffer, size);
b082b524 1200
01c03554
VZ
1201 /*
1202 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1203 * socket and empty datagrams are possible), then the connection has been
1204 * gracefully closed.
1205 *
1206 * Otherwise, recv has returned an error (-1), in which case we have lost
1207 * the socket only if errno does _not_ indicate that there may be more data
1208 * to read.
9b67181b 1209 */
01c03554 1210 if ((ret == 0) && m_stream)
98e7a7f9 1211 {
f4854380 1212 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
2804f77d
VZ
1213 if (m_use_events)
1214 {
1215 m_detected = GSOCK_LOST_FLAG;
1216 Detected_Read();
1217 return 0;
1218 }
98e7a7f9 1219 }
1aa7b427
DS
1220 else if (ret == -1)
1221 {
976abb72
VZ
1222 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1223 m_error = GSOCK_WOULDBLOCK;
1224 else
1225 m_error = GSOCK_IOERR;
1226 }
97e6ee04 1227 }
b082b524 1228
9d715960 1229 /* Enable events again now that we are done processing */
09e6e5ec 1230 Enable(GSOCK_INPUT);
97e6ee04
DE
1231
1232 return ret;
1233}
1234
ba2a81d7 1235int GSocket::Write(const char *buffer, int size)
b082b524 1236{
97e6ee04
DE
1237 int ret;
1238
09e6e5ec 1239 assert(this);
b082b524 1240
97e6ee04
DE
1241 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
1242
09e6e5ec 1243 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1244 {
09e6e5ec 1245 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1246 return -1;
1247 }
1248
1249 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
1250
1251 /* If the socket is blocking, wait for writability (with a timeout) */
09e6e5ec 1252 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04
DE
1253 return -1;
1254
1255 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
1256
1257 /* Write the data */
09e6e5ec
DE
1258 if (m_stream)
1259 ret = Send_Stream(buffer, size);
97e6ee04 1260 else
09e6e5ec 1261 ret = Send_Dgram(buffer, size);
b082b524 1262
97e6ee04
DE
1263 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
1264
1265 if (ret == -1)
1266 {
7e1e6965 1267 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
97e6ee04 1268 {
09e6e5ec 1269 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
1270 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1271 }
1272 else
1273 {
09e6e5ec 1274 m_error = GSOCK_IOERR;
97e6ee04
DE
1275 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1276 }
1277
1278 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1279 * in MSW). Once the first OUTPUT event is received, users can assume
1280 * that the socket is writable until a read operation fails. Only then
1281 * will further OUTPUT events be posted.
1282 */
09e6e5ec 1283 Enable(GSOCK_OUTPUT);
1aa7b427 1284
97e6ee04
DE
1285 return -1;
1286 }
b082b524 1287
97e6ee04
DE
1288 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
1289
1290 return ret;
1291}
1292
1293/* GSocket_Select:
1294 * Polls the socket to determine its status. This function will
1295 * check for the events specified in the 'flags' parameter, and
1296 * it will return a mask indicating which operations can be
1297 * performed. This function won't block, regardless of the
1298 * mode (blocking | nonblocking) of the socket.
1299 */
ba2a81d7 1300GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
97e6ee04 1301{
2804f77d 1302 assert(this);
97e6ee04 1303
cf86dc50
VZ
1304 GSocketEventFlags result = 0;
1305 fd_set readfds;
1306 fd_set writefds;
1307 fd_set exceptfds;
1308 struct timeval tv;
1309
1310 if (m_fd == -1)
1311 return (GSOCK_LOST_FLAG & flags);
1312
1313 /* Do not use a static struct, Linux can garble it */
1314 tv.tv_sec = 0;
1315 tv.tv_usec = 0;
1316
1317 wxFD_ZERO(&readfds);
1318 wxFD_ZERO(&writefds);
1319 wxFD_ZERO(&exceptfds);
1320 wxFD_SET(m_fd, &readfds);
1321 if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
1322 wxFD_SET(m_fd, &writefds);
1323 wxFD_SET(m_fd, &exceptfds);
1324
1325 /* Check 'sticky' CONNECTION flag first */
1326 result |= GSOCK_CONNECTION_FLAG & m_detected;
1327
1328 /* If we have already detected a LOST event, then don't try
1329 * to do any further processing.
1330 */
1331 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1332 {
1333 m_establishing = false;
1334 return (GSOCK_LOST_FLAG & flags);
1335 }
1336
1337 /* Try select now */
1338 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
1339 {
1340 /* What to do here? */
1341 return (result & flags);
1342 }
1343
1344 /* Check for exceptions and errors */
1345 if (wxFD_ISSET(m_fd, &exceptfds))
1346 {
1347 m_establishing = false;
1348 m_detected = GSOCK_LOST_FLAG;
1349
1350 /* LOST event: Abort any further processing */
1351 return (GSOCK_LOST_FLAG & flags);
1352 }
1353
1354 /* Check for readability */
1355 if (wxFD_ISSET(m_fd, &readfds))
1356 {
1357 result |= GSOCK_INPUT_FLAG;
1358
1359 if (m_server && m_stream)
1360 {
1361 /* This is a TCP server socket that detected a connection.
1362 While the INPUT_FLAG is also set, it doesn't matter on
1363 this kind of sockets, as we can only Accept() from them. */
1364 m_detected |= GSOCK_CONNECTION_FLAG;
1365 }
1366 }
1367
1368 /* Check for writability */
1369 if (wxFD_ISSET(m_fd, &writefds))
1370 {
1371 if (m_establishing && !m_server)
1372 {
1373 int error;
1374 SOCKOPTLEN_T len = sizeof(error);
1375 m_establishing = false;
1376 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1377
1378 if (error)
1379 {
1380 m_detected = GSOCK_LOST_FLAG;
1381
1382 /* LOST event: Abort any further processing */
1383 return (GSOCK_LOST_FLAG & flags);
1384 }
1385 else
1386 {
1387 m_detected |= GSOCK_CONNECTION_FLAG;
1388 }
1389 }
1390 else
1391 {
1392 result |= GSOCK_OUTPUT_FLAG;
1393 }
1394 }
1395
1396 return (result | m_detected) & flags;
97e6ee04
DE
1397}
1398
1399/* Flags */
1400
1401/* GSocket_SetNonBlocking:
1402 * Sets the socket to non-blocking mode. All IO calls will return
1403 * immediately.
1404 */
948c96ef 1405void GSocket::SetNonBlocking(bool non_block)
97e6ee04 1406{
09e6e5ec 1407 assert(this);
97e6ee04
DE
1408
1409 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1410
09e6e5ec 1411 m_non_blocking = non_block;
97e6ee04
DE
1412}
1413
1414/* GSocket_SetTimeout:
1415 * Sets the timeout for blocking calls. Time is expressed in
1416 * milliseconds.
1417 */
ba2a81d7 1418void GSocket::SetTimeout(unsigned long millisec)
97e6ee04 1419{
09e6e5ec 1420 assert(this);
97e6ee04 1421
09e6e5ec 1422 m_timeout = millisec;
97e6ee04
DE
1423}
1424
1425/* GSocket_GetError:
d6922577 1426 * Returns the last error occurred for this socket. Note that successful
97e6ee04
DE
1427 * operations do not clear this back to GSOCK_NOERROR, so use it only
1428 * after an error.
1429 */
ba2a81d7 1430GSocketError WXDLLIMPEXP_NET GSocket::GetError()
97e6ee04 1431{
09e6e5ec 1432 assert(this);
97e6ee04 1433
09e6e5ec 1434 return m_error;
97e6ee04
DE
1435}
1436
1437/* Callbacks */
1438
1439/* GSOCK_INPUT:
1440 * There is data to be read in the input buffer. If, after a read
1441 * operation, there is still data available, the callback function will
1442 * be called again.
1443 * GSOCK_OUTPUT:
b082b524 1444 * The socket is available for writing. That is, the next write call
97e6ee04
DE
1445 * won't block. This event is generated only once, when the connection is
1446 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1447 * when the output buffer empties again. This means that the app should
1448 * assume that it can write since the first OUTPUT event, and no more
1449 * OUTPUT events will be generated unless an error occurs.
1450 * GSOCK_CONNECTION:
d6922577 1451 * Connection successfully established, for client sockets, or incoming
97e6ee04
DE
1452 * client connection, for server sockets. Wait for this event (also watch
1453 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1454 * GSOCK_LOST:
1455 * The connection is lost (or a connection request failed); this could
1456 * be due to a failure, or due to the peer closing it gracefully.
1457 */
1458
1459/* GSocket_SetCallback:
1460 * Enables the callbacks specified by 'flags'. Note that 'flags'
1461 * may be a combination of flags OR'ed toghether, so the same
1462 * callback function can be made to accept different events.
1463 * The callback function must have the following prototype:
1464 *
1465 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1466 */
ba2a81d7 1467void GSocket::SetCallback(GSocketEventFlags flags,
97e6ee04
DE
1468 GSocketCallback callback, char *cdata)
1469{
1470 int count;
1471
09e6e5ec 1472 assert(this);
97e6ee04
DE
1473
1474 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1475 {
1476 if ((flags & (1 << count)) != 0)
1477 {
09e6e5ec
DE
1478 m_cbacks[count] = callback;
1479 m_data[count] = cdata;
97e6ee04
DE
1480 }
1481 }
1482}
1483
1484/* GSocket_UnsetCallback:
1485 * Disables all callbacks specified by 'flags', which may be a
1486 * combination of flags OR'ed toghether.
1487 */
ba2a81d7 1488void GSocket::UnsetCallback(GSocketEventFlags flags)
97e6ee04
DE
1489{
1490 int count;
1491
09e6e5ec 1492 assert(this);
97e6ee04
DE
1493
1494 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1495 {
1496 if ((flags & (1 << count)) != 0)
1497 {
09e6e5ec
DE
1498 m_cbacks[count] = NULL;
1499 m_data[count] = NULL;
97e6ee04
DE
1500 }
1501 }
1502}
1503
ba2a81d7 1504GSocketError GSocket::GetSockOpt(int level, int optname,
b082b524
DE
1505 void *optval, int *optlen)
1506{
ddc1a35f 1507 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
b082b524 1508 return GSOCK_NOERROR;
1aa7b427 1509
b082b524
DE
1510 return GSOCK_OPTERR;
1511}
1512
ba2a81d7 1513GSocketError GSocket::SetSockOpt(int level, int optname,
b082b524
DE
1514 const void *optval, int optlen)
1515{
f71bb8ef 1516 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
b082b524 1517 return GSOCK_NOERROR;
1aa7b427 1518
b082b524
DE
1519 return GSOCK_OPTERR;
1520}
1521
ba2a81d7 1522#define CALL_CALLBACK(socket, event) { \
9a7e4a56 1523 socket->Disable(event); \
ba2a81d7
DE
1524 if (socket->m_cbacks[event]) \
1525 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
97e6ee04
DE
1526}
1527
1528
ba2a81d7 1529void GSocket::Enable(GSocketEvent event)
97e6ee04 1530{
2804f77d
VZ
1531 if (m_use_events)
1532 {
1533 m_detected &= ~(1 << event);
1534 GSocketManager::Get()->Install_Callback(this, event);
1535 }
97e6ee04
DE
1536}
1537
ba2a81d7 1538void GSocket::Disable(GSocketEvent event)
97e6ee04 1539{
2804f77d
VZ
1540 if (m_use_events)
1541 {
1542 m_detected |= (1 << event);
1543 GSocketManager::Get()->Uninstall_Callback(this, event);
1544 }
97e6ee04
DE
1545}
1546
1547/* _GSocket_Input_Timeout:
1548 * For blocking sockets, wait until data is available or
1549 * until timeout ellapses.
1550 */
ba2a81d7 1551GSocketError GSocket::Input_Timeout()
97e6ee04
DE
1552{
1553 struct timeval tv;
1554 fd_set readfds;
1555 int ret;
1556
1557 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1558 tv.tv_sec = (m_timeout / 1000);
1559 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1560
09e6e5ec 1561 if (!m_non_blocking)
97e6ee04 1562 {
17a1ebd1
VZ
1563 wxFD_ZERO(&readfds);
1564 wxFD_SET(m_fd, &readfds);
09e6e5ec 1565 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
97e6ee04
DE
1566 if (ret == 0)
1567 {
1568 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
09e6e5ec 1569 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1570 return GSOCK_TIMEDOUT;
1571 }
1aa7b427 1572
97e6ee04
DE
1573 if (ret == -1)
1574 {
1575 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1576 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1577 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1578 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1579 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1580 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1581 return GSOCK_TIMEDOUT;
1582 }
1583 }
1aa7b427 1584
97e6ee04
DE
1585 return GSOCK_NOERROR;
1586}
1587
1588/* _GSocket_Output_Timeout:
1589 * For blocking sockets, wait until data can be sent without
1590 * blocking or until timeout ellapses.
1591 */
ba2a81d7 1592GSocketError GSocket::Output_Timeout()
97e6ee04
DE
1593{
1594 struct timeval tv;
1595 fd_set writefds;
1596 int ret;
1597
1598 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1599 tv.tv_sec = (m_timeout / 1000);
1600 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1601
09e6e5ec 1602 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
97e6ee04 1603
09e6e5ec 1604 if (!m_non_blocking)
97e6ee04 1605 {
17a1ebd1
VZ
1606 wxFD_ZERO(&writefds);
1607 wxFD_SET(m_fd, &writefds);
09e6e5ec 1608 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
97e6ee04
DE
1609 if (ret == 0)
1610 {
1611 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
09e6e5ec 1612 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1613 return GSOCK_TIMEDOUT;
1614 }
1aa7b427 1615
97e6ee04
DE
1616 if (ret == -1)
1617 {
1618 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1619 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1620 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1621 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1622 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1623 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1624 return GSOCK_TIMEDOUT;
1625 }
1aa7b427
DS
1626
1627 if ( ! wxFD_ISSET(m_fd, &writefds) )
1628 {
97e6ee04
DE
1629 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1630 }
1aa7b427
DS
1631 else
1632 {
97e6ee04
DE
1633 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1634 }
1635 }
1636 else
1637 {
1638 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1639 }
1640
1641 return GSOCK_NOERROR;
1642}
1643
ba2a81d7 1644int GSocket::Recv_Stream(char *buffer, int size)
97e6ee04 1645{
bb154f79 1646 int ret;
7e1e6965 1647 do
bb154f79
KH
1648 {
1649 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1650 }
1651 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1652
bb154f79 1653 return ret;
97e6ee04
DE
1654}
1655
ba2a81d7 1656int GSocket::Recv_Dgram(char *buffer, int size)
97e6ee04 1657{
8575ff50 1658 wxSockAddr from;
9e03e02d 1659 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
1660 int ret;
1661 GSocketError err;
1662
1663 fromlen = sizeof(from);
1664
7e1e6965 1665 do
bb154f79 1666 {
8575ff50 1667 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
1aa7b427
DS
1668 }
1669 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
97e6ee04
DE
1670
1671 if (ret == -1)
1672 return -1;
1673
1674 /* Translate a system address into a GSocket address */
09e6e5ec 1675 if (!m_peer)
97e6ee04 1676 {
09e6e5ec
DE
1677 m_peer = GAddress_new();
1678 if (!m_peer)
97e6ee04 1679 {
09e6e5ec 1680 m_error = GSOCK_MEMERR;
97e6ee04
DE
1681 return -1;
1682 }
1683 }
1aa7b427 1684
8575ff50 1685 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
97e6ee04
DE
1686 if (err != GSOCK_NOERROR)
1687 {
09e6e5ec
DE
1688 GAddress_destroy(m_peer);
1689 m_peer = NULL;
1690 m_error = err;
97e6ee04
DE
1691 return -1;
1692 }
1693
1694 return ret;
1695}
1696
ba2a81d7 1697int GSocket::Send_Stream(const char *buffer, int size)
97e6ee04
DE
1698{
1699 int ret;
1700
7e1e6965
WS
1701 MASK_SIGNAL();
1702
1703 do
bb154f79
KH
1704 {
1705 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1706 }
1707 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1708
97e6ee04 1709 UNMASK_SIGNAL();
97e6ee04
DE
1710
1711 return ret;
1712}
1713
ba2a81d7 1714int GSocket::Send_Dgram(const char *buffer, int size)
97e6ee04
DE
1715{
1716 struct sockaddr *addr;
1717 int len, ret;
1718 GSocketError err;
1719
09e6e5ec 1720 if (!m_peer)
97e6ee04 1721 {
09e6e5ec 1722 m_error = GSOCK_INVADDR;
97e6ee04
DE
1723 return -1;
1724 }
1725
09e6e5ec 1726 err = _GAddress_translate_to(m_peer, &addr, &len);
97e6ee04
DE
1727 if (err != GSOCK_NOERROR)
1728 {
09e6e5ec 1729 m_error = err;
97e6ee04
DE
1730 return -1;
1731 }
1732
97e6ee04 1733 MASK_SIGNAL();
7e1e6965
WS
1734
1735 do
bb154f79
KH
1736 {
1737 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1aa7b427
DS
1738 }
1739 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1740
97e6ee04 1741 UNMASK_SIGNAL();
97e6ee04
DE
1742
1743 /* Frees memory allocated from _GAddress_translate_to */
1744 free(addr);
1745
1746 return ret;
1747}
1748
ba2a81d7 1749void GSocket::Detected_Read()
97e6ee04
DE
1750{
1751 char c;
1752
bb154f79
KH
1753 /* Safeguard against straggling call to Detected_Read */
1754 if (m_fd == INVALID_SOCKET)
1755 {
1756 return;
1757 }
1758
97e6ee04
DE
1759 /* If we have already detected a LOST event, then don't try
1760 * to do any further processing.
1761 */
09e6e5ec 1762 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1763 {
948c96ef 1764 m_establishing = false;
97e6ee04 1765
ba2a81d7 1766 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1767 Shutdown();
97e6ee04
DE
1768 return;
1769 }
1770
bb154f79
KH
1771 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1772
1773 if (num > 0)
97e6ee04 1774 {
ba2a81d7 1775 CALL_CALLBACK(this, GSOCK_INPUT);
97e6ee04
DE
1776 }
1777 else
1778 {
09e6e5ec 1779 if (m_server && m_stream)
97e6ee04 1780 {
ba2a81d7 1781 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04 1782 }
e37e082e
VZ
1783 else if (num == 0)
1784 {
01c03554
VZ
1785 if (m_stream)
1786 {
1787 /* graceful shutdown */
1788 CALL_CALLBACK(this, GSOCK_LOST);
1789 Shutdown();
1790 }
1791 else
1792 {
1793 /* Empty datagram received */
1794 CALL_CALLBACK(this, GSOCK_INPUT);
1795 }
e37e082e 1796 }
97e6ee04
DE
1797 else
1798 {
e400d27d 1799 /* Do not throw a lost event in cases where the socket isn't really lost */
7e1e6965 1800 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
bb154f79
KH
1801 {
1802 CALL_CALLBACK(this, GSOCK_INPUT);
1803 }
7e1e6965 1804 else
bb154f79
KH
1805 {
1806 CALL_CALLBACK(this, GSOCK_LOST);
1807 Shutdown();
7e1e6965 1808 }
97e6ee04
DE
1809 }
1810 }
1811}
1812
ba2a81d7 1813void GSocket::Detected_Write()
97e6ee04
DE
1814{
1815 /* If we have already detected a LOST event, then don't try
1816 * to do any further processing.
1817 */
09e6e5ec 1818 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1819 {
948c96ef 1820 m_establishing = false;
97e6ee04 1821
ba2a81d7 1822 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1823 Shutdown();
97e6ee04
DE
1824 return;
1825 }
1826
09e6e5ec 1827 if (m_establishing && !m_server)
97e6ee04
DE
1828 {
1829 int error;
ddc1a35f 1830 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1831
948c96ef 1832 m_establishing = false;
97e6ee04 1833
f71bb8ef 1834 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
97e6ee04
DE
1835
1836 if (error)
1837 {
ba2a81d7 1838 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1839 Shutdown();
97e6ee04
DE
1840 }
1841 else
1842 {
ba2a81d7 1843 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04
DE
1844 /* We have to fire this event by hand because CONNECTION (for clients)
1845 * and OUTPUT are internally the same and we just disabled CONNECTION
1846 * events with the above macro.
1847 */
ba2a81d7 1848 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1849 }
1850 }
1851 else
1852 {
ba2a81d7 1853 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1854 }
1855}
1856
09e6e5ec
DE
1857/* Compatibility functions for GSocket */
1858GSocket *GSocket_new(void)
1859{
ba2a81d7 1860 GSocket *newsocket = new GSocket();
1aa7b427 1861 if (newsocket->IsOk())
09e6e5ec 1862 return newsocket;
1aa7b427 1863
09e6e5ec 1864 delete newsocket;
1aa7b427 1865
09e6e5ec
DE
1866 return NULL;
1867}
1868
97e6ee04
DE
1869/*
1870 * -------------------------------------------------------------------------
1871 * GAddress
1872 * -------------------------------------------------------------------------
1873 */
1874
1875/* CHECK_ADDRESS verifies that the current address family is either
1876 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1877 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1878 * an appropiate error code.
1879 *
1880 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1881 */
1882#define CHECK_ADDRESS(address, family) \
1883{ \
1884 if (address->m_family == GSOCK_NOFAMILY) \
1885 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1886 return address->m_error; \
1887 if (address->m_family != GSOCK_##family) \
1888 { \
1889 address->m_error = GSOCK_INVADDR; \
1890 return GSOCK_INVADDR; \
1891 } \
1892}
1893
1894#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1895{ \
1896 if (address->m_family == GSOCK_NOFAMILY) \
1897 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1898 return retval; \
1899 if (address->m_family != GSOCK_##family) \
1900 { \
1901 address->m_error = GSOCK_INVADDR; \
1902 return retval; \
1903 } \
1904}
1905
1906
1907GAddress *GAddress_new(void)
1908{
1909 GAddress *address;
1910
1911 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1912 return NULL;
1913
1914 address->m_family = GSOCK_NOFAMILY;
1915 address->m_addr = NULL;
1916 address->m_len = 0;
1917
1918 return address;
1919}
1920
1921GAddress *GAddress_copy(GAddress *address)
1922{
1923 GAddress *addr2;
1924
1925 assert(address != NULL);
1926
1927 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1928 return NULL;
1929
1930 memcpy(addr2, address, sizeof(GAddress));
1931
1932 if (address->m_addr && address->m_len > 0)
1933 {
1934 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1935 if (addr2->m_addr == NULL)
1936 {
1937 free(addr2);
1938 return NULL;
1939 }
1940 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1941 }
1942
1943 return addr2;
1944}
1945
1946void GAddress_destroy(GAddress *address)
1947{
1948 assert(address != NULL);
1949
1950 if (address->m_addr)
1951 free(address->m_addr);
1952
1953 free(address);
1954}
1955
1956void GAddress_SetFamily(GAddress *address, GAddressType type)
1957{
1958 assert(address != NULL);
1959
1960 address->m_family = type;
1961}
1962
1963GAddressType GAddress_GetFamily(GAddress *address)
1964{
1965 assert(address != NULL);
1966
1967 return address->m_family;
1968}
1969
1970GSocketError _GAddress_translate_from(GAddress *address,
1971 struct sockaddr *addr, int len)
1972{
1973 address->m_realfamily = addr->sa_family;
1974 switch (addr->sa_family)
1975 {
1976 case AF_INET:
1977 address->m_family = GSOCK_INET;
1978 break;
1979 case AF_UNIX:
1980 address->m_family = GSOCK_UNIX;
1981 break;
8575ff50 1982#if wxUSE_IPV6
97e6ee04
DE
1983 case AF_INET6:
1984 address->m_family = GSOCK_INET6;
1985 break;
8575ff50 1986#endif // wxUSE_IPV6
97e6ee04
DE
1987 default:
1988 {
1989 address->m_error = GSOCK_INVOP;
1990 return GSOCK_INVOP;
1991 }
1992 }
1993
1994 if (address->m_addr)
1995 free(address->m_addr);
1996
1997 address->m_len = len;
1998 address->m_addr = (struct sockaddr *)malloc(len);
1999
2000 if (address->m_addr == NULL)
2001 {
2002 address->m_error = GSOCK_MEMERR;
2003 return GSOCK_MEMERR;
2004 }
1aa7b427 2005
97e6ee04
DE
2006 memcpy(address->m_addr, addr, len);
2007
2008 return GSOCK_NOERROR;
2009}
2010
2011GSocketError _GAddress_translate_to(GAddress *address,
2012 struct sockaddr **addr, int *len)
2013{
2014 if (!address->m_addr)
2015 {
2016 address->m_error = GSOCK_INVADDR;
2017 return GSOCK_INVADDR;
2018 }
2019
2020 *len = address->m_len;
2021 *addr = (struct sockaddr *)malloc(address->m_len);
2022 if (*addr == NULL)
2023 {
2024 address->m_error = GSOCK_MEMERR;
2025 return GSOCK_MEMERR;
2026 }
2027
2028 memcpy(*addr, address->m_addr, address->m_len);
2029 return GSOCK_NOERROR;
2030}
2031
2032/*
2033 * -------------------------------------------------------------------------
2034 * Internet address family
2035 * -------------------------------------------------------------------------
2036 */
2037
2038GSocketError _GAddress_Init_INET(GAddress *address)
2039{
2040 address->m_len = sizeof(struct sockaddr_in);
2041 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2042 if (address->m_addr == NULL)
2043 {
2044 address->m_error = GSOCK_MEMERR;
2045 return GSOCK_MEMERR;
2046 }
2047
2048 address->m_family = GSOCK_INET;
2049 address->m_realfamily = PF_INET;
2050 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
2051 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
2052
2053 return GSOCK_NOERROR;
2054}
2055
2056GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
2057{
2058 struct hostent *he;
2059 struct in_addr *addr;
2060
2061 assert(address != NULL);
2062
2063 CHECK_ADDRESS(address, INET);
2064
2065 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2066
2067 /* If it is a numeric host name, convert it now */
2068#if defined(HAVE_INET_ATON)
2069 if (inet_aton(hostname, addr) == 0)
2070 {
2071#elif defined(HAVE_INET_ADDR)
8c0f8906 2072 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
97e6ee04
DE
2073 {
2074#else
2075 /* Use gethostbyname by default */
9d715960 2076#ifndef __WXMAC__
ba2a81d7 2077 int val = 1; /* VA doesn't like constants in conditional expressions */
97e6ee04 2078 if (val)
9d715960 2079#endif
97e6ee04
DE
2080 {
2081#endif
2082 struct in_addr *array_addr;
2083
2084 /* It is a real name, we solve it */
127189eb
SN
2085 struct hostent h;
2086#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2087 struct hostent_data buffer;
2088#else
2089 char buffer[1024];
2090#endif
2091 int err;
2092 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
2093 if (he == NULL)
97e6ee04
DE
2094 {
2095 /* Reset to invalid address */
2096 addr->s_addr = INADDR_NONE;
2097 address->m_error = GSOCK_NOHOST;
2098 return GSOCK_NOHOST;
2099 }
1aa7b427 2100
97e6ee04
DE
2101 array_addr = (struct in_addr *) *(he->h_addr_list);
2102 addr->s_addr = array_addr[0].s_addr;
2103 }
1aa7b427 2104
97e6ee04
DE
2105 return GSOCK_NOERROR;
2106}
2107
60edcf45
VZ
2108
2109GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
2110{
2111 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2112}
2113
97e6ee04
DE
2114GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2115{
2116 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2117}
2118
2119GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2120 unsigned long hostaddr)
2121{
2122 struct in_addr *addr;
2123
2124 assert(address != NULL);
2125
2126 CHECK_ADDRESS(address, INET);
2127
2128 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
9d715960 2129 addr->s_addr = htonl(hostaddr);
97e6ee04
DE
2130
2131 return GSOCK_NOERROR;
2132}
2133
2134GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2135 const char *protocol)
2136{
2137 struct servent *se;
2138 struct sockaddr_in *addr;
2139
2140 assert(address != NULL);
2141 CHECK_ADDRESS(address, INET);
2142
2143 if (!port)
2144 {
2145 address->m_error = GSOCK_INVPORT;
2146 return GSOCK_INVPORT;
2147 }
b082b524 2148
127189eb
SN
2149#if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2150 struct servent_data buffer;
f6bc1c74 2151#else
127189eb 2152 char buffer[1024];
f6bc1c74 2153#endif
127189eb
SN
2154 struct servent serv;
2155 se = wxGetservbyname_r(port, protocol, &serv,
2156 (void*)&buffer, sizeof(buffer));
97e6ee04
DE
2157 if (!se)
2158 {
2159 /* the cast to int suppresses compiler warnings about subscript having the
2160 type char */
2161 if (isdigit((int)port[0]))
2162 {
2163 int port_int;
2164
2165 port_int = atoi(port);
2166 addr = (struct sockaddr_in *)address->m_addr;
2167 addr->sin_port = htons(port_int);
2168 return GSOCK_NOERROR;
2169 }
2170
2171 address->m_error = GSOCK_INVPORT;
2172 return GSOCK_INVPORT;
2173 }
2174
2175 addr = (struct sockaddr_in *)address->m_addr;
2176 addr->sin_port = se->s_port;
2177
2178 return GSOCK_NOERROR;
2179}
2180
2181GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2182{
2183 struct sockaddr_in *addr;
2184
2185 assert(address != NULL);
2186 CHECK_ADDRESS(address, INET);
b082b524 2187
97e6ee04
DE
2188 addr = (struct sockaddr_in *)address->m_addr;
2189 addr->sin_port = htons(port);
2190
2191 return GSOCK_NOERROR;
2192}
2193
2194GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2195{
2196 struct hostent *he;
2197 char *addr_buf;
2198 struct sockaddr_in *addr;
2199
b082b524 2200 assert(address != NULL);
97e6ee04
DE
2201 CHECK_ADDRESS(address, INET);
2202
2203 addr = (struct sockaddr_in *)address->m_addr;
2204 addr_buf = (char *)&(addr->sin_addr);
2205
127189eb
SN
2206 struct hostent temphost;
2207#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2208 struct hostent_data buffer;
2209#else
2210 char buffer[1024];
2211#endif
2212 int err;
2213 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2214 (void*)&buffer, sizeof(buffer), &err);
97e6ee04
DE
2215 if (he == NULL)
2216 {
2217 address->m_error = GSOCK_NOHOST;
2218 return GSOCK_NOHOST;
2219 }
2220
2221 strncpy(hostname, he->h_name, sbuf);
2222
2223 return GSOCK_NOERROR;
2224}
2225
2226unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2227{
2228 struct sockaddr_in *addr;
2229
b082b524
DE
2230 assert(address != NULL);
2231 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2232
2233 addr = (struct sockaddr_in *)address->m_addr;
2234
9d715960 2235 return ntohl(addr->sin_addr.s_addr);
97e6ee04
DE
2236}
2237
2238unsigned short GAddress_INET_GetPort(GAddress *address)
2239{
2240 struct sockaddr_in *addr;
2241
b082b524
DE
2242 assert(address != NULL);
2243 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2244
2245 addr = (struct sockaddr_in *)address->m_addr;
2246 return ntohs(addr->sin_port);
2247}
2248
8575ff50
VZ
2249#if wxUSE_IPV6
2250/*
2251 * -------------------------------------------------------------------------
2252 * Internet IPv6 address family
2253 * -------------------------------------------------------------------------
2254 */
2255
2256GSocketError _GAddress_Init_INET6(GAddress *address)
2257{
2258 struct in6_addr any_address = IN6ADDR_ANY_INIT;
2259 address->m_len = sizeof(struct sockaddr_in6);
2260 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2261 if (address->m_addr == NULL)
2262 {
2263 address->m_error = GSOCK_MEMERR;
2264 return GSOCK_MEMERR;
2265 }
2266 memset(address->m_addr,0,address->m_len);
2267
2268 address->m_family = GSOCK_INET6;
2269 address->m_realfamily = AF_INET6;
2270 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
2271 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
2272
2273 return GSOCK_NOERROR;
2274}
2275
2276GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
2277{
2278 assert(address != NULL);
2279 CHECK_ADDRESS(address, INET6);
2280
2281 addrinfo hints;
2282 memset( & hints, 0, sizeof( hints ) );
2283 hints.ai_family = AF_INET6;
2284 addrinfo * info = 0;
2285 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
2286 {
2287 address->m_error = GSOCK_NOHOST;
2288 return GSOCK_NOHOST;
2289 }
2290
2291 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
2292 freeaddrinfo( info );
2293 return GSOCK_NOERROR;
2294}
2295
2296GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
2297{
2298 assert(address != NULL);
2299
2300 CHECK_ADDRESS(address, INET6);
2301
2302 struct in6_addr addr;
2303 memset( & addr, 0, sizeof( addr ) );
2304 return GAddress_INET6_SetHostAddress(address, addr);
2305}
2306GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
2307 struct in6_addr hostaddr)
2308{
2309 assert(address != NULL);
2310
2311 CHECK_ADDRESS(address, INET6);
2312
2313 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
2314
2315 return GSOCK_NOERROR;
2316}
2317
2318GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
2319 const char *protocol)
2320{
2321 struct servent *se;
2322 struct sockaddr_in6 *addr;
2323
2324 assert(address != NULL);
2325 CHECK_ADDRESS(address, INET6);
2326
2327 if (!port)
2328 {
2329 address->m_error = GSOCK_INVPORT;
2330 return GSOCK_INVPORT;
2331 }
2332
2333 se = getservbyname(port, protocol);
2334 if (!se)
2335 {
2336 if (isdigit(port[0]))
2337 {
2338 int port_int;
2339
2340 port_int = atoi(port);
2341 addr = (struct sockaddr_in6 *)address->m_addr;
2342 addr->sin6_port = htons((u_short) port_int);
2343 return GSOCK_NOERROR;
2344 }
2345
2346 address->m_error = GSOCK_INVPORT;
2347 return GSOCK_INVPORT;
2348 }
2349
2350 addr = (struct sockaddr_in6 *)address->m_addr;
2351 addr->sin6_port = se->s_port;
2352
2353 return GSOCK_NOERROR;
2354}
2355
2356GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
2357{
2358 struct sockaddr_in6 *addr;
2359
2360 assert(address != NULL);
2361 CHECK_ADDRESS(address, INET6);
2362
2363 addr = (struct sockaddr_in6 *)address->m_addr;
2364 addr->sin6_port = htons(port);
2365
2366 return GSOCK_NOERROR;
2367}
2368
2369GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2370{
2371 struct hostent *he;
2372 char *addr_buf;
2373 struct sockaddr_in6 *addr;
2374
2375 assert(address != NULL);
2376 CHECK_ADDRESS(address, INET6);
2377
2378 addr = (struct sockaddr_in6 *)address->m_addr;
2379 addr_buf = (char *)&(addr->sin6_addr);
2380
2381 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
2382 if (he == NULL)
2383 {
2384 address->m_error = GSOCK_NOHOST;
2385 return GSOCK_NOHOST;
2386 }
2387
2388 strncpy(hostname, he->h_name, sbuf);
2389
2390 return GSOCK_NOERROR;
2391}
2392
2393GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
2394{
2395 assert(address != NULL);
2396 assert(hostaddr != NULL);
2397 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2398 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2399 return GSOCK_NOERROR;
2400}
2401
2402unsigned short GAddress_INET6_GetPort(GAddress *address)
2403{
2404 assert(address != NULL);
2405 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2406
2407 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2408}
2409
2410#endif // wxUSE_IPV6
2411
97e6ee04
DE
2412/*
2413 * -------------------------------------------------------------------------
2414 * Unix address family
2415 * -------------------------------------------------------------------------
2416 */
2417
2418#ifndef __VISAGECPP__
2419GSocketError _GAddress_Init_UNIX(GAddress *address)
2420{
2421 address->m_len = sizeof(struct sockaddr_un);
2422 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2423 if (address->m_addr == NULL)
2424 {
2425 address->m_error = GSOCK_MEMERR;
2426 return GSOCK_MEMERR;
2427 }
2428
2429 address->m_family = GSOCK_UNIX;
2430 address->m_realfamily = PF_UNIX;
2431 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2432 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2433
2434 return GSOCK_NOERROR;
2435}
2436
2437#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2438
2439GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2440{
2441 struct sockaddr_un *addr;
2442
b082b524 2443 assert(address != NULL);
97e6ee04 2444
b082b524 2445 CHECK_ADDRESS(address, UNIX);
97e6ee04
DE
2446
2447 addr = ((struct sockaddr_un *)address->m_addr);
2448 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2449 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2450
2451 return GSOCK_NOERROR;
2452}
2453
2454GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2455{
2456 struct sockaddr_un *addr;
2457
2458 assert(address != NULL);
2459 CHECK_ADDRESS(address, UNIX);
2460
2461 addr = (struct sockaddr_un *)address->m_addr;
2462
2463 strncpy(path, addr->sun_path, sbuf);
2464
2465 return GSOCK_NOERROR;
2466}
2467#endif /* !defined(__VISAGECPP__) */
2468#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */