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