]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/unix/gsocket.c
1. wxGetOsDescription() function added
[wxWidgets.git] / src / unix / gsocket.c
... / ...
CommitLineData
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Purpose: GSocket main Unix file
5 * CVSID: $Id$
6 * -------------------------------------------------------------------------
7 */
8
9#include "wx/setup.h"
10
11#if wxUSE_SOCKETS
12
13#include <assert.h>
14#include <sys/types.h>
15#include <netdb.h>
16#include <sys/ioctl.h>
17#ifdef __VMS__
18#define SOCK_LEN_TYP (unsigned int*)
19#include <socket.h>
20struct sockaddr_un {
21 u_char sun_len; /* sockaddr len including null */
22 u_char sun_family; /* AF_UNIX */
23 char sun_path[108]; /* path name (gag) */
24};
25#else
26#include <sys/socket.h>
27#include <sys/un.h>
28#define SOCK_LEN_TYP (int*)
29#endif
30#include <sys/time.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <errno.h>
34
35#include <string.h>
36#include <unistd.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <stddef.h>
40#include <ctype.h>
41
42#ifdef sun
43# include <sys/filio.h>
44#endif
45
46#ifdef sgi
47# include <bstring.h>
48#endif
49
50#include <signal.h>
51
52#include "wx/gsocket.h"
53#include "wx/unix/gsockunx.h"
54
55#ifndef SOCKLEN_T
56
57#ifdef __GLIBC__
58# if __GLIBC__ == 2
59# define SOCKLEN_T socklen_t
60# endif
61#else
62# define SOCKLEN_T int
63#endif
64
65#endif
66
67#define MASK_SIGNAL() \
68{ \
69 void (*old_handler)(int); \
70 \
71 old_handler = signal(SIGPIPE, SIG_IGN);
72
73#define UNMASK_SIGNAL() \
74 signal(SIGPIPE, old_handler); \
75}
76
77
78/* Global initialisers */
79
80bool GSocket_Init()
81{
82 return TRUE;
83}
84
85void GSocket_Cleanup()
86{
87}
88
89/* Constructors / Destructors */
90
91GSocket *GSocket_new()
92{
93 int i;
94 GSocket *socket;
95
96 socket = (GSocket *)malloc(sizeof(GSocket));
97
98 if (socket == NULL)
99 return NULL;
100
101 socket->m_fd = -1;
102 for (i=0;i<GSOCK_MAX_EVENT;i++)
103 {
104 socket->m_cbacks[i] = NULL;
105 }
106 socket->m_detected = 0;
107 socket->m_local = NULL;
108 socket->m_peer = NULL;
109 socket->m_error = GSOCK_NOERROR;
110 socket->m_server = FALSE;
111 socket->m_stream = TRUE;
112 socket->m_gui_dependent = NULL;
113 socket->m_non_blocking = FALSE;
114 socket->m_timeout = 10*60*1000;
115 /* 10 minutes * 60 sec * 1000 millisec */
116 socket->m_establishing = FALSE;
117
118 /* We initialize the GUI specific entries here */
119 _GSocket_GUI_Init(socket);
120
121 return socket;
122}
123
124void GSocket_destroy(GSocket *socket)
125{
126 assert(socket != NULL);
127
128 /* First, we check that the socket is really shutdowned */
129 if (socket->m_fd != -1)
130 GSocket_Shutdown(socket);
131
132 /* We destroy GUI specific variables */
133 _GSocket_GUI_Destroy(socket);
134
135 /* We destroy private addresses */
136 if (socket->m_local)
137 GAddress_destroy(socket->m_local);
138
139 if (socket->m_peer)
140 GAddress_destroy(socket->m_peer);
141
142 /* We destroy socket itself */
143 free(socket);
144}
145
146void GSocket_Shutdown(GSocket *socket)
147{
148 int evt;
149
150 assert(socket != NULL);
151
152 /* If socket has been created, we shutdown it */
153 if (socket->m_fd != -1)
154 {
155 shutdown(socket->m_fd, 2);
156 close(socket->m_fd);
157 socket->m_fd = -1;
158 }
159
160 /* We also disable GUI callbacks */
161 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
162 socket->m_cbacks[evt] = NULL;
163
164 socket->m_detected = 0;
165 _GSocket_Disable_Events(socket);
166}
167
168/* Address handling */
169
170GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
171{
172 assert(socket != NULL);
173
174 if ((socket->m_fd != -1 && !socket->m_server)) {
175 socket->m_error = GSOCK_INVSOCK;
176 return GSOCK_INVSOCK;
177 }
178
179 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
180 socket->m_error = GSOCK_INVADDR;
181 return GSOCK_INVADDR;
182 }
183
184 if (socket->m_local)
185 GAddress_destroy(socket->m_local);
186
187 socket->m_local = GAddress_copy(address);
188
189 return GSOCK_NOERROR;
190}
191
192GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
193{
194 assert(socket != NULL);
195
196 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
197 socket->m_error = GSOCK_INVADDR;
198 return GSOCK_INVADDR;
199 }
200
201 if (socket->m_peer)
202 GAddress_destroy(socket->m_peer);
203
204 socket->m_peer = GAddress_copy(address);
205
206 return GSOCK_NOERROR;
207}
208
209GAddress *GSocket_GetLocal(GSocket *socket)
210{
211 GAddress *address;
212 struct sockaddr addr;
213 SOCKLEN_T size;
214 GSocketError err;
215
216 assert(socket != NULL);
217
218 if (socket->m_local)
219 return GAddress_copy(socket->m_local);
220
221 if (socket->m_fd == -1) {
222 socket->m_error = GSOCK_INVSOCK;
223 return NULL;
224 }
225
226 size = sizeof(addr);
227
228 if (getsockname(socket->m_fd, &addr, SOCK_LEN_TYP &size) < 0) {
229 socket->m_error = GSOCK_IOERR;
230 return NULL;
231 }
232
233 address = GAddress_new();
234 if (address == NULL) {
235 socket->m_error = GSOCK_MEMERR;
236 return NULL;
237 }
238 socket->m_error = _GAddress_translate_from(address, &addr, size);
239 if (socket->m_error != GSOCK_NOERROR) {
240 GAddress_destroy(address);
241 return NULL;
242 }
243
244 return address;
245}
246
247GAddress *GSocket_GetPeer(GSocket *socket)
248{
249 assert(socket != NULL);
250
251 if (socket->m_peer)
252 return GAddress_copy(socket->m_peer);
253
254 return NULL;
255}
256
257/* Server specific parts */
258
259/* GSocket_SetServer:
260 * Sets up the socket as a server. It uses the "Local" field of GSocket.
261 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
262 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
263 * been initialized, GSOCK_INVADDR if the local address has not been
264 * defined and GSOCK_IOERR for other internal errors.
265 */
266GSocketError GSocket_SetServer(GSocket *sck)
267{
268 int type;
269 int arg = 1;
270
271 assert(sck != NULL);
272
273 if (sck->m_fd != -1) {
274 sck->m_error = GSOCK_INVSOCK;
275 return GSOCK_INVSOCK;
276 }
277
278 if (!sck->m_local) {
279 sck->m_error = GSOCK_INVADDR;
280 return GSOCK_INVADDR;
281 }
282
283 /* We always have a stream here */
284 sck->m_stream = TRUE;
285 sck->m_server = TRUE;
286
287 /* Create the socket */
288 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
289
290 if (sck->m_fd == -1) {
291 sck->m_error = GSOCK_IOERR;
292 return GSOCK_IOERR;
293 }
294
295 ioctl(sck->m_fd, FIONBIO, &arg);
296 _GSocket_Enable_Events(sck);
297
298 /* Bind the socket to the LOCAL address */
299 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
300 close(sck->m_fd);
301 sck->m_fd = -1;
302 sck->m_error = GSOCK_IOERR;
303 return GSOCK_IOERR;
304 }
305
306 /* Enable listening up to 5 connections */
307 if (listen(sck->m_fd, 5) < 0) {
308 close(sck->m_fd);
309 sck->m_fd = -1;
310 sck->m_error = GSOCK_IOERR;
311 return GSOCK_IOERR;
312 }
313
314 return GSOCK_NOERROR;
315}
316
317/* GSocket_WaitConnection:
318 * Waits for an incoming client connection.
319 */
320GSocket *GSocket_WaitConnection(GSocket *socket)
321{
322 GSocket *connection;
323 int arg = 1;
324
325 assert(socket != NULL);
326
327 /* Reenable CONNECTION events */
328 _GSocket_Enable(socket, GSOCK_CONNECTION);
329
330 /* If the socket has already been created, we exit immediately */
331 if (socket->m_fd == -1 || !socket->m_server)
332 {
333 socket->m_error = GSOCK_INVSOCK;
334 return NULL;
335 }
336
337 /* Create a GSocket object for the new connection */
338 connection = GSocket_new();
339 if (!connection)
340 {
341 connection->m_error = GSOCK_MEMERR;
342 return NULL;
343 }
344
345 /* Accept the incoming connection */
346 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
347 {
348 GSocket_destroy(connection);
349 /* socket->m_error set by _GSocket_Input_Timeout */
350 return NULL;
351 }
352
353 connection->m_fd = accept(socket->m_fd, NULL, NULL);
354
355 if (connection->m_fd == -1)
356 {
357 if (errno == EWOULDBLOCK)
358 socket->m_error = GSOCK_WOULDBLOCK;
359 else
360 socket->m_error = GSOCK_IOERR;
361
362 GSocket_destroy(connection);
363 return NULL;
364 }
365
366 /* Initialize all fields */
367 connection->m_server = FALSE;
368 connection->m_stream = TRUE;
369 connection->m_oriented = TRUE;
370
371 ioctl(connection->m_fd, FIONBIO, &arg);
372 _GSocket_Enable_Events(connection);
373
374 return connection;
375}
376
377/* Non oriented connections */
378
379GSocketError GSocket_SetNonOriented(GSocket *sck)
380{
381 int arg = 1;
382
383 assert(sck != NULL);
384
385 if (sck->m_fd != -1) {
386 sck->m_error = GSOCK_INVSOCK;
387 return GSOCK_INVSOCK;
388 }
389
390 if (!sck->m_local) {
391 sck->m_error = GSOCK_INVADDR;
392 return GSOCK_INVADDR;
393 }
394
395 sck->m_stream = FALSE;
396 sck->m_server = FALSE;
397 sck->m_oriented = FALSE;
398
399 /* Create the socket */
400 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
401
402 if (sck->m_fd < 0) {
403 sck->m_error = GSOCK_IOERR;
404 return GSOCK_IOERR;
405 }
406
407 ioctl(sck->m_fd, FIONBIO, &arg);
408 _GSocket_Enable_Events(sck);
409
410 /* Bind it to the LOCAL address */
411 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
412 close(sck->m_fd);
413 sck->m_fd = -1;
414 sck->m_error = GSOCK_IOERR;
415 return GSOCK_IOERR;
416 }
417
418 return GSOCK_NOERROR;
419}
420
421/* Client specific parts */
422
423/* GSocket_Connect:
424 * Establishes a client connection to a server using the "Peer"
425 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
426 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
427 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
428 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
429 * the connection request can be completed later. Use GSocket_Select()
430 * to check or wait for a GSOCK_CONNECTION event.
431 */
432GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
433{
434 int type, err, ret;
435 int arg = 1;
436
437 assert(sck != NULL);
438
439 /* Enable CONNECTION events (needed for nonblocking connections) */
440 _GSocket_Enable(sck, GSOCK_CONNECTION);
441
442 if (sck->m_fd != -1)
443 {
444 sck->m_error = GSOCK_INVSOCK;
445 return GSOCK_INVSOCK;
446 }
447
448 if (!sck->m_peer)
449 {
450 sck->m_error = GSOCK_INVADDR;
451 return GSOCK_INVADDR;
452 }
453
454 /* Test whether we want the socket to be a stream (e.g. TCP) */
455 sck->m_stream = (stream == GSOCK_STREAMED);
456 sck->m_oriented = TRUE;
457 sck->m_server = FALSE;
458 sck->m_establishing = FALSE;
459
460 if (sck->m_stream)
461 type = SOCK_STREAM;
462 else
463 type = SOCK_DGRAM;
464
465 /* Create the socket */
466 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
467
468 if (sck->m_fd == -1) {
469 sck->m_error = GSOCK_IOERR;
470 return GSOCK_IOERR;
471 }
472
473 ioctl(sck->m_fd, FIONBIO, &arg);
474 _GSocket_Enable_Events(sck);
475
476 /* Connect it to the PEER address */
477 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
478
479 if (ret == -1)
480 {
481 err = errno;
482
483 /* If connect failed with EINPROGRESS and the GSocket object
484 * is in blocking mode, we select() for the specified timeout
485 * checking for writability to see if the connection request
486 * completes.
487 */
488 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
489 {
490 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
491 {
492 close(sck->m_fd);
493 sck->m_fd = -1;
494 /* sck->m_error is set in _GSocket_Output_Timeout */
495 return GSOCK_TIMEDOUT;
496 }
497 else
498 {
499 return GSOCK_NOERROR;
500 }
501 }
502
503 /* If connect failed with EINPROGRESS and the GSocket object
504 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
505 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
506 * this way if the connection completes, a GSOCK_CONNECTION
507 * event will be generated, if enabled.
508 */
509 if ((err == EINPROGRESS) && (sck->m_non_blocking))
510 {
511 sck->m_error = GSOCK_WOULDBLOCK;
512 sck->m_establishing = TRUE;
513
514 return GSOCK_WOULDBLOCK;
515 }
516
517 /* If connect failed with an error other than EINPROGRESS,
518 * then the call to GSocket_Connect has failed.
519 */
520 close(sck->m_fd);
521 sck->m_fd = -1;
522 sck->m_error = GSOCK_IOERR;
523
524 return GSOCK_IOERR;
525 }
526
527 return GSOCK_NOERROR;
528}
529
530/* Generic IO */
531
532/* Like recv(), send(), ... */
533int GSocket_Read(GSocket *socket, char *buffer, int size)
534{
535 int ret;
536
537 assert(socket != NULL);
538
539 /* Reenable INPUT events */
540 _GSocket_Enable(socket, GSOCK_INPUT);
541
542 if (socket->m_fd == -1 || socket->m_server)
543 {
544 socket->m_error = GSOCK_INVSOCK;
545 return -1;
546 }
547
548 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
549 return -1;
550
551 if (socket->m_stream)
552 ret = _GSocket_Recv_Stream(socket, buffer, size);
553 else
554 ret = _GSocket_Recv_Dgram(socket, buffer, size);
555
556 if (ret == -1)
557 {
558 if (errno == EWOULDBLOCK)
559 socket->m_error = GSOCK_WOULDBLOCK;
560 else
561 socket->m_error = GSOCK_IOERR;
562 }
563
564 return ret;
565}
566
567int GSocket_Write(GSocket *socket, const char *buffer,
568 int size)
569{
570 int ret;
571
572 assert(socket != NULL);
573
574 if (socket->m_fd == -1 || socket->m_server)
575 {
576 socket->m_error = GSOCK_INVSOCK;
577 return -1;
578 }
579
580 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
581 return -1;
582
583 if (socket->m_stream)
584 ret = _GSocket_Send_Stream(socket, buffer, size);
585 else
586 ret = _GSocket_Send_Dgram(socket, buffer, size);
587
588 if (ret == -1)
589 {
590 if (errno == EWOULDBLOCK)
591 socket->m_error = GSOCK_WOULDBLOCK;
592 else
593 socket->m_error = GSOCK_IOERR;
594
595 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
596 * in MSW). Once the first OUTPUT event is received, users can assume
597 * that the socket is writable until a read operation fails. Only then
598 * will further OUTPUT events be posted.
599 */
600 _GSocket_Enable(socket, GSOCK_OUTPUT);
601 }
602
603 return ret;
604}
605
606/* GSocket_Select:
607 * Polls the socket to determine its status. This function will
608 * check for the events specified in the 'flags' parameter, and
609 * it will return a mask indicating which operations can be
610 * performed. This function won't block, regardless of the
611 * mode (blocking|nonblocking) of the socket.
612 */
613GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
614{
615 assert(socket != NULL);
616
617 return (flags & socket->m_detected);
618}
619
620/* Flags */
621
622/* GSocket_SetNonBlocking:
623 * Sets the socket to non-blocking mode. This is useful if
624 * we don't want to wait.
625 */
626void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
627{
628 assert(socket != NULL);
629
630 socket->m_non_blocking = non_block;
631}
632
633/* GSocket_SetTimeout:
634 * Sets the timeout for blocking calls. Time is
635 * expressed in milliseconds.
636 */
637void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
638{
639 assert(socket != NULL);
640
641 socket->m_timeout = millisec;
642}
643
644/* GSocket_GetError:
645 * Returns the last error occured for this socket.
646 */
647GSocketError GSocket_GetError(GSocket *socket)
648{
649 assert(socket != NULL);
650
651 return socket->m_error;
652}
653
654/* Callbacks */
655
656/* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
657 * and LOST). The callbacks are called in the following situations:
658 *
659 * INPUT: There is at least one byte in the input buffer
660 * OUTPUT: The system is sure that the next write call will not block
661 * CONNECTION: Two cases are possible:
662 * Client socket -> the connection is established
663 * Server socket -> a client requests a connection
664 * LOST: The connection is lost
665 *
666 * An event is generated only once and its state is reseted when the
667 * relative IO call is requested.
668 * For example: INPUT -> GSocket_Read()
669 * CONNECTION -> GSocket_Accept()
670 */
671
672/* GSocket_SetCallback:
673 * Enables the callbacks specified by 'flags'. Note that 'flags'
674 * may be a combination of flags OR'ed toghether, so the same
675 * callback function can be made to accept different events.
676 * The callback function must have the following prototype:
677 *
678 * void function(GSocket *socket, GSocketEvent event, char *cdata)
679 */
680void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
681 GSocketCallback callback, char *cdata)
682{
683 int count;
684
685 assert(socket != NULL);
686
687 for (count = 0; count < GSOCK_MAX_EVENT; count++)
688 {
689 if ((flags & (1 << count)) != 0)
690 {
691 socket->m_cbacks[count] = callback;
692 socket->m_data[count] = cdata;
693 }
694 }
695}
696
697/* GSocket_UnsetCallback:
698 * Disables all callbacks specified by 'flags', which may be a
699 * combination of flags OR'ed toghether.
700 */
701void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
702{
703 int count;
704
705 assert(socket != NULL);
706
707 for (count = 0; count < GSOCK_MAX_EVENT; count++)
708 {
709 if ((flags & (1 << count)) != 0)
710 {
711 socket->m_cbacks[count] = NULL;
712 socket->m_data[count] = NULL;
713 }
714 }
715}
716
717#define CALL_CALLBACK(socket, event) { \
718 _GSocket_Disable(socket, event); \
719 if (socket->m_cbacks[event]) \
720 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
721}
722
723
724void _GSocket_Enable(GSocket *socket, GSocketEvent event)
725{
726 socket->m_detected &= ~(1 << event);
727 _GSocket_Install_Callback(socket, event);
728}
729
730void _GSocket_Disable(GSocket *socket, GSocketEvent event)
731{
732 socket->m_detected |= (1 << event);
733 _GSocket_Uninstall_Callback(socket, event);
734}
735
736/* _GSocket_Input_Timeout:
737 * For blocking sockets, wait until data is available or
738 * until timeout ellapses.
739 */
740GSocketError _GSocket_Input_Timeout(GSocket *socket)
741{
742 struct timeval tv;
743 fd_set readfds;
744
745 /* Linux select() will overwrite the struct on return */
746 tv.tv_sec = (socket->m_timeout / 1000);
747 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
748
749 if (!socket->m_non_blocking)
750 {
751 FD_ZERO(&readfds);
752 FD_SET(socket->m_fd, &readfds);
753 if (select(socket->m_fd + 1, &readfds, NULL, NULL, &tv) == 0)
754 {
755 socket->m_error = GSOCK_TIMEDOUT;
756 return GSOCK_TIMEDOUT;
757 }
758 }
759 return GSOCK_NOERROR;
760}
761
762/* _GSocket_Output_Timeout:
763 * For blocking sockets, wait until data can be sent without
764 * blocking or until timeout ellapses.
765 */
766GSocketError _GSocket_Output_Timeout(GSocket *socket)
767{
768 struct timeval tv;
769 fd_set writefds;
770
771 /* Linux select() will overwrite the struct on return */
772 tv.tv_sec = (socket->m_timeout / 1000);
773 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
774
775 if (!socket->m_non_blocking)
776 {
777 FD_ZERO(&writefds);
778 FD_SET(socket->m_fd, &writefds);
779 if (select(socket->m_fd + 1, NULL, &writefds, NULL, &tv) == 0)
780 {
781 socket->m_error = GSOCK_TIMEDOUT;
782 return GSOCK_TIMEDOUT;
783 }
784 }
785 return GSOCK_NOERROR;
786}
787
788int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
789{
790 int ret;
791
792 MASK_SIGNAL();
793 ret = recv(socket->m_fd, buffer, size, 0);
794 UNMASK_SIGNAL();
795
796 return ret;
797}
798
799int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
800{
801 struct sockaddr from;
802 SOCKLEN_T fromlen;
803 int ret;
804 GSocketError err;
805
806 fromlen = sizeof(from);
807
808 MASK_SIGNAL();
809 ret = recvfrom(socket->m_fd, buffer, size, 0, &from,
810 SOCK_LEN_TYP &fromlen);
811 UNMASK_SIGNAL();
812
813 if (ret == -1)
814 return -1;
815
816 /* Translate a system address into a GSocket address */
817 if (!socket->m_peer)
818 {
819 socket->m_peer = GAddress_new();
820 if (!socket->m_peer)
821 {
822 socket->m_error = GSOCK_MEMERR;
823 return -1;
824 }
825 }
826 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
827 if (err != GSOCK_NOERROR)
828 {
829 GAddress_destroy(socket->m_peer);
830 socket->m_peer = NULL;
831 socket->m_error = err;
832 return -1;
833 }
834
835 return ret;
836}
837
838int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
839{
840 int ret;
841 GSocketError err;
842
843 MASK_SIGNAL();
844 ret = send(socket->m_fd, buffer, size, 0);
845 UNMASK_SIGNAL();
846
847 return ret;
848}
849
850int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
851{
852 struct sockaddr *addr;
853 int len, ret;
854 GSocketError err;
855
856 if (!socket->m_peer) {
857 socket->m_error = GSOCK_INVADDR;
858 return -1;
859 }
860
861 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
862 if (err != GSOCK_NOERROR) {
863 socket->m_error = err;
864 return -1;
865 }
866
867 MASK_SIGNAL();
868 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
869 UNMASK_SIGNAL();
870
871 /* Frees memory allocated from _GAddress_translate_to */
872 free(addr);
873
874 return ret;
875}
876
877void _GSocket_Detected_Read(GSocket *socket)
878{
879 char c;
880 int ret;
881
882 if (socket->m_stream)
883 {
884 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
885
886 if (ret < 0 && socket->m_server)
887 {
888 CALL_CALLBACK(socket, GSOCK_CONNECTION);
889 return;
890 }
891
892 if (ret > 0)
893 {
894 CALL_CALLBACK(socket, GSOCK_INPUT);
895 }
896 else
897 {
898 CALL_CALLBACK(socket, GSOCK_LOST);
899 }
900 }
901}
902
903void _GSocket_Detected_Write(GSocket *socket)
904{
905 if (socket->m_establishing && !socket->m_server)
906 {
907 int error, len;
908
909 socket->m_establishing = FALSE;
910
911 len = sizeof(error);
912 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*) &error,
913 SOCK_LEN_TYP &len);
914
915 if (error)
916 {
917 CALL_CALLBACK(socket, GSOCK_LOST);
918 }
919 else
920 {
921 CALL_CALLBACK(socket, GSOCK_CONNECTION);
922 /* We have to fire this event by hand because CONNECTION (for clients)
923 * and OUTPUT are internally the same and we just disabled CONNECTION
924 * events with the above macro.
925 */
926 CALL_CALLBACK(socket, GSOCK_OUTPUT);
927 }
928 }
929 else
930 {
931 CALL_CALLBACK(socket, GSOCK_OUTPUT);
932 }
933}
934
935/*
936 * -------------------------------------------------------------------------
937 * GAddress
938 * -------------------------------------------------------------------------
939 */
940
941/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
942 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
943 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
944 */
945#define CHECK_ADDRESS(address, family, retval) \
946{ \
947 if (address->m_family == GSOCK_NOFAMILY) \
948 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
949 return address->m_error; \
950 }\
951 if (address->m_family != GSOCK_##family) {\
952 address->m_error = GSOCK_INVADDR; \
953 return retval; \
954 } \
955}
956
957GAddress *GAddress_new()
958{
959 GAddress *address;
960
961 address = (GAddress *)malloc(sizeof(GAddress));
962
963 if (address == NULL)
964 return NULL;
965
966 address->m_family = GSOCK_NOFAMILY;
967 address->m_addr = NULL;
968 address->m_len = 0;
969
970 return address;
971}
972
973GAddress *GAddress_copy(GAddress *address)
974{
975 GAddress *addr2;
976
977 assert(address != NULL);
978
979 addr2 = (GAddress *)malloc(sizeof(GAddress));
980
981 if (addr2 == NULL)
982 return NULL;
983
984 memcpy(addr2, address, sizeof(GAddress));
985
986 if (address->m_addr) {
987 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
988 if (addr2->m_addr == NULL) {
989 free(addr2);
990 return NULL;
991 }
992 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
993 }
994
995 return addr2;
996}
997
998void GAddress_destroy(GAddress *address)
999{
1000 assert(address != NULL);
1001
1002 free(address);
1003}
1004
1005void GAddress_SetFamily(GAddress *address, GAddressType type)
1006{
1007 assert(address != NULL);
1008
1009 address->m_family = type;
1010}
1011
1012GAddressType GAddress_GetFamily(GAddress *address)
1013{
1014 assert(address != NULL);
1015
1016 return address->m_family;
1017}
1018
1019GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
1020 address->m_realfamily = addr->sa_family;
1021 switch (addr->sa_family) {
1022 case AF_INET:
1023 address->m_family = GSOCK_INET;
1024 break;
1025 case AF_UNIX:
1026 address->m_family = GSOCK_UNIX;
1027 break;
1028#ifdef AF_INET6
1029 case AF_INET6:
1030 address->m_family = GSOCK_INET6;
1031 break;
1032#endif
1033 default:
1034 {
1035 address->m_error = GSOCK_INVOP;
1036 return GSOCK_INVOP;
1037 }
1038 }
1039
1040 if (address->m_addr)
1041 free(address->m_addr);
1042
1043 address->m_len = len;
1044 address->m_addr = (struct sockaddr *)malloc(len);
1045 if (address->m_addr == NULL) {
1046 address->m_error = GSOCK_MEMERR;
1047 return GSOCK_MEMERR;
1048 }
1049 memcpy(address->m_addr, addr, len);
1050
1051 return GSOCK_NOERROR;
1052}
1053
1054GSocketError _GAddress_translate_to(GAddress *address,
1055 struct sockaddr **addr, int *len)
1056{
1057 if (!address->m_addr) {
1058 address->m_error = GSOCK_INVADDR;
1059 return GSOCK_INVADDR;
1060 }
1061
1062 *len = address->m_len;
1063 *addr = (struct sockaddr *)malloc(address->m_len);
1064 if (*addr == NULL) {
1065 address->m_error = GSOCK_MEMERR;
1066 return GSOCK_MEMERR;
1067 }
1068
1069 memcpy(*addr, address->m_addr, address->m_len);
1070 return GSOCK_NOERROR;
1071}
1072
1073/*
1074 * -------------------------------------------------------------------------
1075 * Internet address family
1076 * -------------------------------------------------------------------------
1077 */
1078
1079GSocketError _GAddress_Init_INET(GAddress *address)
1080{
1081 address->m_len = sizeof(struct sockaddr_in);
1082 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1083 if (address->m_addr == NULL)
1084 {
1085 address->m_error = GSOCK_MEMERR;
1086 return GSOCK_MEMERR;
1087 }
1088
1089 address->m_family = GSOCK_INET;
1090 address->m_realfamily = PF_INET;
1091 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1092 /*
1093 INADDR_BROADCAST is identical to INADDR_NONE which is not defined
1094 on all unices. INADDR_BROADCAST should be fine to indicate an error.
1095 */
1096 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_BROADCAST;
1097
1098 return GSOCK_NOERROR;
1099}
1100
1101GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1102{
1103 struct hostent *he;
1104 struct in_addr *addr;
1105
1106 assert(address != NULL);
1107
1108 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1109
1110 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1111
1112 /* If it is a numeric host name, convert it now */
1113#if defined(HAVE_INET_ATON)
1114 if (inet_aton(hostname, addr) == 0)
1115 {
1116#elif defined(HAVE_INET_ADDR)
1117 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
1118 if ( (addr->s_addr = inet_addr(hostname)) == -1 )
1119 {
1120#else
1121 /* Use gethostbyname by default */
1122 if (1)
1123 {
1124#endif
1125 struct in_addr *array_addr;
1126
1127 /* It is a real name, we solve it */
1128 if ((he = gethostbyname(hostname)) == NULL)
1129 {
1130 address->m_error = GSOCK_NOHOST;
1131 return GSOCK_NOHOST;
1132 }
1133 array_addr = (struct in_addr *) *(he->h_addr_list);
1134 addr->s_addr = array_addr[0].s_addr;
1135 }
1136 return GSOCK_NOERROR;
1137}
1138
1139GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1140 unsigned long hostaddr)
1141{
1142 struct in_addr *addr;
1143
1144 assert(address != NULL);
1145
1146 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1147
1148 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1149 addr->s_addr = hostaddr;
1150
1151 return GSOCK_NOERROR;
1152}
1153
1154GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1155 const char *protocol)
1156{
1157 struct servent *se;
1158 struct sockaddr_in *addr;
1159
1160 assert(address != NULL);
1161 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1162
1163 if (!port)
1164 {
1165 address->m_error = GSOCK_INVPORT;
1166 return GSOCK_INVPORT;
1167 }
1168
1169 se = getservbyname(port, protocol);
1170 if (!se) {
1171 if (isdigit(port[0]))
1172 {
1173 int port_int;
1174
1175 port_int = atoi(port);
1176 addr = (struct sockaddr_in *)address->m_addr;
1177 addr->sin_port = htons(port_int);
1178 return GSOCK_NOERROR;
1179 }
1180
1181 address->m_error = GSOCK_INVPORT;
1182 return GSOCK_INVPORT;
1183 }
1184
1185 addr = (struct sockaddr_in *)address->m_addr;
1186 addr->sin_port = se->s_port;
1187
1188 return GSOCK_NOERROR;
1189}
1190
1191GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1192{
1193 struct sockaddr_in *addr;
1194
1195 assert(address != NULL);
1196 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1197
1198 addr = (struct sockaddr_in *)address->m_addr;
1199 addr->sin_port = htons(port);
1200
1201 return GSOCK_NOERROR;
1202}
1203
1204GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1205{
1206 struct hostent *he;
1207 char *addr_buf;
1208 struct sockaddr_in *addr;
1209
1210 assert(address != NULL);
1211 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1212
1213 addr = (struct sockaddr_in *)address->m_addr;
1214 addr_buf = (char *)&(addr->sin_addr);
1215
1216 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1217 if (he == NULL)
1218 {
1219 address->m_error = GSOCK_NOHOST;
1220 return GSOCK_NOHOST;
1221 }
1222
1223 strncpy(hostname, he->h_name, sbuf);
1224
1225 return GSOCK_NOERROR;
1226}
1227
1228unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1229{
1230 struct sockaddr_in *addr;
1231
1232 assert(address != NULL);
1233 CHECK_ADDRESS(address, INET, 0);
1234
1235 addr = (struct sockaddr_in *)address->m_addr;
1236
1237 return addr->sin_addr.s_addr;
1238}
1239
1240unsigned short GAddress_INET_GetPort(GAddress *address)
1241{
1242 struct sockaddr_in *addr;
1243
1244 assert(address != NULL);
1245 CHECK_ADDRESS(address, INET, 0);
1246
1247 addr = (struct sockaddr_in *)address->m_addr;
1248 return ntohs(addr->sin_port);
1249}
1250
1251/*
1252 * -------------------------------------------------------------------------
1253 * Unix address family
1254 * -------------------------------------------------------------------------
1255 */
1256
1257GSocketError _GAddress_Init_UNIX(GAddress *address)
1258{
1259 address->m_len = sizeof(struct sockaddr_un);
1260 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1261 if (address->m_addr == NULL)
1262 {
1263 address->m_error = GSOCK_MEMERR;
1264 return GSOCK_MEMERR;
1265 }
1266
1267 address->m_family = GSOCK_UNIX;
1268 address->m_realfamily = PF_UNIX;
1269 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1270 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1271
1272 return TRUE;
1273}
1274
1275GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1276{
1277 struct sockaddr_un *addr;
1278
1279 assert(address != NULL);
1280
1281 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1282
1283 addr = ((struct sockaddr_un *)address->m_addr);
1284 memcpy(addr->sun_path, path, strlen(path));
1285
1286 return GSOCK_NOERROR;
1287}
1288
1289GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1290{
1291 struct sockaddr_un *addr;
1292
1293 assert(address != NULL);
1294 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1295
1296 addr = (struct sockaddr_un *)address->m_addr;
1297
1298 strncpy(path, addr->sun_path, sbuf);
1299
1300 return GSOCK_NOERROR;
1301}
1302
1303#endif
1304 /* wxUSE_SOCKETS */