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