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