]> git.saurik.com Git - wxWidgets.git/blame - src/unix/gsocket.cpp
Use renderer to draw checkmark
[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
ba2a81d7
DE
453/* Table of GUI-related functions. We must call them indirectly because
454 * of wxBase and GUI separation: */
444cb1fd 455
3e1400ac 456static GSocketGUIFunctionsTable *gs_gui_functions;
b082b524 457
985acf87
VZ
458class GSocketGUIFunctionsTableNull: public GSocketGUIFunctionsTable
459{
460public:
461 virtual bool OnInit();
462 virtual void OnExit();
463 virtual bool CanUseEventLoop();
464 virtual bool Init_Socket(GSocket *socket);
465 virtual void Destroy_Socket(GSocket *socket);
466 virtual void Install_Callback(GSocket *socket, GSocketEvent event);
467 virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event);
468 virtual void Enable_Events(GSocket *socket);
469 virtual void Disable_Events(GSocket *socket);
470};
471
472bool GSocketGUIFunctionsTableNull::OnInit()
473{ return true; }
474void GSocketGUIFunctionsTableNull::OnExit()
475{}
476bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
477{ return false; }
478bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket *WXUNUSED(socket))
479{ return true; }
480void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket *WXUNUSED(socket))
481{}
482void GSocketGUIFunctionsTableNull::Install_Callback(GSocket *WXUNUSED(socket), GSocketEvent WXUNUSED(event))
483{}
484void GSocketGUIFunctionsTableNull::Uninstall_Callback(GSocket *WXUNUSED(socket), GSocketEvent WXUNUSED(event))
485{}
486void GSocketGUIFunctionsTableNull::Enable_Events(GSocket *WXUNUSED(socket))
487{}
488void GSocketGUIFunctionsTableNull::Disable_Events(GSocket *WXUNUSED(socket))
489{}
ba2a81d7 490/* Global initialisers */
444cb1fd 491
3e1400ac 492void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable *guifunc)
444cb1fd 493{
ba2a81d7 494 gs_gui_functions = guifunc;
444cb1fd
DE
495}
496
97e6ee04
DE
497int GSocket_Init(void)
498{
ba2a81d7
DE
499 if (!gs_gui_functions)
500 {
985acf87 501 static GSocketGUIFunctionsTableNull table;
ba2a81d7
DE
502 gs_gui_functions = &table;
503 }
504 if ( !gs_gui_functions->OnInit() )
505 return 0;
506 return 1;
97e6ee04
DE
507}
508
509void GSocket_Cleanup(void)
510{
ba2a81d7
DE
511 if (gs_gui_functions)
512 {
513 gs_gui_functions->OnExit();
514 }
97e6ee04
DE
515}
516
ba2a81d7
DE
517/* Constructors / Destructors for GSocket */
518
519GSocket::GSocket()
97e6ee04 520{
09e6e5ec 521 int i;
97e6ee04 522
09e6e5ec 523 m_fd = INVALID_SOCKET;
5e1eac14
VZ
524 m_handler = NULL;
525
97e6ee04
DE
526 for (i=0;i<GSOCK_MAX_EVENT;i++)
527 {
09e6e5ec 528 m_cbacks[i] = NULL;
97e6ee04 529 }
09e6e5ec
DE
530 m_detected = 0;
531 m_local = NULL;
532 m_peer = NULL;
533 m_error = GSOCK_NOERROR;
948c96ef
DE
534 m_server = false;
535 m_stream = true;
09e6e5ec 536 m_gui_dependent = NULL;
948c96ef 537 m_non_blocking = false;
1eef64d8 538 m_reusable = false;
60edcf45
VZ
539 m_broadcast = false;
540 m_dobind = true;
09e6e5ec 541 m_timeout = 10*60*1000;
97e6ee04 542 /* 10 minutes * 60 sec * 1000 millisec */
948c96ef 543 m_establishing = false;
97e6ee04 544
ba2a81d7
DE
545 assert(gs_gui_functions);
546 /* Per-socket GUI-specific initialization */
547 m_ok = gs_gui_functions->Init_Socket(this);
97e6ee04
DE
548}
549
ba2a81d7 550void GSocket::Close()
97e6ee04 551{
985acf87 552 gs_gui_functions->Disable_Events(this);
dd6c8be6
DE
553
554 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
555 will close the socket during Disable_Events. However, it will only do this
556 if it is being used. That is, it won't do it in a console program. To
557 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
558 if it has closed the socket which indicates to us (at runtime, instead of
559 at compile time as this had been before) that the socket has already
560 been closed.
561 */
562 if(m_fd != INVALID_SOCKET)
563 close(m_fd);
09e6e5ec 564 m_fd = INVALID_SOCKET;
97e6ee04
DE
565}
566
ba2a81d7 567GSocket::~GSocket()
97e6ee04 568{
ba2a81d7
DE
569 assert(this);
570
571 /* Check that the socket is really shutdowned */
572 if (m_fd != INVALID_SOCKET)
573 Shutdown();
574
575 /* Per-socket GUI-specific cleanup */
985acf87 576 gs_gui_functions->Destroy_Socket(this);
ba2a81d7 577
5e1eac14
VZ
578 delete m_handler;
579
97e6ee04 580 /* Destroy private addresses */
09e6e5ec
DE
581 if (m_local)
582 GAddress_destroy(m_local);
97e6ee04 583
09e6e5ec
DE
584 if (m_peer)
585 GAddress_destroy(m_peer);
97e6ee04
DE
586}
587
588/* GSocket_Shutdown:
589 * Disallow further read/write operations on this socket, close
590 * the fd and disable all callbacks.
591 */
ba2a81d7 592void GSocket::Shutdown()
97e6ee04
DE
593{
594 int evt;
595
09e6e5ec 596 assert(this);
97e6ee04 597
c3b501e1 598 /* Don't allow events to fire after socket has been closed */
985acf87 599 gs_gui_functions->Disable_Events(this);
c3b501e1 600
97e6ee04 601 /* If socket has been created, shutdown it */
09e6e5ec 602 if (m_fd != INVALID_SOCKET)
97e6ee04 603 {
cd632a86 604 shutdown(m_fd, 1);
09e6e5ec 605 Close();
97e6ee04
DE
606 }
607
608 /* Disable GUI callbacks */
609 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
09e6e5ec 610 m_cbacks[evt] = NULL;
97e6ee04 611
09e6e5ec 612 m_detected = GSOCK_LOST_FLAG;
97e6ee04
DE
613}
614
615/* Address handling */
616
617/* GSocket_SetLocal:
618 * GSocket_GetLocal:
619 * GSocket_SetPeer:
620 * GSocket_GetPeer:
621 * Set or get the local or peer address for this socket. The 'set'
622 * functions return GSOCK_NOERROR on success, an error code otherwise.
623 * The 'get' functions return a pointer to a GAddress object on success,
624 * or NULL otherwise, in which case they set the error code of the
625 * corresponding GSocket.
626 *
627 * Error codes:
628 * GSOCK_INVSOCK - the socket is not valid.
629 * GSOCK_INVADDR - the address is not valid.
630 */
ba2a81d7 631GSocketError GSocket::SetLocal(GAddress *address)
97e6ee04 632{
09e6e5ec 633 assert(this);
97e6ee04
DE
634
635 /* the socket must be initialized, or it must be a server */
09e6e5ec 636 if ((m_fd != INVALID_SOCKET && !m_server))
97e6ee04 637 {
09e6e5ec 638 m_error = GSOCK_INVSOCK;
97e6ee04
DE
639 return GSOCK_INVSOCK;
640 }
641
642 /* check address */
643 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
644 {
09e6e5ec 645 m_error = GSOCK_INVADDR;
97e6ee04
DE
646 return GSOCK_INVADDR;
647 }
648
09e6e5ec
DE
649 if (m_local)
650 GAddress_destroy(m_local);
97e6ee04 651
09e6e5ec 652 m_local = GAddress_copy(address);
97e6ee04
DE
653
654 return GSOCK_NOERROR;
655}
656
ba2a81d7 657GSocketError GSocket::SetPeer(GAddress *address)
97e6ee04 658{
09e6e5ec 659 assert(this);
97e6ee04
DE
660
661 /* check address */
662 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
663 {
09e6e5ec 664 m_error = GSOCK_INVADDR;
97e6ee04
DE
665 return GSOCK_INVADDR;
666 }
667
09e6e5ec
DE
668 if (m_peer)
669 GAddress_destroy(m_peer);
97e6ee04 670
09e6e5ec 671 m_peer = GAddress_copy(address);
97e6ee04
DE
672
673 return GSOCK_NOERROR;
674}
675
ba2a81d7 676GAddress *GSocket::GetLocal()
97e6ee04
DE
677{
678 GAddress *address;
679 struct sockaddr addr;
9e03e02d 680 WX_SOCKLEN_T size = sizeof(addr);
97e6ee04
DE
681 GSocketError err;
682
09e6e5ec 683 assert(this);
97e6ee04
DE
684
685 /* try to get it from the m_local var first */
09e6e5ec
DE
686 if (m_local)
687 return GAddress_copy(m_local);
97e6ee04
DE
688
689 /* else, if the socket is initialized, try getsockname */
09e6e5ec 690 if (m_fd == INVALID_SOCKET)
97e6ee04 691 {
09e6e5ec 692 m_error = GSOCK_INVSOCK;
97e6ee04
DE
693 return NULL;
694 }
695
9e03e02d 696 if (getsockname(m_fd, &addr, (WX_SOCKLEN_T *) &size) < 0)
97e6ee04 697 {
09e6e5ec 698 m_error = GSOCK_IOERR;
97e6ee04
DE
699 return NULL;
700 }
701
702 /* got a valid address from getsockname, create a GAddress object */
703 address = GAddress_new();
704 if (address == NULL)
705 {
09e6e5ec 706 m_error = GSOCK_MEMERR;
97e6ee04
DE
707 return NULL;
708 }
709
710 err = _GAddress_translate_from(address, &addr, size);
711 if (err != GSOCK_NOERROR)
712 {
713 GAddress_destroy(address);
09e6e5ec 714 m_error = err;
97e6ee04
DE
715 return NULL;
716 }
717
718 return address;
719}
720
ba2a81d7 721GAddress *GSocket::GetPeer()
97e6ee04 722{
09e6e5ec 723 assert(this);
97e6ee04
DE
724
725 /* try to get it from the m_peer var */
09e6e5ec
DE
726 if (m_peer)
727 return GAddress_copy(m_peer);
97e6ee04
DE
728
729 return NULL;
730}
731
732/* Server specific parts */
733
734/* GSocket_SetServer:
735 * Sets up this socket as a server. The local address must have been
736 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
737 * Returns GSOCK_NOERROR on success, one of the following otherwise:
b082b524 738 *
97e6ee04
DE
739 * Error codes:
740 * GSOCK_INVSOCK - the socket is in use.
741 * GSOCK_INVADDR - the local address has not been set.
b082b524 742 * GSOCK_IOERR - low-level error.
97e6ee04 743 */
ba2a81d7 744GSocketError GSocket::SetServer()
97e6ee04
DE
745{
746 int arg = 1;
747
09e6e5ec 748 assert(this);
97e6ee04
DE
749
750 /* must not be in use */
09e6e5ec 751 if (m_fd != INVALID_SOCKET)
97e6ee04 752 {
09e6e5ec 753 m_error = GSOCK_INVSOCK;
97e6ee04
DE
754 return GSOCK_INVSOCK;
755 }
756
757 /* the local addr must have been set */
09e6e5ec 758 if (!m_local)
97e6ee04 759 {
09e6e5ec 760 m_error = GSOCK_INVADDR;
97e6ee04
DE
761 return GSOCK_INVADDR;
762 }
763
764 /* Initialize all fields */
948c96ef
DE
765 m_stream = true;
766 m_server = true;
97e6ee04
DE
767
768 /* Create the socket */
09e6e5ec 769 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
97e6ee04 770
09e6e5ec 771 if (m_fd == INVALID_SOCKET)
97e6ee04 772 {
09e6e5ec 773 m_error = GSOCK_IOERR;
97e6ee04
DE
774 return GSOCK_IOERR;
775 }
bb154f79
KH
776
777 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
778#ifdef SO_NOSIGPIPE
01ba4b67 779 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
780#endif
781
09e6e5ec 782 ioctl(m_fd, FIONBIO, &arg);
985acf87 783 gs_gui_functions->Enable_Events(this);
97e6ee04
DE
784
785 /* allow a socket to re-bind if the socket is in the TIME_WAIT
786 state after being previously closed.
787 */
ba2a81d7 788 if (m_reusable)
c232b3cd 789 {
01ba4b67 790 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 791#ifdef SO_REUSEPORT
01ba4b67 792 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
793#endif
794 }
97e6ee04
DE
795
796 /* Bind to the local address,
797 * retrieve the actual address bound,
798 * and listen up to 5 connections.
799 */
09e6e5ec
DE
800 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
801 (getsockname(m_fd,
802 m_local->m_addr,
9e03e02d 803 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
09e6e5ec 804 (listen(m_fd, 5) != 0))
97e6ee04 805 {
09e6e5ec
DE
806 Close();
807 m_error = GSOCK_IOERR;
97e6ee04
DE
808 return GSOCK_IOERR;
809 }
810
811 return GSOCK_NOERROR;
812}
813
814/* GSocket_WaitConnection:
815 * Waits for an incoming client connection. Returns a pointer to
816 * a GSocket object, or NULL if there was an error, in which case
817 * the last error field will be updated for the calling GSocket.
818 *
819 * Error codes (set in the calling GSocket)
820 * GSOCK_INVSOCK - the socket is not valid or not a server.
821 * GSOCK_TIMEDOUT - timeout, no incoming connections.
822 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
823 * GSOCK_MEMERR - couldn't allocate memory.
b082b524 824 * GSOCK_IOERR - low-level error.
97e6ee04 825 */
ba2a81d7 826GSocket *GSocket::WaitConnection()
97e6ee04
DE
827{
828 struct sockaddr from;
9e03e02d 829 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
830 GSocket *connection;
831 GSocketError err;
832 int arg = 1;
833
09e6e5ec 834 assert(this);
97e6ee04 835
97e6ee04 836 /* If the socket has already been created, we exit immediately */
09e6e5ec 837 if (m_fd == INVALID_SOCKET || !m_server)
97e6ee04 838 {
09e6e5ec 839 m_error = GSOCK_INVSOCK;
97e6ee04
DE
840 return NULL;
841 }
842
843 /* Create a GSocket object for the new connection */
444cb1fd 844 connection = GSocket_new();
97e6ee04 845
444cb1fd 846 if (!connection)
97e6ee04 847 {
09e6e5ec 848 m_error = GSOCK_MEMERR;
97e6ee04
DE
849 return NULL;
850 }
851
852 /* Wait for a connection (with timeout) */
09e6e5ec 853 if (Input_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 854 {
85431efa 855 delete connection;
09e6e5ec 856 /* m_error set by _GSocket_Input_Timeout */
97e6ee04
DE
857 return NULL;
858 }
859
9e03e02d 860 connection->m_fd = accept(m_fd, &from, (WX_SOCKLEN_T *) &fromlen);
97e6ee04 861
bb154f79
KH
862 /* Reenable CONNECTION events */
863 Enable(GSOCK_CONNECTION);
bb154f79 864
97e6ee04
DE
865 if (connection->m_fd == INVALID_SOCKET)
866 {
867 if (errno == EWOULDBLOCK)
09e6e5ec 868 m_error = GSOCK_WOULDBLOCK;
97e6ee04 869 else
09e6e5ec 870 m_error = GSOCK_IOERR;
97e6ee04 871
85431efa 872 delete connection;
97e6ee04
DE
873 return NULL;
874 }
875
876 /* Initialize all fields */
948c96ef
DE
877 connection->m_server = false;
878 connection->m_stream = true;
97e6ee04
DE
879
880 /* Setup the peer address field */
881 connection->m_peer = GAddress_new();
882 if (!connection->m_peer)
883 {
85431efa 884 delete connection;
09e6e5ec 885 m_error = GSOCK_MEMERR;
97e6ee04
DE
886 return NULL;
887 }
1aa7b427 888
97e6ee04
DE
889 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
890 if (err != GSOCK_NOERROR)
891 {
85431efa 892 delete connection;
09e6e5ec 893 m_error = err;
97e6ee04
DE
894 return NULL;
895 }
1aa7b427 896
97e6ee04
DE
897#if defined(__EMX__) || defined(__VISAGECPP__)
898 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
899#else
900 ioctl(connection->m_fd, FIONBIO, &arg);
901#endif
985acf87 902 gs_gui_functions->Enable_Events(connection);
97e6ee04
DE
903
904 return connection;
905}
906
948c96ef 907bool GSocket::SetReusable()
b082b524
DE
908{
909 /* socket must not be null, and must not be in use/already bound */
1aa7b427
DS
910 if (this && m_fd == INVALID_SOCKET)
911 {
948c96ef 912 m_reusable = true;
1aa7b427 913
948c96ef 914 return true;
b082b524 915 }
1aa7b427 916
948c96ef 917 return false;
b082b524
DE
918}
919
60edcf45
VZ
920bool GSocket::SetBroadcast()
921{
922 /* socket must not be in use/already bound */
923 if (m_fd == INVALID_SOCKET) {
924 m_broadcast = true;
925 return true;
926 }
927 return false;
928}
929
930bool GSocket::DontDoBind()
931{
932 /* socket must not be in use/already bound */
933 if (m_fd == INVALID_SOCKET) {
934 m_dobind = false;
935 return true;
936 }
937 return false;
938}
939
97e6ee04
DE
940/* Client specific parts */
941
942/* GSocket_Connect:
943 * For stream (connection oriented) sockets, GSocket_Connect() tries
944 * to establish a client connection to a server using the peer address
945 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
d6922577 946 * connection has been successfully established, or one of the error
97e6ee04
DE
947 * codes listed below. Note that for nonblocking sockets, a return
948 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
949 * request can be completed later; you should use GSocket_Select()
950 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
951 * corresponding asynchronous events.
952 *
953 * For datagram (non connection oriented) sockets, GSocket_Connect()
954 * just sets the peer address established with GSocket_SetPeer() as
955 * default destination.
956 *
957 * Error codes:
958 * GSOCK_INVSOCK - the socket is in use or not valid.
959 * GSOCK_INVADDR - the peer address has not been established.
960 * GSOCK_TIMEDOUT - timeout, the connection failed.
961 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
962 * GSOCK_MEMERR - couldn't allocate memory.
b082b524 963 * GSOCK_IOERR - low-level error.
97e6ee04 964 */
ba2a81d7 965GSocketError GSocket::Connect(GSocketStream stream)
97e6ee04
DE
966{
967 int err, ret;
968 int arg = 1;
969
09e6e5ec 970 assert(this);
97e6ee04
DE
971
972 /* Enable CONNECTION events (needed for nonblocking connections) */
09e6e5ec 973 Enable(GSOCK_CONNECTION);
97e6ee04 974
09e6e5ec 975 if (m_fd != INVALID_SOCKET)
97e6ee04 976 {
09e6e5ec 977 m_error = GSOCK_INVSOCK;
97e6ee04
DE
978 return GSOCK_INVSOCK;
979 }
980
09e6e5ec 981 if (!m_peer)
97e6ee04 982 {
09e6e5ec 983 m_error = GSOCK_INVADDR;
97e6ee04
DE
984 return GSOCK_INVADDR;
985 }
986
987 /* Streamed or dgram socket? */
09e6e5ec 988 m_stream = (stream == GSOCK_STREAMED);
948c96ef
DE
989 m_server = false;
990 m_establishing = false;
97e6ee04
DE
991
992 /* Create the socket */
09e6e5ec
DE
993 m_fd = socket(m_peer->m_realfamily,
994 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
97e6ee04 995
09e6e5ec 996 if (m_fd == INVALID_SOCKET)
97e6ee04 997 {
09e6e5ec 998 m_error = GSOCK_IOERR;
97e6ee04
DE
999 return GSOCK_IOERR;
1000 }
bb154f79
KH
1001
1002 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
1003#ifdef SO_NOSIGPIPE
01ba4b67 1004 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
1005#endif
1006
97e6ee04 1007#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 1008 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 1009#else
09e6e5ec 1010 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 1011#endif
97e6ee04 1012
c232b3cd
KH
1013 // If the reuse flag is set, use the applicable socket reuse flags(s)
1014 if (m_reusable)
1015 {
01ba4b67 1016 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 1017#ifdef SO_REUSEPORT
01ba4b67 1018 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
1019#endif
1020 }
1021
1022 // If a local address has been set, then we need to bind to it before calling connect
1023 if (m_local && m_local->m_addr)
1024 {
1025 bind(m_fd, m_local->m_addr, m_local->m_len);
1026 }
1027
97e6ee04 1028 /* Connect it to the peer address, with a timeout (see below) */
09e6e5ec 1029 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
97e6ee04 1030
0d34c30e
KH
1031 /* We only call Enable_Events if we know we aren't shutting down the socket.
1032 * NB: Enable_Events needs to be called whether the socket is blocking or
1033 * non-blocking, it just shouldn't be called prior to knowing there is a
1034 * connection _if_ blocking sockets are being used.
1035 * If connect above returns 0, we are already connected and need to make the
17a1ebd1 1036 * call to Enable_Events now.
a3687636 1037 */
17a1ebd1 1038
985acf87
VZ
1039 if (m_non_blocking || ret == 0)
1040 gs_gui_functions->Enable_Events(this);
bb154f79 1041
97e6ee04
DE
1042 if (ret == -1)
1043 {
1044 err = errno;
1045
1046 /* If connect failed with EINPROGRESS and the GSocket object
1047 * is in blocking mode, we select() for the specified timeout
1048 * checking for writability to see if the connection request
1049 * completes.
1050 */
09e6e5ec 1051 if ((err == EINPROGRESS) && (!m_non_blocking))
97e6ee04 1052 {
09e6e5ec 1053 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 1054 {
09e6e5ec
DE
1055 Close();
1056 /* m_error is set in _GSocket_Output_Timeout */
97e6ee04
DE
1057 return GSOCK_TIMEDOUT;
1058 }
1059 else
1060 {
1061 int error;
ddc1a35f 1062 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1063
f71bb8ef 1064 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
985acf87
VZ
1065
1066 gs_gui_functions->Enable_Events(this);
bb154f79 1067
97e6ee04
DE
1068 if (!error)
1069 return GSOCK_NOERROR;
1070 }
1071 }
1072
1073 /* If connect failed with EINPROGRESS and the GSocket object
1074 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1075 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1076 * this way if the connection completes, a GSOCK_CONNECTION
1077 * event will be generated, if enabled.
1078 */
09e6e5ec 1079 if ((err == EINPROGRESS) && (m_non_blocking))
97e6ee04 1080 {
948c96ef 1081 m_establishing = true;
09e6e5ec 1082 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
1083 return GSOCK_WOULDBLOCK;
1084 }
1085
1086 /* If connect failed with an error other than EINPROGRESS,
1087 * then the call to GSocket_Connect has failed.
1088 */
09e6e5ec
DE
1089 Close();
1090 m_error = GSOCK_IOERR;
1aa7b427 1091
97e6ee04
DE
1092 return GSOCK_IOERR;
1093 }
1094
1095 return GSOCK_NOERROR;
1096}
1097
1098/* Datagram sockets */
1099
1100/* GSocket_SetNonOriented:
1101 * Sets up this socket as a non-connection oriented (datagram) socket.
1102 * Before using this function, the local address must have been set
1103 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1104 * on success, or one of the following otherwise.
1105 *
1106 * Error codes:
1107 * GSOCK_INVSOCK - the socket is in use.
1108 * GSOCK_INVADDR - the local address has not been set.
1109 * GSOCK_IOERR - low-level error.
1110 */
ba2a81d7 1111GSocketError GSocket::SetNonOriented()
97e6ee04
DE
1112{
1113 int arg = 1;
1114
09e6e5ec 1115 assert(this);
97e6ee04 1116
09e6e5ec 1117 if (m_fd != INVALID_SOCKET)
97e6ee04 1118 {
09e6e5ec 1119 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1120 return GSOCK_INVSOCK;
1121 }
1122
09e6e5ec 1123 if (!m_local)
97e6ee04 1124 {
09e6e5ec 1125 m_error = GSOCK_INVADDR;
97e6ee04
DE
1126 return GSOCK_INVADDR;
1127 }
1128
1129 /* Initialize all fields */
948c96ef
DE
1130 m_stream = false;
1131 m_server = false;
97e6ee04
DE
1132
1133 /* Create the socket */
09e6e5ec 1134 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
97e6ee04 1135
09e6e5ec 1136 if (m_fd == INVALID_SOCKET)
97e6ee04 1137 {
09e6e5ec 1138 m_error = GSOCK_IOERR;
97e6ee04
DE
1139 return GSOCK_IOERR;
1140 }
1141#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 1142 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 1143#else
09e6e5ec 1144 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 1145#endif
985acf87 1146 gs_gui_functions->Enable_Events(this);
97e6ee04 1147
01ba4b67
VZ
1148 if (m_reusable)
1149 {
1150 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
1151#ifdef SO_REUSEPORT
1152 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
1153#endif
1154 }
1155
60edcf45 1156 if (m_broadcast)
97e6ee04 1157 {
60edcf45
VZ
1158 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
1159 }
1160 if (m_dobind)
1161 {
1162 /* Bind to the local address,
1163 * and retrieve the actual address bound.
1164 */
1165 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
1166 (getsockname(m_fd,
1167 m_local->m_addr,
1168 (WX_SOCKLEN_T *) &m_local->m_len) != 0))
1169 {
1170 Close();
1171 m_error = GSOCK_IOERR;
1172 return GSOCK_IOERR;
1173 }
97e6ee04 1174 }
97e6ee04
DE
1175 return GSOCK_NOERROR;
1176}
1177
1178/* Generic IO */
1179
1180/* Like recv(), send(), ... */
ba2a81d7 1181int GSocket::Read(char *buffer, int size)
97e6ee04
DE
1182{
1183 int ret;
1184
09e6e5ec 1185 assert(this);
97e6ee04 1186
09e6e5ec 1187 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1188 {
09e6e5ec 1189 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1190 return -1;
1191 }
1192
9d715960
DE
1193 /* Disable events during query of socket status */
1194 Disable(GSOCK_INPUT);
b082b524 1195
97e6ee04 1196 /* If the socket is blocking, wait for data (with a timeout) */
976abb72
VZ
1197 if (Input_Timeout() == GSOCK_TIMEDOUT) {
1198 m_error = GSOCK_TIMEDOUT;
1199 /* Don't return here immediately, otherwise socket events would not be
1200 * re-enabled! */
9d715960 1201 ret = -1;
976abb72 1202 }
1aa7b427
DS
1203 else
1204 {
9d715960
DE
1205 /* Read the data */
1206 if (m_stream)
1207 ret = Recv_Stream(buffer, size);
1208 else
1209 ret = Recv_Dgram(buffer, size);
b082b524 1210
f4854380 1211 /* If recv returned zero, then the connection has been gracefully closed.
9b67181b
KH
1212 * Otherwise, recv has returned an error (-1), in which case we have lost the
1213 * socket only if errno does _not_ indicate that there may be more data to read.
1214 */
1215 if (ret == 0)
98e7a7f9 1216 {
f4854380 1217 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
985acf87
VZ
1218 m_detected = GSOCK_LOST_FLAG;
1219 Detected_Read();
1220 return 0;
98e7a7f9 1221 }
1aa7b427
DS
1222 else if (ret == -1)
1223 {
976abb72
VZ
1224 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1225 m_error = GSOCK_WOULDBLOCK;
1226 else
1227 m_error = GSOCK_IOERR;
1228 }
97e6ee04 1229 }
b082b524 1230
9d715960 1231 /* Enable events again now that we are done processing */
09e6e5ec 1232 Enable(GSOCK_INPUT);
97e6ee04
DE
1233
1234 return ret;
1235}
1236
ba2a81d7 1237int GSocket::Write(const char *buffer, int size)
b082b524 1238{
97e6ee04
DE
1239 int ret;
1240
09e6e5ec 1241 assert(this);
b082b524 1242
97e6ee04
DE
1243 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
1244
09e6e5ec 1245 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1246 {
09e6e5ec 1247 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1248 return -1;
1249 }
1250
1251 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
1252
1253 /* If the socket is blocking, wait for writability (with a timeout) */
09e6e5ec 1254 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04
DE
1255 return -1;
1256
1257 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
1258
1259 /* Write the data */
09e6e5ec
DE
1260 if (m_stream)
1261 ret = Send_Stream(buffer, size);
97e6ee04 1262 else
09e6e5ec 1263 ret = Send_Dgram(buffer, size);
b082b524 1264
97e6ee04
DE
1265 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
1266
1267 if (ret == -1)
1268 {
7e1e6965 1269 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
97e6ee04 1270 {
09e6e5ec 1271 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
1272 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1273 }
1274 else
1275 {
09e6e5ec 1276 m_error = GSOCK_IOERR;
97e6ee04
DE
1277 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1278 }
1279
1280 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1281 * in MSW). Once the first OUTPUT event is received, users can assume
1282 * that the socket is writable until a read operation fails. Only then
1283 * will further OUTPUT events be posted.
1284 */
09e6e5ec 1285 Enable(GSOCK_OUTPUT);
1aa7b427 1286
97e6ee04
DE
1287 return -1;
1288 }
b082b524 1289
97e6ee04
DE
1290 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
1291
1292 return ret;
1293}
1294
1295/* GSocket_Select:
1296 * Polls the socket to determine its status. This function will
1297 * check for the events specified in the 'flags' parameter, and
1298 * it will return a mask indicating which operations can be
1299 * performed. This function won't block, regardless of the
1300 * mode (blocking | nonblocking) of the socket.
1301 */
ba2a81d7 1302GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
97e6ee04 1303{
ba2a81d7 1304 if (!gs_gui_functions->CanUseEventLoop())
97e6ee04
DE
1305 {
1306
1307 GSocketEventFlags result = 0;
1308 fd_set readfds;
1309 fd_set writefds;
1310 fd_set exceptfds;
1311 struct timeval tv;
1312
9d715960
DE
1313 assert(this);
1314
60b0bd1d
JS
1315 if (m_fd == -1)
1316 return (GSOCK_LOST_FLAG & flags);
17a1ebd1 1317
97e6ee04 1318 /* Do not use a static struct, Linux can garble it */
09e6e5ec 1319 tv.tv_sec = m_timeout / 1000;
7488a05e 1320 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1321
17a1ebd1
VZ
1322 wxFD_ZERO(&readfds);
1323 wxFD_ZERO(&writefds);
1324 wxFD_ZERO(&exceptfds);
1325 wxFD_SET(m_fd, &readfds);
9d715960 1326 if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
17a1ebd1
VZ
1327 wxFD_SET(m_fd, &writefds);
1328 wxFD_SET(m_fd, &exceptfds);
97e6ee04
DE
1329
1330 /* Check 'sticky' CONNECTION flag first */
09e6e5ec 1331 result |= (GSOCK_CONNECTION_FLAG & m_detected);
97e6ee04
DE
1332
1333 /* If we have already detected a LOST event, then don't try
1334 * to do any further processing.
1335 */
09e6e5ec 1336 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1337 {
948c96ef 1338 m_establishing = false;
97e6ee04
DE
1339
1340 return (GSOCK_LOST_FLAG & flags);
1341 }
1342
1343 /* Try select now */
09e6e5ec 1344 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
97e6ee04
DE
1345 {
1346 /* What to do here? */
1347 return (result & flags);
1348 }
1349
b74865fa
KH
1350 /* Check for exceptions and errors */
1351 if (wxFD_ISSET(m_fd, &exceptfds))
1352 {
1353 m_establishing = false;
1354 m_detected = GSOCK_LOST_FLAG;
1355
1356 /* LOST event: Abort any further processing */
1357 return (GSOCK_LOST_FLAG & flags);
1358 }
1359
97e6ee04 1360 /* Check for readability */
17a1ebd1 1361 if (wxFD_ISSET(m_fd, &readfds))
97e6ee04 1362 {
b74865fa 1363 result |= GSOCK_INPUT_FLAG;
bb154f79 1364
b74865fa 1365 if (m_server && m_stream)
97e6ee04 1366 {
b74865fa
KH
1367 /* This is a TCP server socket that detected a connection.
1368 While the INPUT_FLAG is also set, it doesn't matter on
01ba4b67 1369 this kind of sockets, as we can only Accept() from them. */
b74865fa
KH
1370 result |= GSOCK_CONNECTION_FLAG;
1371 m_detected |= GSOCK_CONNECTION_FLAG;
97e6ee04
DE
1372 }
1373 }
1374
1375 /* Check for writability */
17a1ebd1 1376 if (wxFD_ISSET(m_fd, &writefds))
97e6ee04 1377 {
09e6e5ec 1378 if (m_establishing && !m_server)
97e6ee04
DE
1379 {
1380 int error;
ddc1a35f 1381 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1382
948c96ef 1383 m_establishing = false;
97e6ee04 1384
f71bb8ef 1385 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
97e6ee04
DE
1386
1387 if (error)
1388 {
09e6e5ec 1389 m_detected = GSOCK_LOST_FLAG;
97e6ee04
DE
1390
1391 /* LOST event: Abort any further processing */
1392 return (GSOCK_LOST_FLAG & flags);
1393 }
1394 else
1395 {
1396 result |= GSOCK_CONNECTION_FLAG;
09e6e5ec 1397 m_detected |= GSOCK_CONNECTION_FLAG;
97e6ee04
DE
1398 }
1399 }
1400 else
1401 {
1402 result |= GSOCK_OUTPUT_FLAG;
1403 }
1404 }
97e6ee04
DE
1405
1406 return (result & flags);
1407
1408 }
1409 else
1410 {
09e6e5ec
DE
1411 assert(this);
1412 return flags & m_detected;
97e6ee04
DE
1413 }
1414}
1415
1416/* Flags */
1417
1418/* GSocket_SetNonBlocking:
1419 * Sets the socket to non-blocking mode. All IO calls will return
1420 * immediately.
1421 */
948c96ef 1422void GSocket::SetNonBlocking(bool non_block)
97e6ee04 1423{
09e6e5ec 1424 assert(this);
97e6ee04
DE
1425
1426 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1427
09e6e5ec 1428 m_non_blocking = non_block;
97e6ee04
DE
1429}
1430
1431/* GSocket_SetTimeout:
1432 * Sets the timeout for blocking calls. Time is expressed in
1433 * milliseconds.
1434 */
ba2a81d7 1435void GSocket::SetTimeout(unsigned long millisec)
97e6ee04 1436{
09e6e5ec 1437 assert(this);
97e6ee04 1438
09e6e5ec 1439 m_timeout = millisec;
97e6ee04
DE
1440}
1441
1442/* GSocket_GetError:
d6922577 1443 * Returns the last error occurred for this socket. Note that successful
97e6ee04
DE
1444 * operations do not clear this back to GSOCK_NOERROR, so use it only
1445 * after an error.
1446 */
ba2a81d7 1447GSocketError WXDLLIMPEXP_NET GSocket::GetError()
97e6ee04 1448{
09e6e5ec 1449 assert(this);
97e6ee04 1450
09e6e5ec 1451 return m_error;
97e6ee04
DE
1452}
1453
1454/* Callbacks */
1455
1456/* GSOCK_INPUT:
1457 * There is data to be read in the input buffer. If, after a read
1458 * operation, there is still data available, the callback function will
1459 * be called again.
1460 * GSOCK_OUTPUT:
b082b524 1461 * The socket is available for writing. That is, the next write call
97e6ee04
DE
1462 * won't block. This event is generated only once, when the connection is
1463 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1464 * when the output buffer empties again. This means that the app should
1465 * assume that it can write since the first OUTPUT event, and no more
1466 * OUTPUT events will be generated unless an error occurs.
1467 * GSOCK_CONNECTION:
d6922577 1468 * Connection successfully established, for client sockets, or incoming
97e6ee04
DE
1469 * client connection, for server sockets. Wait for this event (also watch
1470 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1471 * GSOCK_LOST:
1472 * The connection is lost (or a connection request failed); this could
1473 * be due to a failure, or due to the peer closing it gracefully.
1474 */
1475
1476/* GSocket_SetCallback:
1477 * Enables the callbacks specified by 'flags'. Note that 'flags'
1478 * may be a combination of flags OR'ed toghether, so the same
1479 * callback function can be made to accept different events.
1480 * The callback function must have the following prototype:
1481 *
1482 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1483 */
ba2a81d7 1484void GSocket::SetCallback(GSocketEventFlags flags,
97e6ee04
DE
1485 GSocketCallback callback, char *cdata)
1486{
1487 int count;
1488
09e6e5ec 1489 assert(this);
97e6ee04
DE
1490
1491 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1492 {
1493 if ((flags & (1 << count)) != 0)
1494 {
09e6e5ec
DE
1495 m_cbacks[count] = callback;
1496 m_data[count] = cdata;
97e6ee04
DE
1497 }
1498 }
1499}
1500
1501/* GSocket_UnsetCallback:
1502 * Disables all callbacks specified by 'flags', which may be a
1503 * combination of flags OR'ed toghether.
1504 */
ba2a81d7 1505void GSocket::UnsetCallback(GSocketEventFlags flags)
97e6ee04
DE
1506{
1507 int count;
1508
09e6e5ec 1509 assert(this);
97e6ee04
DE
1510
1511 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1512 {
1513 if ((flags & (1 << count)) != 0)
1514 {
09e6e5ec
DE
1515 m_cbacks[count] = NULL;
1516 m_data[count] = NULL;
97e6ee04
DE
1517 }
1518 }
1519}
1520
ba2a81d7 1521GSocketError GSocket::GetSockOpt(int level, int optname,
b082b524
DE
1522 void *optval, int *optlen)
1523{
ddc1a35f 1524 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
b082b524 1525 return GSOCK_NOERROR;
1aa7b427 1526
b082b524
DE
1527 return GSOCK_OPTERR;
1528}
1529
ba2a81d7 1530GSocketError GSocket::SetSockOpt(int level, int optname,
b082b524
DE
1531 const void *optval, int optlen)
1532{
f71bb8ef 1533 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
b082b524 1534 return GSOCK_NOERROR;
1aa7b427 1535
b082b524
DE
1536 return GSOCK_OPTERR;
1537}
1538
ba2a81d7 1539#define CALL_CALLBACK(socket, event) { \
9a7e4a56 1540 socket->Disable(event); \
ba2a81d7
DE
1541 if (socket->m_cbacks[event]) \
1542 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
97e6ee04
DE
1543}
1544
1545
ba2a81d7 1546void GSocket::Enable(GSocketEvent event)
97e6ee04 1547{
985acf87
VZ
1548 m_detected &= ~(1 << event);
1549 gs_gui_functions->Install_Callback(this, event);
97e6ee04
DE
1550}
1551
ba2a81d7 1552void GSocket::Disable(GSocketEvent event)
97e6ee04 1553{
985acf87
VZ
1554 m_detected |= (1 << event);
1555 gs_gui_functions->Uninstall_Callback(this, event);
97e6ee04
DE
1556}
1557
1558/* _GSocket_Input_Timeout:
1559 * For blocking sockets, wait until data is available or
1560 * until timeout ellapses.
1561 */
ba2a81d7 1562GSocketError GSocket::Input_Timeout()
97e6ee04
DE
1563{
1564 struct timeval tv;
1565 fd_set readfds;
1566 int ret;
1567
1568 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1569 tv.tv_sec = (m_timeout / 1000);
1570 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1571
09e6e5ec 1572 if (!m_non_blocking)
97e6ee04 1573 {
17a1ebd1
VZ
1574 wxFD_ZERO(&readfds);
1575 wxFD_SET(m_fd, &readfds);
09e6e5ec 1576 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
97e6ee04
DE
1577 if (ret == 0)
1578 {
1579 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
09e6e5ec 1580 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1581 return GSOCK_TIMEDOUT;
1582 }
1aa7b427 1583
97e6ee04
DE
1584 if (ret == -1)
1585 {
1586 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1587 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1588 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1589 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1590 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1591 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1592 return GSOCK_TIMEDOUT;
1593 }
1594 }
1aa7b427 1595
97e6ee04
DE
1596 return GSOCK_NOERROR;
1597}
1598
1599/* _GSocket_Output_Timeout:
1600 * For blocking sockets, wait until data can be sent without
1601 * blocking or until timeout ellapses.
1602 */
ba2a81d7 1603GSocketError GSocket::Output_Timeout()
97e6ee04
DE
1604{
1605 struct timeval tv;
1606 fd_set writefds;
1607 int ret;
1608
1609 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1610 tv.tv_sec = (m_timeout / 1000);
1611 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1612
09e6e5ec 1613 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
97e6ee04 1614
09e6e5ec 1615 if (!m_non_blocking)
97e6ee04 1616 {
17a1ebd1
VZ
1617 wxFD_ZERO(&writefds);
1618 wxFD_SET(m_fd, &writefds);
09e6e5ec 1619 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
97e6ee04
DE
1620 if (ret == 0)
1621 {
1622 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
09e6e5ec 1623 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1624 return GSOCK_TIMEDOUT;
1625 }
1aa7b427 1626
97e6ee04
DE
1627 if (ret == -1)
1628 {
1629 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1630 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1631 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1632 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1633 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1634 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1635 return GSOCK_TIMEDOUT;
1636 }
1aa7b427
DS
1637
1638 if ( ! wxFD_ISSET(m_fd, &writefds) )
1639 {
97e6ee04
DE
1640 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1641 }
1aa7b427
DS
1642 else
1643 {
97e6ee04
DE
1644 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1645 }
1646 }
1647 else
1648 {
1649 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1650 }
1651
1652 return GSOCK_NOERROR;
1653}
1654
ba2a81d7 1655int GSocket::Recv_Stream(char *buffer, int size)
97e6ee04 1656{
bb154f79 1657 int ret;
7e1e6965 1658 do
bb154f79
KH
1659 {
1660 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1661 }
1662 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1663
bb154f79 1664 return ret;
97e6ee04
DE
1665}
1666
ba2a81d7 1667int GSocket::Recv_Dgram(char *buffer, int size)
97e6ee04
DE
1668{
1669 struct sockaddr from;
9e03e02d 1670 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
1671 int ret;
1672 GSocketError err;
1673
1674 fromlen = sizeof(from);
1675
7e1e6965 1676 do
bb154f79 1677 {
9e03e02d 1678 ret = recvfrom(m_fd, buffer, size, 0, &from, (WX_SOCKLEN_T *) &fromlen);
1aa7b427
DS
1679 }
1680 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
97e6ee04
DE
1681
1682 if (ret == -1)
1683 return -1;
1684
1685 /* Translate a system address into a GSocket address */
09e6e5ec 1686 if (!m_peer)
97e6ee04 1687 {
09e6e5ec
DE
1688 m_peer = GAddress_new();
1689 if (!m_peer)
97e6ee04 1690 {
09e6e5ec 1691 m_error = GSOCK_MEMERR;
97e6ee04
DE
1692 return -1;
1693 }
1694 }
1aa7b427 1695
09e6e5ec 1696 err = _GAddress_translate_from(m_peer, &from, fromlen);
97e6ee04
DE
1697 if (err != GSOCK_NOERROR)
1698 {
09e6e5ec
DE
1699 GAddress_destroy(m_peer);
1700 m_peer = NULL;
1701 m_error = err;
97e6ee04
DE
1702 return -1;
1703 }
1704
1705 return ret;
1706}
1707
ba2a81d7 1708int GSocket::Send_Stream(const char *buffer, int size)
97e6ee04
DE
1709{
1710 int ret;
1711
7e1e6965
WS
1712 MASK_SIGNAL();
1713
1714 do
bb154f79
KH
1715 {
1716 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1717 }
1718 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1719
97e6ee04 1720 UNMASK_SIGNAL();
97e6ee04
DE
1721
1722 return ret;
1723}
1724
ba2a81d7 1725int GSocket::Send_Dgram(const char *buffer, int size)
97e6ee04
DE
1726{
1727 struct sockaddr *addr;
1728 int len, ret;
1729 GSocketError err;
1730
09e6e5ec 1731 if (!m_peer)
97e6ee04 1732 {
09e6e5ec 1733 m_error = GSOCK_INVADDR;
97e6ee04
DE
1734 return -1;
1735 }
1736
09e6e5ec 1737 err = _GAddress_translate_to(m_peer, &addr, &len);
97e6ee04
DE
1738 if (err != GSOCK_NOERROR)
1739 {
09e6e5ec 1740 m_error = err;
97e6ee04
DE
1741 return -1;
1742 }
1743
97e6ee04 1744 MASK_SIGNAL();
7e1e6965
WS
1745
1746 do
bb154f79
KH
1747 {
1748 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1aa7b427
DS
1749 }
1750 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1751
97e6ee04 1752 UNMASK_SIGNAL();
97e6ee04
DE
1753
1754 /* Frees memory allocated from _GAddress_translate_to */
1755 free(addr);
1756
1757 return ret;
1758}
1759
ba2a81d7 1760void GSocket::Detected_Read()
97e6ee04
DE
1761{
1762 char c;
1763
bb154f79
KH
1764 /* Safeguard against straggling call to Detected_Read */
1765 if (m_fd == INVALID_SOCKET)
1766 {
1767 return;
1768 }
1769
97e6ee04
DE
1770 /* If we have already detected a LOST event, then don't try
1771 * to do any further processing.
1772 */
09e6e5ec 1773 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1774 {
948c96ef 1775 m_establishing = false;
97e6ee04 1776
ba2a81d7 1777 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1778 Shutdown();
97e6ee04
DE
1779 return;
1780 }
1781
bb154f79
KH
1782 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1783
1784 if (num > 0)
97e6ee04 1785 {
ba2a81d7 1786 CALL_CALLBACK(this, GSOCK_INPUT);
97e6ee04
DE
1787 }
1788 else
1789 {
09e6e5ec 1790 if (m_server && m_stream)
97e6ee04 1791 {
ba2a81d7 1792 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04 1793 }
e37e082e
VZ
1794 else if (num == 0)
1795 {
1796 /* graceful shutdown */
1797 CALL_CALLBACK(this, GSOCK_LOST);
1798 Shutdown();
1799 }
97e6ee04
DE
1800 else
1801 {
e400d27d 1802 /* Do not throw a lost event in cases where the socket isn't really lost */
7e1e6965 1803 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
bb154f79
KH
1804 {
1805 CALL_CALLBACK(this, GSOCK_INPUT);
1806 }
7e1e6965 1807 else
bb154f79
KH
1808 {
1809 CALL_CALLBACK(this, GSOCK_LOST);
1810 Shutdown();
7e1e6965 1811 }
97e6ee04
DE
1812 }
1813 }
1814}
1815
ba2a81d7 1816void GSocket::Detected_Write()
97e6ee04
DE
1817{
1818 /* If we have already detected a LOST event, then don't try
1819 * to do any further processing.
1820 */
09e6e5ec 1821 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1822 {
948c96ef 1823 m_establishing = false;
97e6ee04 1824
ba2a81d7 1825 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1826 Shutdown();
97e6ee04
DE
1827 return;
1828 }
1829
09e6e5ec 1830 if (m_establishing && !m_server)
97e6ee04
DE
1831 {
1832 int error;
ddc1a35f 1833 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1834
948c96ef 1835 m_establishing = false;
97e6ee04 1836
f71bb8ef 1837 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
97e6ee04
DE
1838
1839 if (error)
1840 {
ba2a81d7 1841 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1842 Shutdown();
97e6ee04
DE
1843 }
1844 else
1845 {
ba2a81d7 1846 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04
DE
1847 /* We have to fire this event by hand because CONNECTION (for clients)
1848 * and OUTPUT are internally the same and we just disabled CONNECTION
1849 * events with the above macro.
1850 */
ba2a81d7 1851 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1852 }
1853 }
1854 else
1855 {
ba2a81d7 1856 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1857 }
1858}
1859
09e6e5ec
DE
1860/* Compatibility functions for GSocket */
1861GSocket *GSocket_new(void)
1862{
ba2a81d7 1863 GSocket *newsocket = new GSocket();
1aa7b427 1864 if (newsocket->IsOk())
09e6e5ec 1865 return newsocket;
1aa7b427 1866
09e6e5ec 1867 delete newsocket;
1aa7b427 1868
09e6e5ec
DE
1869 return NULL;
1870}
1871
97e6ee04
DE
1872/*
1873 * -------------------------------------------------------------------------
1874 * GAddress
1875 * -------------------------------------------------------------------------
1876 */
1877
1878/* CHECK_ADDRESS verifies that the current address family is either
1879 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1880 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1881 * an appropiate error code.
1882 *
1883 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1884 */
1885#define CHECK_ADDRESS(address, family) \
1886{ \
1887 if (address->m_family == GSOCK_NOFAMILY) \
1888 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1889 return address->m_error; \
1890 if (address->m_family != GSOCK_##family) \
1891 { \
1892 address->m_error = GSOCK_INVADDR; \
1893 return GSOCK_INVADDR; \
1894 } \
1895}
1896
1897#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1898{ \
1899 if (address->m_family == GSOCK_NOFAMILY) \
1900 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1901 return retval; \
1902 if (address->m_family != GSOCK_##family) \
1903 { \
1904 address->m_error = GSOCK_INVADDR; \
1905 return retval; \
1906 } \
1907}
1908
1909
1910GAddress *GAddress_new(void)
1911{
1912 GAddress *address;
1913
1914 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1915 return NULL;
1916
1917 address->m_family = GSOCK_NOFAMILY;
1918 address->m_addr = NULL;
1919 address->m_len = 0;
1920
1921 return address;
1922}
1923
1924GAddress *GAddress_copy(GAddress *address)
1925{
1926 GAddress *addr2;
1927
1928 assert(address != NULL);
1929
1930 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1931 return NULL;
1932
1933 memcpy(addr2, address, sizeof(GAddress));
1934
1935 if (address->m_addr && address->m_len > 0)
1936 {
1937 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1938 if (addr2->m_addr == NULL)
1939 {
1940 free(addr2);
1941 return NULL;
1942 }
1943 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1944 }
1945
1946 return addr2;
1947}
1948
1949void GAddress_destroy(GAddress *address)
1950{
1951 assert(address != NULL);
1952
1953 if (address->m_addr)
1954 free(address->m_addr);
1955
1956 free(address);
1957}
1958
1959void GAddress_SetFamily(GAddress *address, GAddressType type)
1960{
1961 assert(address != NULL);
1962
1963 address->m_family = type;
1964}
1965
1966GAddressType GAddress_GetFamily(GAddress *address)
1967{
1968 assert(address != NULL);
1969
1970 return address->m_family;
1971}
1972
1973GSocketError _GAddress_translate_from(GAddress *address,
1974 struct sockaddr *addr, int len)
1975{
1976 address->m_realfamily = addr->sa_family;
1977 switch (addr->sa_family)
1978 {
1979 case AF_INET:
1980 address->m_family = GSOCK_INET;
1981 break;
1982 case AF_UNIX:
1983 address->m_family = GSOCK_UNIX;
1984 break;
1985#ifdef AF_INET6
1986 case AF_INET6:
1987 address->m_family = GSOCK_INET6;
1988 break;
1989#endif
1990 default:
1991 {
1992 address->m_error = GSOCK_INVOP;
1993 return GSOCK_INVOP;
1994 }
1995 }
1996
1997 if (address->m_addr)
1998 free(address->m_addr);
1999
2000 address->m_len = len;
2001 address->m_addr = (struct sockaddr *)malloc(len);
2002
2003 if (address->m_addr == NULL)
2004 {
2005 address->m_error = GSOCK_MEMERR;
2006 return GSOCK_MEMERR;
2007 }
1aa7b427 2008
97e6ee04
DE
2009 memcpy(address->m_addr, addr, len);
2010
2011 return GSOCK_NOERROR;
2012}
2013
2014GSocketError _GAddress_translate_to(GAddress *address,
2015 struct sockaddr **addr, int *len)
2016{
2017 if (!address->m_addr)
2018 {
2019 address->m_error = GSOCK_INVADDR;
2020 return GSOCK_INVADDR;
2021 }
2022
2023 *len = address->m_len;
2024 *addr = (struct sockaddr *)malloc(address->m_len);
2025 if (*addr == NULL)
2026 {
2027 address->m_error = GSOCK_MEMERR;
2028 return GSOCK_MEMERR;
2029 }
2030
2031 memcpy(*addr, address->m_addr, address->m_len);
2032 return GSOCK_NOERROR;
2033}
2034
2035/*
2036 * -------------------------------------------------------------------------
2037 * Internet address family
2038 * -------------------------------------------------------------------------
2039 */
2040
2041GSocketError _GAddress_Init_INET(GAddress *address)
2042{
2043 address->m_len = sizeof(struct sockaddr_in);
2044 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2045 if (address->m_addr == NULL)
2046 {
2047 address->m_error = GSOCK_MEMERR;
2048 return GSOCK_MEMERR;
2049 }
2050
2051 address->m_family = GSOCK_INET;
2052 address->m_realfamily = PF_INET;
2053 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
2054 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
2055
2056 return GSOCK_NOERROR;
2057}
2058
2059GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
2060{
2061 struct hostent *he;
2062 struct in_addr *addr;
2063
2064 assert(address != NULL);
2065
2066 CHECK_ADDRESS(address, INET);
2067
2068 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2069
2070 /* If it is a numeric host name, convert it now */
2071#if defined(HAVE_INET_ATON)
2072 if (inet_aton(hostname, addr) == 0)
2073 {
2074#elif defined(HAVE_INET_ADDR)
8c0f8906 2075 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
97e6ee04
DE
2076 {
2077#else
2078 /* Use gethostbyname by default */
9d715960 2079#ifndef __WXMAC__
ba2a81d7 2080 int val = 1; /* VA doesn't like constants in conditional expressions */
97e6ee04 2081 if (val)
9d715960 2082#endif
97e6ee04
DE
2083 {
2084#endif
2085 struct in_addr *array_addr;
2086
2087 /* It is a real name, we solve it */
127189eb
SN
2088 struct hostent h;
2089#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2090 struct hostent_data buffer;
2091#else
2092 char buffer[1024];
2093#endif
2094 int err;
2095 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
2096 if (he == NULL)
97e6ee04
DE
2097 {
2098 /* Reset to invalid address */
2099 addr->s_addr = INADDR_NONE;
2100 address->m_error = GSOCK_NOHOST;
2101 return GSOCK_NOHOST;
2102 }
1aa7b427 2103
97e6ee04
DE
2104 array_addr = (struct in_addr *) *(he->h_addr_list);
2105 addr->s_addr = array_addr[0].s_addr;
2106 }
1aa7b427 2107
97e6ee04
DE
2108 return GSOCK_NOERROR;
2109}
2110
60edcf45
VZ
2111
2112GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
2113{
2114 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2115}
2116
97e6ee04
DE
2117GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2118{
2119 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2120}
2121
2122GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2123 unsigned long hostaddr)
2124{
2125 struct in_addr *addr;
2126
2127 assert(address != NULL);
2128
2129 CHECK_ADDRESS(address, INET);
2130
2131 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
9d715960 2132 addr->s_addr = htonl(hostaddr);
97e6ee04
DE
2133
2134 return GSOCK_NOERROR;
2135}
2136
2137GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2138 const char *protocol)
2139{
2140 struct servent *se;
2141 struct sockaddr_in *addr;
2142
2143 assert(address != NULL);
2144 CHECK_ADDRESS(address, INET);
2145
2146 if (!port)
2147 {
2148 address->m_error = GSOCK_INVPORT;
2149 return GSOCK_INVPORT;
2150 }
b082b524 2151
127189eb
SN
2152#if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2153 struct servent_data buffer;
f6bc1c74 2154#else
127189eb 2155 char buffer[1024];
f6bc1c74 2156#endif
127189eb
SN
2157 struct servent serv;
2158 se = wxGetservbyname_r(port, protocol, &serv,
2159 (void*)&buffer, sizeof(buffer));
97e6ee04
DE
2160 if (!se)
2161 {
2162 /* the cast to int suppresses compiler warnings about subscript having the
2163 type char */
2164 if (isdigit((int)port[0]))
2165 {
2166 int port_int;
2167
2168 port_int = atoi(port);
2169 addr = (struct sockaddr_in *)address->m_addr;
2170 addr->sin_port = htons(port_int);
2171 return GSOCK_NOERROR;
2172 }
2173
2174 address->m_error = GSOCK_INVPORT;
2175 return GSOCK_INVPORT;
2176 }
2177
2178 addr = (struct sockaddr_in *)address->m_addr;
2179 addr->sin_port = se->s_port;
2180
2181 return GSOCK_NOERROR;
2182}
2183
2184GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2185{
2186 struct sockaddr_in *addr;
2187
2188 assert(address != NULL);
2189 CHECK_ADDRESS(address, INET);
b082b524 2190
97e6ee04
DE
2191 addr = (struct sockaddr_in *)address->m_addr;
2192 addr->sin_port = htons(port);
2193
2194 return GSOCK_NOERROR;
2195}
2196
2197GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2198{
2199 struct hostent *he;
2200 char *addr_buf;
2201 struct sockaddr_in *addr;
2202
b082b524 2203 assert(address != NULL);
97e6ee04
DE
2204 CHECK_ADDRESS(address, INET);
2205
2206 addr = (struct sockaddr_in *)address->m_addr;
2207 addr_buf = (char *)&(addr->sin_addr);
2208
127189eb
SN
2209 struct hostent temphost;
2210#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2211 struct hostent_data buffer;
2212#else
2213 char buffer[1024];
2214#endif
2215 int err;
2216 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2217 (void*)&buffer, sizeof(buffer), &err);
97e6ee04
DE
2218 if (he == NULL)
2219 {
2220 address->m_error = GSOCK_NOHOST;
2221 return GSOCK_NOHOST;
2222 }
2223
2224 strncpy(hostname, he->h_name, sbuf);
2225
2226 return GSOCK_NOERROR;
2227}
2228
2229unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2230{
2231 struct sockaddr_in *addr;
2232
b082b524
DE
2233 assert(address != NULL);
2234 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2235
2236 addr = (struct sockaddr_in *)address->m_addr;
2237
9d715960 2238 return ntohl(addr->sin_addr.s_addr);
97e6ee04
DE
2239}
2240
2241unsigned short GAddress_INET_GetPort(GAddress *address)
2242{
2243 struct sockaddr_in *addr;
2244
b082b524
DE
2245 assert(address != NULL);
2246 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2247
2248 addr = (struct sockaddr_in *)address->m_addr;
2249 return ntohs(addr->sin_port);
2250}
2251
2252/*
2253 * -------------------------------------------------------------------------
2254 * Unix address family
2255 * -------------------------------------------------------------------------
2256 */
2257
2258#ifndef __VISAGECPP__
2259GSocketError _GAddress_Init_UNIX(GAddress *address)
2260{
2261 address->m_len = sizeof(struct sockaddr_un);
2262 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2263 if (address->m_addr == NULL)
2264 {
2265 address->m_error = GSOCK_MEMERR;
2266 return GSOCK_MEMERR;
2267 }
2268
2269 address->m_family = GSOCK_UNIX;
2270 address->m_realfamily = PF_UNIX;
2271 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2272 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2273
2274 return GSOCK_NOERROR;
2275}
2276
2277#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2278
2279GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2280{
2281 struct sockaddr_un *addr;
2282
b082b524 2283 assert(address != NULL);
97e6ee04 2284
b082b524 2285 CHECK_ADDRESS(address, UNIX);
97e6ee04
DE
2286
2287 addr = ((struct sockaddr_un *)address->m_addr);
2288 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2289 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2290
2291 return GSOCK_NOERROR;
2292}
2293
2294GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2295{
2296 struct sockaddr_un *addr;
2297
2298 assert(address != NULL);
2299 CHECK_ADDRESS(address, UNIX);
2300
2301 addr = (struct sockaddr_un *)address->m_addr;
2302
2303 strncpy(path, addr->sun_path, sbuf);
2304
2305 return GSOCK_NOERROR;
2306}
2307#endif /* !defined(__VISAGECPP__) */
2308#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */