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