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