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