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