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