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