]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
9a575b233c4d43d34fb2e79cfc4314a5e006e420
[wxWidgets.git] / src / unix / gsocket.c
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 "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 #if !defined(__LINUX__) && !defined(__FREEBSD__)
61 # define CAN_USE_TIMEOUT
62 #elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
63 # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1)
64 # define CAN_USE_TIMEOUT
65 # endif
66 #endif
67
68 /* Global initialisers */
69
70 bool GSocket_Init()
71 {
72 return TRUE;
73 }
74
75 void GSocket_Cleanup()
76 {
77 }
78
79 /* Constructors / Destructors */
80
81 GSocket *GSocket_new()
82 {
83 int i;
84 GSocket *socket;
85
86 socket = (GSocket *)malloc(sizeof(GSocket));
87
88 if (socket == NULL)
89 return NULL;
90
91 socket->m_fd = -1;
92 for (i=0;i<GSOCK_MAX_EVENT;i++) {
93 socket->m_fbacks[i] = NULL;
94 socket->m_iocalls[i] = FALSE;
95 }
96 socket->m_local = NULL;
97 socket->m_peer = NULL;
98 socket->m_error = GSOCK_NOERROR;
99 socket->m_server = FALSE;
100 socket->m_stream = TRUE;
101 socket->m_gui_dependent = NULL;
102 socket->m_blocking = FALSE;
103 socket->m_timeout = 10*60*1000;
104 /* 10 minutes * 60 sec * 1000 millisec */
105
106 /* We initialize the GUI specific entries here */
107 _GSocket_GUI_Init(socket);
108
109 return socket;
110 }
111
112 void GSocket_destroy(GSocket *socket)
113 {
114 assert(socket != NULL);
115
116 /* First, we check that the socket is really shutdowned */
117 if (socket->m_fd != -1)
118 GSocket_Shutdown(socket);
119
120 /* We destroy GUI specific variables */
121 _GSocket_GUI_Destroy(socket);
122
123 /* We destroy private addresses */
124 if (socket->m_local)
125 GAddress_destroy(socket->m_local);
126
127 if (socket->m_peer)
128 GAddress_destroy(socket->m_peer);
129
130 /* We destroy socket itself */
131 free(socket);
132 }
133
134 void GSocket_Shutdown(GSocket *socket)
135 {
136 int evt;
137
138 assert(socket != NULL);
139
140 /* If socket has been created, we shutdown it */
141 if (socket->m_fd != -1) {
142 /* Only oriented connection should be shutdowned */
143 if (socket->m_oriented)
144 shutdown(socket->m_fd, 2);
145 close(socket->m_fd);
146 socket->m_fd = -1;
147 }
148
149 /* We also disable GUI callbacks */
150 for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
151 _GSocket_Uninstall_Callback(socket, evt);
152 }
153
154 /* Address handling */
155
156 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
157 {
158 assert(socket != NULL);
159
160 if ((socket->m_fd != -1 && !socket->m_server)) {
161 socket->m_error = GSOCK_INVSOCK;
162 return GSOCK_INVSOCK;
163 }
164
165 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
166 socket->m_error = GSOCK_INVADDR;
167 return GSOCK_INVADDR;
168 }
169
170 if (socket->m_local)
171 GAddress_destroy(socket->m_local);
172
173 socket->m_local = GAddress_copy(address);
174
175 return GSOCK_NOERROR;
176 }
177
178 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
179 {
180 assert(socket != NULL);
181
182 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
183 socket->m_error = GSOCK_INVADDR;
184 return GSOCK_INVADDR;
185 }
186
187 if (socket->m_peer)
188 GAddress_destroy(socket->m_peer);
189
190 socket->m_peer = GAddress_copy(address);
191
192 return GSOCK_NOERROR;
193 }
194
195 GAddress *GSocket_GetLocal(GSocket *socket)
196 {
197 GAddress *address;
198 struct sockaddr addr;
199 SOCKLEN_T size;
200
201 assert(socket != NULL);
202
203 if (socket->m_local)
204 return GAddress_copy(socket->m_local);
205
206 if (socket->m_fd == -1) {
207 socket->m_error = GSOCK_INVSOCK;
208 return NULL;
209 }
210
211 size = sizeof(addr);
212
213 if (getsockname(socket->m_fd, &addr, &size) < 0) {
214 socket->m_error = GSOCK_IOERR;
215 return NULL;
216 }
217
218 address = GAddress_new();
219 if (address == NULL) {
220 socket->m_error = GSOCK_MEMERR;
221 return NULL;
222 }
223 if (_GAddress_translate_from(address, &addr, size) != GSOCK_NOERROR) {
224 GAddress_destroy(address);
225 return NULL;
226 }
227
228 return address;
229 }
230
231 GAddress *GSocket_GetPeer(GSocket *socket)
232 {
233 assert(socket != NULL);
234
235 if (socket->m_peer)
236 return GAddress_copy(socket->m_peer);
237
238 return NULL;
239 }
240
241 /* Server specific parts */
242
243 /*
244 GSocket_SetServer() setup the socket as a server. It uses the "Local" field
245 of GSocket. "Local" must be set by GSocket_SetLocal() before
246 GSocket_SetServer() is called. GSOCK_INVSOCK if socket has been initialized.
247 In case, you haven't yet defined the local address, it returns GSOCK_INVADDR.
248 In the other cases it returns GSOCK_IOERR.
249 */
250 GSocketError GSocket_SetServer(GSocket *sck)
251 {
252 int type;
253
254 assert(sck != NULL);
255
256 if (sck->m_fd != -1) {
257 sck->m_error = GSOCK_INVSOCK;
258 return GSOCK_INVSOCK;
259 }
260
261 if (!sck->m_local) {
262 sck->m_error = GSOCK_INVADDR;
263 return GSOCK_INVADDR;
264 }
265
266 /* We always have a stream here */
267 sck->m_stream = TRUE;
268 sck->m_server = TRUE;
269
270 /* Create the socket */
271 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
272
273 if (sck->m_fd == -1) {
274 sck->m_error = GSOCK_IOERR;
275 return GSOCK_IOERR;
276 }
277
278 /* Bind the socket to the LOCAL address */
279 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
280 close(sck->m_fd);
281 sck->m_fd = -1;
282 sck->m_error = GSOCK_IOERR;
283 return GSOCK_IOERR;
284 }
285
286 /* Enable listening up to 5 connections */
287 if (listen(sck->m_fd, 5) < 0) {
288 close(sck->m_fd);
289 sck->m_fd = -1;
290 sck->m_error = GSOCK_IOERR;
291 return GSOCK_IOERR;
292 }
293
294 GSocket_SetNonBlocking(sck, sck->m_blocking);
295 GSocket_SetTimeout(sck, sck->m_timeout);
296
297 return GSOCK_NOERROR;
298 }
299
300 /*
301 GSocket_WaitConnection() waits for an incoming client connection.
302 */
303 GSocket *GSocket_WaitConnection(GSocket *socket)
304 {
305 GSocket *connection;
306
307 assert(socket != NULL);
308
309 /* If the socket has already been created, we exit immediately */
310 if (socket->m_fd == -1 || !socket->m_server) {
311 socket->m_error = GSOCK_INVSOCK;
312 return NULL;
313 }
314
315 /* Reenable GSOCK_CONNECTION event */
316 _GSocket_Enable(socket, GSOCK_CONNECTION);
317
318 /* Create a GSocket object for the new connection */
319 connection = GSocket_new();
320
321 /* Accept the incoming connection */
322 connection->m_fd = accept(socket->m_fd, NULL, NULL);
323 if (connection->m_fd == -1) {
324 GSocket_destroy(connection);
325 socket->m_error = GSOCK_IOERR;
326 return NULL;
327 }
328
329 /* Initialize all fields */
330 connection->m_stream = TRUE;
331 connection->m_server = FALSE;
332 connection->m_oriented = TRUE;
333
334 return connection;
335 }
336
337 /* Non oriented connections */
338
339 GSocketError GSocket_SetNonOriented(GSocket *sck)
340 {
341 assert(sck != NULL);
342
343 if (sck->m_fd != -1) {
344 sck->m_error = GSOCK_INVSOCK;
345 return GSOCK_INVSOCK;
346 }
347
348 if (!sck->m_local) {
349 sck->m_error = GSOCK_INVADDR;
350 return GSOCK_INVADDR;
351 }
352
353 sck->m_stream = FALSE;
354 sck->m_server = FALSE;
355 sck->m_oriented = FALSE;
356
357 /* Create the socket */
358 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
359
360 /* Bind it to the LOCAL address */
361 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
362 close(sck->m_fd);
363 sck->m_fd = -1;
364 sck->m_error = GSOCK_IOERR;
365 return GSOCK_IOERR;
366 }
367
368 GSocket_SetNonBlocking(sck, sck->m_blocking);
369 GSocket_SetTimeout(sck, sck->m_timeout);
370
371 return GSOCK_NOERROR;
372 }
373
374 /* Client specific parts */
375
376 /*
377 GSocket_Connect() establishes a client connection to a server using the "Peer"
378 field of GSocket. "Peer" must be set by GSocket_SetPeer() before
379 GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
380 */
381 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
382 {
383 int type;
384
385 assert(sck != NULL);
386
387 if (sck->m_fd != -1) {
388 sck->m_error = GSOCK_INVSOCK;
389 return GSOCK_INVSOCK;
390 }
391
392 if (!sck->m_peer) {
393 sck->m_error = GSOCK_INVADDR;
394 return GSOCK_INVADDR;
395 }
396
397 /* Test whether we want the socket to be a stream (e.g. TCP) */
398 sck->m_stream = (stream == GSOCK_STREAMED);
399 sck->m_oriented = TRUE;
400
401 if (sck->m_stream)
402 type = SOCK_STREAM;
403 else
404 type = SOCK_DGRAM;
405
406 /* Create the socket */
407 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
408
409 if (sck->m_fd == -1) {
410 sck->m_error = GSOCK_IOERR;
411 return GSOCK_IOERR;
412 }
413
414 /* Connect it to the PEER address */
415 if (connect(sck->m_fd, sck->m_peer->m_addr,
416 sck->m_peer->m_len) != 0) {
417 close(sck->m_fd);
418 sck->m_fd = -1;
419 sck->m_error = GSOCK_IOERR;
420 return GSOCK_IOERR;
421 }
422
423 /* It is not a server */
424 sck->m_server = FALSE;
425
426 GSocket_SetNonBlocking(sck, sck->m_blocking);
427 GSocket_SetTimeout(sck, sck->m_timeout);
428
429 return GSOCK_NOERROR;
430 }
431
432 /* Generic IO */
433
434 /* Like recv(), send(), ... */
435 int GSocket_Read(GSocket *socket, char *buffer, int size)
436 {
437 assert(socket != NULL);
438
439 if (socket->m_fd == -1 || socket->m_server) {
440 socket->m_error = GSOCK_INVSOCK;
441 return -1;
442 }
443
444 /* Reenable GSOCK_INPUT event */
445 _GSocket_Enable(socket, GSOCK_INPUT);
446
447 if (socket->m_stream)
448 return _GSocket_Recv_Stream(socket, buffer, size);
449 else
450 return _GSocket_Recv_Dgram(socket, buffer, size);
451 }
452
453 int GSocket_Write(GSocket *socket, const char *buffer,
454 int size)
455 {
456 assert(socket != NULL);
457
458 if (socket->m_fd == -1 || socket->m_server) {
459 socket->m_error = GSOCK_INVSOCK;
460 return -1;
461 }
462
463 _GSocket_Enable(socket, GSOCK_OUTPUT);
464
465 if (socket->m_stream)
466 return _GSocket_Send_Stream(socket, buffer, size);
467 else
468 return _GSocket_Send_Dgram(socket, buffer, size);
469 }
470
471 bool GSocket_DataAvailable(GSocket *socket)
472 {
473 fd_set read_set;
474 struct timeval tv;
475
476 assert(socket != NULL);
477
478 if (socket->m_fd == -1 || socket->m_server) {
479 socket->m_error = GSOCK_INVSOCK;
480 return FALSE;
481 }
482
483 FD_ZERO(&read_set);
484 FD_SET(socket->m_fd, &read_set);
485
486 tv.tv_sec = 0;
487 tv.tv_usec = 0;
488
489 select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
490
491 return FD_ISSET(socket->m_fd, &read_set);
492 }
493
494 /* Flags */
495
496 /*
497 GSocket_SetNonBlocking() puts the socket in non-blocking mode. This is useful
498 if we don't want to wait.
499 */
500 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
501 {
502 assert(socket != NULL);
503
504 socket->m_blocking = non_block;
505
506 if (socket->m_fd != -1)
507 ioctl(socket->m_fd, FIONBIO, &non_block);
508 }
509
510 /*
511 * GSocket_SetTimeout()
512 */
513
514 void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
515 {
516 assert(socket != NULL);
517
518 socket->m_timeout = millisec;
519 /* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or
520 SO_RCVTIMEO. The man pages, that these flags should exist but
521 are read only. RR. */
522 /* OK, restrict this to GLIBC 2.1. GL. */
523 /* Anyway, they seem to pose problems: I need to know the socket level and
524 it varies (may be SOL_TCP, SOL_UDP, ...). I disables this and use the
525 other solution. GL. */
526 #if 0
527 #ifdef CAN_USE_TIMEOUT
528 if (socket->m_fd != -1) {
529 struct timeval tval;
530
531 tval.tv_sec = millisec / 1000;
532 tval.tv_usec = (millisec % 1000) * 1000;
533 setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
534 setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
535 }
536 #endif
537 #endif
538 }
539
540 /*
541 GSocket_GetError() returns the last error occured on the socket stream.
542 */
543
544 GSocketError GSocket_GetError(GSocket *socket)
545 {
546 assert(socket != NULL);
547
548 return socket->m_error;
549 }
550
551 /* Callbacks */
552
553 /*
554 Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
555 INPUT: The function is called when there is at least a byte in the
556 input buffer
557 OUTPUT: The function is called when the system is sure the next write call
558 will not block
559 CONNECTION: Two cases is possible:
560 Client socket -> the connection is established
561 Server socket -> a client request a connection
562 LOST: the connection is lost
563
564 SetCallback accepts a combination of these flags so a same callback can
565 receive different events.
566
567 An event is generated only once and its state is reseted when the relative
568 IO call is requested.
569 For example: INPUT -> GSocket_Read()
570 CONNECTION -> GSocket_Accept()
571 */
572 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
573 GSocketCallback fallback, char *cdata)
574 {
575 int count;
576
577 assert (socket != NULL);
578
579 for (count=0;count<GSOCK_MAX_EVENT;count++) {
580 /* We test each flag and, if it is enabled, we enable the corresponding
581 event */
582 if ((event & (1 << count)) != 0) {
583 socket->m_fbacks[count] = fallback;
584 socket->m_data[count] = cdata;
585 _GSocket_Enable(socket, count);
586 }
587 }
588 }
589
590 /*
591 UnsetCallback will disables all fallbacks specified by "event".
592 NOTE: event may be a combination of flags
593 */
594 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
595 {
596 int count = 0;
597
598 assert(socket != NULL);
599
600 for (count=0;count<GSOCK_MAX_EVENT;count++) {
601 if ((event & (1 << count)) != 0) {
602 _GSocket_Disable(socket, count);
603 socket->m_fbacks[count] = NULL;
604 }
605 }
606 }
607
608 #define CALL_FALLBACK(socket, event) \
609 if (socket->m_iocalls[event] && \
610 socket->m_fbacks[event]) {\
611 _GSocket_Disable(socket, event); \
612 socket->m_fbacks[event](socket, event, \
613 socket->m_data[event]); \
614 }
615
616 #define MASK_SIGNAL() \
617 { \
618 void (*old_handler)(int); \
619 \
620 old_handler = signal(SIGPIPE, SIG_IGN);
621
622 #define UNMASK_SIGNAL() \
623 signal(SIGPIPE, old_handler); \
624 }
625
626 #if 0
627 #ifndef CAN_USE_TIMEOUT
628
629 #define ENABLE_TIMEOUT(socket) \
630 { \
631 struct itimerval old_ival, new_ival; \
632 void (*old_timer_sig)(int); \
633 \
634 new_ival.it_interval.tv_sec = socket->m_timeout / 1000; \
635 new_ival.it_interval.tv_usec = (socket->m_timeout % 1000) * 1000; \
636 setitimer(ITIMER_REAL, &new_ival, &old_ival); \
637 old_timer_sig = signal(SIGALRM, SIG_DFL);
638
639 #define DISABLE_TIMEOUT(socket) \
640 signal(SIGALRM, old_timer_sig); \
641 setitimer(ITIMER_REAL, &old_ival, NULL); \
642 }
643
644 #else
645
646 #define ENABLE_TIMEOUT(s)
647 #define DISABLE_TIMEOUT(s)
648
649 #endif
650
651 #endif
652
653 /* Temporary */
654 #define ENABLE_TIMEOUT(s)
655 #define DISABLE_TIMEOUT(s)
656
657 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
658 {
659 socket->m_iocalls[event] = TRUE;
660 if (socket->m_fbacks[event])
661 _GSocket_Install_Callback(socket, event);
662 }
663
664 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
665 {
666 socket->m_iocalls[event] = FALSE;
667 if (socket->m_fbacks[event])
668 _GSocket_Uninstall_Callback(socket, event);
669 }
670
671 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
672 {
673 int ret;
674
675 MASK_SIGNAL();
676 ENABLE_TIMEOUT(socket);
677 ret = recv(socket->m_fd, buffer, size, 0);
678 DISABLE_TIMEOUT(socket);
679 UNMASK_SIGNAL();
680
681 if (ret == -1 && errno != EWOULDBLOCK) {
682 socket->m_error = GSOCK_IOERR;
683 return -1;
684 }
685 if (errno == EWOULDBLOCK) {
686 socket->m_error = GSOCK_TRYAGAIN;
687 return -1;
688 }
689 return ret;
690 }
691
692 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
693 {
694 struct sockaddr from;
695 SOCKLEN_T fromlen;
696 int ret;
697
698 fromlen = sizeof(from);
699
700 MASK_SIGNAL();
701 ENABLE_TIMEOUT(socket);
702 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
703 DISABLE_TIMEOUT(socket);
704 UNMASK_SIGNAL();
705 if (ret == -1 && errno != EWOULDBLOCK) {
706 socket->m_error = GSOCK_IOERR;
707 return -1;
708 }
709 if (errno == EWOULDBLOCK) {
710 socket->m_error = GSOCK_TRYAGAIN;
711 return -1;
712 }
713
714 /* Translate a system address into a GSocket address */
715 if (!socket->m_peer) {
716 socket->m_peer = GAddress_new();
717 if (!socket->m_peer) {
718 socket->m_error = GSOCK_MEMERR;
719 return -1;
720 }
721 }
722 if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR)
723 return -1;
724
725 return ret;
726 }
727
728 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
729 {
730 int ret;
731
732 MASK_SIGNAL();
733 ENABLE_TIMEOUT(socket);
734 ret = send(socket->m_fd, buffer, size, 0);
735 DISABLE_TIMEOUT(socket);
736 UNMASK_SIGNAL();
737 if (ret == -1 && errno != EWOULDBLOCK) {
738 socket->m_error = GSOCK_IOERR;
739 return -1;
740 }
741 if (errno == EWOULDBLOCK) {
742 socket->m_error = GSOCK_TRYAGAIN;
743 return -1;
744 }
745 return ret;
746 }
747
748 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
749 {
750 struct sockaddr *addr;
751 int len, ret;
752
753 if (!socket->m_peer) {
754 socket->m_error = GSOCK_INVADDR;
755 return -1;
756 }
757
758 if (_GAddress_translate_to(socket->m_peer, &addr, &len) != GSOCK_NOERROR) {
759 return -1;
760 }
761
762 MASK_SIGNAL();
763 ENABLE_TIMEOUT(socket);
764 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
765 DISABLE_TIMEOUT(socket);
766 UNMASK_SIGNAL();
767
768 /* Frees memory allocated from _GAddress_translate_to */
769 free(addr);
770
771 if (ret == -1 && errno != EWOULDBLOCK) {
772 socket->m_error = GSOCK_IOERR;
773 return -1;
774 }
775 if (errno == EWOULDBLOCK) {
776 socket->m_error = GSOCK_TRYAGAIN;
777 return -1;
778 }
779
780 return ret;
781 }
782
783 void _GSocket_Detected_Read(GSocket *socket)
784 {
785 char c;
786 int ret;
787
788 if (socket->m_stream) {
789 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
790
791 if (ret < 0 && socket->m_server) {
792 CALL_FALLBACK(socket, GSOCK_CONNECTION);
793 return;
794 }
795
796 if (ret > 0) {
797 CALL_FALLBACK(socket, GSOCK_INPUT);
798 } else {
799 CALL_FALLBACK(socket, GSOCK_LOST);
800 }
801 }
802 }
803
804 void _GSocket_Detected_Write(GSocket *socket)
805 {
806 CALL_FALLBACK(socket, GSOCK_OUTPUT);
807 }
808
809 #undef CALL_FALLBACK
810 #undef MASK_SIGNAL
811 #undef UNMASK_SIGNAL
812
813 /*
814 * -------------------------------------------------------------------------
815 * GAddress
816 * -------------------------------------------------------------------------
817 */
818
819 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
820 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
821 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
822 */
823 #define CHECK_ADDRESS(address, family, retval) \
824 { \
825 if (address->m_family == GSOCK_NOFAMILY) \
826 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
827 return address->m_error; \
828 }\
829 if (address->m_family != GSOCK_##family) {\
830 address->m_error = GSOCK_INVADDR; \
831 return retval; \
832 } \
833 }
834
835 GAddress *GAddress_new()
836 {
837 GAddress *address;
838
839 address = (GAddress *)malloc(sizeof(GAddress));
840
841 if (address == NULL)
842 return NULL;
843
844 address->m_family = GSOCK_NOFAMILY;
845 address->m_addr = NULL;
846 address->m_len = 0;
847
848 return address;
849 }
850
851 GAddress *GAddress_copy(GAddress *address)
852 {
853 GAddress *addr2;
854
855 assert(address != NULL);
856
857 addr2 = (GAddress *)malloc(sizeof(GAddress));
858
859 if (addr2 == NULL)
860 return NULL;
861
862 memcpy(addr2, address, sizeof(GAddress));
863
864 if (address->m_addr) {
865 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
866 if (addr2->m_addr == NULL) {
867 free(addr2);
868 return NULL;
869 }
870 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
871 }
872
873 return addr2;
874 }
875
876 void GAddress_destroy(GAddress *address)
877 {
878 assert(address != NULL);
879
880 free(address);
881 }
882
883 void GAddress_SetFamily(GAddress *address, GAddressType type)
884 {
885 assert(address != NULL);
886
887 address->m_family = type;
888 }
889
890 GAddressType GAddress_GetFamily(GAddress *address)
891 {
892 assert(address != NULL);
893
894 return address->m_family;
895 }
896
897 GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
898 address->m_realfamily = addr->sa_family;
899 switch (addr->sa_family) {
900 case AF_INET:
901 address->m_family = GSOCK_INET;
902 break;
903 case AF_UNIX:
904 address->m_family = GSOCK_UNIX;
905 break;
906 #ifdef AF_INET6
907 case AF_INET6:
908 address->m_family = GSOCK_INET6;
909 break;
910 #endif
911 default:
912 {
913 address->m_error = GSOCK_INVOP;
914 return GSOCK_INVOP;
915 }
916 }
917
918 if (address->m_addr)
919 free(address->m_addr);
920
921 address->m_len = len;
922 address->m_addr = (struct sockaddr *)malloc(len);
923 if (address->m_addr == NULL) {
924 address->m_error = GSOCK_MEMERR;
925 return GSOCK_MEMERR;
926 }
927 memcpy(address->m_addr, addr, len);
928
929 return GSOCK_NOERROR;
930 }
931
932 GSocketError _GAddress_translate_to(GAddress *address,
933 struct sockaddr **addr, int *len)
934 {
935 if (!address->m_addr) {
936 address->m_error = GSOCK_INVADDR;
937 return GSOCK_INVADDR;
938 }
939
940 *len = address->m_len;
941 *addr = (struct sockaddr *)malloc(address->m_len);
942 if (*addr == NULL) {
943 address->m_error = GSOCK_MEMERR;
944 return GSOCK_MEMERR;
945 }
946
947 memcpy(*addr, address->m_addr, address->m_len);
948 return GSOCK_NOERROR;
949 }
950
951 /*
952 * -------------------------------------------------------------------------
953 * Internet address family
954 * -------------------------------------------------------------------------
955 */
956
957 GSocketError _GAddress_Init_INET(GAddress *address)
958 {
959 address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
960 if (address->m_addr == NULL) {
961 address->m_error = GSOCK_MEMERR;
962 return GSOCK_MEMERR;
963 }
964
965 address->m_len = sizeof(struct sockaddr_in);
966
967 address->m_family = GSOCK_INET;
968 address->m_realfamily = PF_INET;
969 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
970 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
971
972 return GSOCK_NOERROR;
973 }
974
975 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
976 {
977 struct hostent *he;
978 struct in_addr *addr;
979
980 assert(address != NULL);
981
982 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
983
984 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
985
986 /* If it is a numeric host name, convert it now */
987 if (inet_aton(hostname, addr) == 0) {
988 struct in_addr *array_addr;
989
990 /* It is a real name, we solve it */
991 if ((he = gethostbyname(hostname)) == NULL) {
992 address->m_error = GSOCK_NOHOST;
993 return GSOCK_NOHOST;
994 }
995 array_addr = (struct in_addr *) *(he->h_addr_list);
996 addr->s_addr = array_addr[0].s_addr;
997 }
998 return GSOCK_NOERROR;
999 }
1000
1001 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1002 unsigned long hostaddr)
1003 {
1004 struct in_addr *addr;
1005
1006 assert(address != NULL);
1007
1008 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1009
1010 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1011 addr->s_addr = hostaddr;
1012
1013 return GSOCK_NOERROR;
1014 }
1015
1016 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1017 const char *protocol)
1018 {
1019 struct servent *se;
1020 struct sockaddr_in *addr;
1021
1022 assert(address != NULL);
1023 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1024
1025 if (!port) {
1026 address->m_error = GSOCK_INVPORT;
1027 return GSOCK_INVPORT;
1028 }
1029
1030 se = getservbyname(port, protocol);
1031 if (!se) {
1032 if (isdigit(port[0])) {
1033 int port_int;
1034
1035 port_int = atoi(port);
1036 addr = (struct sockaddr_in *)address->m_addr;
1037 addr->sin_port = htons(port_int);
1038 return GSOCK_NOERROR;
1039 }
1040
1041 address->m_error = GSOCK_INVPORT;
1042 return GSOCK_INVPORT;
1043 }
1044
1045 addr = (struct sockaddr_in *)address->m_addr;
1046 addr->sin_port = se->s_port;
1047
1048 return GSOCK_NOERROR;
1049 }
1050
1051 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1052 {
1053 struct sockaddr_in *addr;
1054
1055 assert(address != NULL);
1056 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1057
1058 addr = (struct sockaddr_in *)address->m_addr;
1059 addr->sin_port = htons(port);
1060
1061 return GSOCK_NOERROR;
1062 }
1063
1064 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1065 {
1066 struct hostent *he;
1067 char *addr_buf;
1068 struct sockaddr_in *addr;
1069
1070 assert(address != NULL);
1071 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1072
1073 addr = (struct sockaddr_in *)address->m_addr;
1074 addr_buf = (char *)&(addr->sin_addr);
1075
1076 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1077 if (he == NULL) {
1078 address->m_error = GSOCK_NOHOST;
1079 return GSOCK_NOHOST;
1080 }
1081
1082 strncpy(hostname, he->h_name, sbuf);
1083
1084 return GSOCK_NOERROR;
1085 }
1086
1087 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1088 {
1089 struct sockaddr_in *addr;
1090
1091 assert(address != NULL);
1092 CHECK_ADDRESS(address, INET, 0);
1093
1094 addr = (struct sockaddr_in *)address->m_addr;
1095
1096 return addr->sin_addr.s_addr;
1097 }
1098
1099 unsigned short GAddress_INET_GetPort(GAddress *address)
1100 {
1101 struct sockaddr_in *addr;
1102
1103 assert(address != NULL);
1104 CHECK_ADDRESS(address, INET, 0);
1105
1106 addr = (struct sockaddr_in *)address->m_addr;
1107 return ntohs(addr->sin_port);
1108 }
1109
1110 /*
1111 * -------------------------------------------------------------------------
1112 * Unix address family
1113 * -------------------------------------------------------------------------
1114 */
1115
1116 GSocketError _GAddress_Init_UNIX(GAddress *address)
1117 {
1118 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1119 if (address->m_addr == NULL) {
1120 address->m_error = GSOCK_MEMERR;
1121 return GSOCK_MEMERR;
1122 }
1123
1124 address->m_len = sizeof(struct sockaddr_un);
1125 address->m_family = GSOCK_UNIX;
1126 address->m_realfamily = PF_UNIX;
1127 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1128 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1129
1130 return TRUE;
1131 }
1132
1133 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1134 {
1135 struct sockaddr_un *addr;
1136
1137 assert(address != NULL);
1138
1139 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1140
1141 addr = ((struct sockaddr_un *)address->m_addr);
1142 memcpy(addr->sun_path, path, strlen(path));
1143
1144 return GSOCK_NOERROR;
1145 }
1146
1147 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1148 {
1149 struct sockaddr_un *addr;
1150
1151 assert(address != NULL);
1152 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1153
1154 addr = (struct sockaddr_un *)address->m_addr;
1155
1156 strncpy(path, addr->sun_path, sbuf);
1157
1158 return GSOCK_NOERROR;
1159 }
1160
1161 #endif
1162 /* wxUSE_SOCKETS */