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