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