]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
Prototypes for some _internal_ functions had to be changed (API remains the same)
[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 /* GSocket_Select:
528 * Polls the socket to determine its status. This function will
529 * check for the events specified in the 'flags' parameter, and
530 * it will return a mask indicating which operations can be
531 * performed. This function won't block, regardless of the
532 * mode (blocking|nonblocking) of the socket.
533 */
534 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
535 {
536 fd_set readfds, writefds, exceptfds;
537 struct timeval tv;
538 GSocketEventFlags mask;
539 int error, len;
540
541 assert(socket != NULL);
542
543 if (socket->m_fd == -1)
544 {
545 socket->m_error = GSOCK_INVSOCK;
546 return FALSE;
547 }
548
549 FD_ZERO(&readfds);
550 FD_ZERO(&writefds);
551 FD_ZERO(&exceptfds);
552 FD_SET(socket->m_fd, &readfds);
553 FD_SET(socket->m_fd, &writefds);
554 FD_SET(socket->m_fd, &exceptfds);
555
556 tv.tv_sec = 0;
557 tv.tv_usec = 0;
558 select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv);
559
560 mask = 0;
561
562 /* If select() says that the socket is readable, then we have
563 * no way to distinguish if that means 'data available' (to
564 * recv) or 'incoming connection' (to accept). The same goes
565 * for writability: we cannot distinguish between 'you can
566 * send data' and 'connection request completed'. So we will
567 * assume the following: if the flag was set upon entry,
568 * that means that the event was possible.
569 */
570 if (FD_ISSET(socket->m_fd, &readfds))
571 {
572 mask |= (flags & GSOCK_CONNECTION_FLAG);
573 mask |= (flags & GSOCK_INPUT_FLAG);
574 }
575 if (FD_ISSET(socket->m_fd, &writefds))
576 {
577 if (socket->m_establishing)
578 {
579 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
580
581 if (error)
582 mask |= (flags & GSOCK_LOST_FLAG);
583 else
584 mask |= (flags & GSOCK_CONNECTION_FLAG);
585 }
586 mask |= (flags & GSOCK_OUTPUT_FLAG);
587 }
588 if (FD_ISSET(socket->m_fd, &exceptfds))
589 mask |= (flags & GSOCK_LOST_FLAG);
590
591 return mask;
592 }
593
594 /* Flags */
595
596 /*
597 GSocket_SetNonBlocking() puts the socket in non-blocking mode. This is useful
598 if we don't want to wait.
599 */
600 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
601 {
602 assert(socket != NULL);
603
604 socket->m_non_blocking = non_block;
605
606 if (socket->m_fd != -1)
607 ioctl(socket->m_fd, FIONBIO, &non_block);
608 }
609
610 /*
611 * GSocket_SetTimeout()
612 */
613
614 void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
615 {
616 assert(socket != NULL);
617
618 socket->m_timeout = millisec;
619 }
620
621 /*
622 GSocket_GetError() returns the last error occured on the socket stream.
623 */
624
625 GSocketError GSocket_GetError(GSocket *socket)
626 {
627 assert(socket != NULL);
628
629 return socket->m_error;
630 }
631
632 /* Callbacks */
633
634 /*
635 Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION)
636 INPUT: The function is called when there is at least a byte in the
637 input buffer
638 OUTPUT: The function is called when the system is sure the next write call
639 will not block
640 CONNECTION: Two cases is possible:
641 Client socket -> the connection is established
642 Server socket -> a client request a connection
643 LOST: the connection is lost
644
645 SetCallback accepts a combination of these flags so a same callback can
646 receive different events.
647
648 An event is generated only once and its state is reseted when the relative
649 IO call is requested.
650 For example: INPUT -> GSocket_Read()
651 CONNECTION -> GSocket_Accept()
652 */
653 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
654 GSocketCallback callback, char *cdata)
655 {
656 int count;
657
658 assert (socket != NULL);
659
660 for (count=0;count<GSOCK_MAX_EVENT;count++) {
661 /* We test each flag and, if it is enabled, we enable the corresponding
662 event */
663 if ((flags & (1 << count)) != 0) {
664 socket->m_cbacks[count] = callback;
665 socket->m_data[count] = cdata;
666 _GSocket_Enable(socket, count);
667 }
668 }
669 }
670
671 /*
672 UnsetCallback will disables all callbacks specified by "flags".
673 NOTE: "flags" may be a combination of flags
674 */
675 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
676 {
677 int count = 0;
678
679 assert(socket != NULL);
680
681 for (count=0;count<GSOCK_MAX_EVENT;count++) {
682 if ((flags & (1 << count)) != 0) {
683 _GSocket_Disable(socket, count);
684 socket->m_cbacks[count] = NULL;
685 }
686 }
687 }
688
689 #define CALL_CALLBACK(socket, event) \
690 if (socket->m_iocalls[event] && \
691 socket->m_cbacks[event]) {\
692 _GSocket_Disable(socket, event); \
693 socket->m_cbacks[event](socket, event, \
694 socket->m_data[event]); \
695 }
696
697 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
698 {
699 socket->m_iocalls[event] = TRUE;
700 if (socket->m_cbacks[event])
701 _GSocket_Install_Callback(socket, event);
702 }
703
704 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
705 {
706 socket->m_iocalls[event] = FALSE;
707 if (socket->m_cbacks[event])
708 _GSocket_Uninstall_Callback(socket, event);
709 }
710
711 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
712 {
713 int ret;
714
715 MASK_SIGNAL();
716 ENABLE_TIMEOUT(socket);
717 ret = recv(socket->m_fd, buffer, size, 0);
718 DISABLE_TIMEOUT(socket);
719 UNMASK_SIGNAL();
720
721 if (ret == -1 &&
722 errno != ETIMEDOUT && errno != EWOULDBLOCK && errno != EINTR) {
723 socket->m_error = GSOCK_IOERR;
724 return -1;
725 }
726 if (errno == EWOULDBLOCK) {
727 socket->m_error = GSOCK_WOULDBLOCK;
728 return -1;
729 }
730 if (errno == ETIMEDOUT || errno == EINTR) {
731 socket->m_error = GSOCK_TIMEDOUT;
732 return -1;
733 }
734 return ret;
735 }
736
737 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
738 {
739 struct sockaddr from;
740 SOCKLEN_T fromlen;
741 int ret;
742 GSocketError err;
743
744 fromlen = sizeof(from);
745
746 MASK_SIGNAL();
747 ENABLE_TIMEOUT(socket);
748 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
749 DISABLE_TIMEOUT(socket);
750 UNMASK_SIGNAL();
751 if (ret == -1 && errno != EWOULDBLOCK && errno != EINTR && errno != ETIMEDOUT) {
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
764 /* Translate a system address into a GSocket address */
765 if (!socket->m_peer) {
766 socket->m_peer = GAddress_new();
767 if (!socket->m_peer) {
768 socket->m_error = GSOCK_MEMERR;
769 return -1;
770 }
771 }
772 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
773 if (err != GSOCK_NOERROR) {
774 GAddress_destroy(socket->m_peer);
775 socket->m_peer = NULL;
776 socket->m_error = err;
777 return -1;
778 }
779
780 return ret;
781 }
782
783 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
784 {
785 int ret;
786 GSocketError err;
787
788 MASK_SIGNAL();
789 ENABLE_TIMEOUT(socket);
790 ret = send(socket->m_fd, buffer, size, 0);
791 DISABLE_TIMEOUT(socket);
792 UNMASK_SIGNAL();
793 if (ret == -1 && errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) {
794 socket->m_error = GSOCK_IOERR;
795 return -1;
796 }
797 if (errno == EWOULDBLOCK) {
798 socket->m_error = GSOCK_WOULDBLOCK;
799 return -1;
800 }
801 if (errno == ETIMEDOUT || errno == EINTR) {
802 socket->m_error = GSOCK_TIMEDOUT;
803 return -1;
804 }
805 return ret;
806 }
807
808 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
809 {
810 struct sockaddr *addr;
811 int len, ret;
812 GSocketError err;
813
814 if (!socket->m_peer) {
815 socket->m_error = GSOCK_INVADDR;
816 return -1;
817 }
818
819 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
820 if (err != GSOCK_NOERROR) {
821 socket->m_error = err;
822 return -1;
823 }
824
825 MASK_SIGNAL();
826 ENABLE_TIMEOUT(socket);
827 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
828 DISABLE_TIMEOUT(socket);
829 UNMASK_SIGNAL();
830
831 /* Frees memory allocated from _GAddress_translate_to */
832 free(addr);
833
834 if (ret == -1 && errno != EWOULDBLOCK) {
835 socket->m_error = GSOCK_IOERR;
836 return -1;
837 }
838 if (errno == EWOULDBLOCK) {
839 socket->m_error = GSOCK_WOULDBLOCK;
840 return -1;
841 }
842
843 return ret;
844 }
845
846 void _GSocket_Detected_Read(GSocket *socket)
847 {
848 char c;
849 int ret;
850
851 if (socket->m_stream) {
852 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
853
854 if (ret < 0 && socket->m_server) {
855 CALL_CALLBACK(socket, GSOCK_CONNECTION);
856 return;
857 }
858
859 if (ret > 0) {
860 CALL_CALLBACK(socket, GSOCK_INPUT);
861 } else {
862 CALL_CALLBACK(socket, GSOCK_LOST);
863 }
864 }
865 }
866
867 void _GSocket_Detected_Write(GSocket *socket)
868 {
869 if (socket->m_establishing) {
870 int error, len;
871
872 len = sizeof(error);
873
874 socket->m_establishing = FALSE;
875 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
876
877 if (error) {
878 socket->m_error = GSOCK_IOERR;
879 GSocket_Shutdown(socket);
880 } else
881 socket->m_error = GSOCK_NOERROR;
882
883 CALL_CALLBACK(socket, GSOCK_CONNECTION);
884 } else
885 CALL_CALLBACK(socket, GSOCK_OUTPUT);
886 }
887
888 /*
889 * -------------------------------------------------------------------------
890 * GAddress
891 * -------------------------------------------------------------------------
892 */
893
894 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
895 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
896 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
897 */
898 #define CHECK_ADDRESS(address, family, retval) \
899 { \
900 if (address->m_family == GSOCK_NOFAMILY) \
901 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
902 return address->m_error; \
903 }\
904 if (address->m_family != GSOCK_##family) {\
905 address->m_error = GSOCK_INVADDR; \
906 return retval; \
907 } \
908 }
909
910 GAddress *GAddress_new()
911 {
912 GAddress *address;
913
914 address = (GAddress *)malloc(sizeof(GAddress));
915
916 if (address == NULL)
917 return NULL;
918
919 address->m_family = GSOCK_NOFAMILY;
920 address->m_addr = NULL;
921 address->m_len = 0;
922
923 return address;
924 }
925
926 GAddress *GAddress_copy(GAddress *address)
927 {
928 GAddress *addr2;
929
930 assert(address != NULL);
931
932 addr2 = (GAddress *)malloc(sizeof(GAddress));
933
934 if (addr2 == NULL)
935 return NULL;
936
937 memcpy(addr2, address, sizeof(GAddress));
938
939 if (address->m_addr) {
940 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
941 if (addr2->m_addr == NULL) {
942 free(addr2);
943 return NULL;
944 }
945 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
946 }
947
948 return addr2;
949 }
950
951 void GAddress_destroy(GAddress *address)
952 {
953 assert(address != NULL);
954
955 free(address);
956 }
957
958 void GAddress_SetFamily(GAddress *address, GAddressType type)
959 {
960 assert(address != NULL);
961
962 address->m_family = type;
963 }
964
965 GAddressType GAddress_GetFamily(GAddress *address)
966 {
967 assert(address != NULL);
968
969 return address->m_family;
970 }
971
972 GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
973 address->m_realfamily = addr->sa_family;
974 switch (addr->sa_family) {
975 case AF_INET:
976 address->m_family = GSOCK_INET;
977 break;
978 case AF_UNIX:
979 address->m_family = GSOCK_UNIX;
980 break;
981 #ifdef AF_INET6
982 case AF_INET6:
983 address->m_family = GSOCK_INET6;
984 break;
985 #endif
986 default:
987 {
988 address->m_error = GSOCK_INVOP;
989 return GSOCK_INVOP;
990 }
991 }
992
993 if (address->m_addr)
994 free(address->m_addr);
995
996 address->m_len = len;
997 address->m_addr = (struct sockaddr *)malloc(len);
998 if (address->m_addr == NULL) {
999 address->m_error = GSOCK_MEMERR;
1000 return GSOCK_MEMERR;
1001 }
1002 memcpy(address->m_addr, addr, len);
1003
1004 return GSOCK_NOERROR;
1005 }
1006
1007 GSocketError _GAddress_translate_to(GAddress *address,
1008 struct sockaddr **addr, int *len)
1009 {
1010 if (!address->m_addr) {
1011 address->m_error = GSOCK_INVADDR;
1012 return GSOCK_INVADDR;
1013 }
1014
1015 *len = address->m_len;
1016 *addr = (struct sockaddr *)malloc(address->m_len);
1017 if (*addr == NULL) {
1018 address->m_error = GSOCK_MEMERR;
1019 return GSOCK_MEMERR;
1020 }
1021
1022 memcpy(*addr, address->m_addr, address->m_len);
1023 return GSOCK_NOERROR;
1024 }
1025
1026 /*
1027 * -------------------------------------------------------------------------
1028 * Internet address family
1029 * -------------------------------------------------------------------------
1030 */
1031
1032 GSocketError _GAddress_Init_INET(GAddress *address)
1033 {
1034 address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
1035 if (address->m_addr == NULL) {
1036 address->m_error = GSOCK_MEMERR;
1037 return GSOCK_MEMERR;
1038 }
1039
1040 address->m_len = sizeof(struct sockaddr_in);
1041
1042 address->m_family = GSOCK_INET;
1043 address->m_realfamily = PF_INET;
1044 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1045 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1046
1047 return GSOCK_NOERROR;
1048 }
1049
1050 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1051 {
1052 struct hostent *he;
1053 struct in_addr *addr;
1054
1055 assert(address != NULL);
1056
1057 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1058
1059 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1060
1061 /* If it is a numeric host name, convert it now */
1062 #if defined(HAVE_INET_ATON)
1063 if (inet_aton(hostname, addr) == 0) {
1064 #elif defined(HAVE_INET_ADDR)
1065 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
1066 if ( (addr->s_addr = inet_addr(hostname)) == -1 ) {
1067 #else
1068 /* Use gethostbyname by default */
1069 if (1) {
1070 #endif
1071 struct in_addr *array_addr;
1072
1073 /* It is a real name, we solve it */
1074 if ((he = gethostbyname(hostname)) == NULL) {
1075 address->m_error = GSOCK_NOHOST;
1076 return GSOCK_NOHOST;
1077 }
1078 array_addr = (struct in_addr *) *(he->h_addr_list);
1079 addr->s_addr = array_addr[0].s_addr;
1080 }
1081 return GSOCK_NOERROR;
1082 }
1083
1084 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1085 unsigned long hostaddr)
1086 {
1087 struct in_addr *addr;
1088
1089 assert(address != NULL);
1090
1091 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1092
1093 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1094 addr->s_addr = hostaddr;
1095
1096 return GSOCK_NOERROR;
1097 }
1098
1099 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1100 const char *protocol)
1101 {
1102 struct servent *se;
1103 struct sockaddr_in *addr;
1104
1105 assert(address != NULL);
1106 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1107
1108 if (!port) {
1109 address->m_error = GSOCK_INVPORT;
1110 return GSOCK_INVPORT;
1111 }
1112
1113 se = getservbyname(port, protocol);
1114 if (!se) {
1115 if (isdigit(port[0])) {
1116 int port_int;
1117
1118 port_int = atoi(port);
1119 addr = (struct sockaddr_in *)address->m_addr;
1120 addr->sin_port = htons(port_int);
1121 return GSOCK_NOERROR;
1122 }
1123
1124 address->m_error = GSOCK_INVPORT;
1125 return GSOCK_INVPORT;
1126 }
1127
1128 addr = (struct sockaddr_in *)address->m_addr;
1129 addr->sin_port = se->s_port;
1130
1131 return GSOCK_NOERROR;
1132 }
1133
1134 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1135 {
1136 struct sockaddr_in *addr;
1137
1138 assert(address != NULL);
1139 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1140
1141 addr = (struct sockaddr_in *)address->m_addr;
1142 addr->sin_port = htons(port);
1143
1144 return GSOCK_NOERROR;
1145 }
1146
1147 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1148 {
1149 struct hostent *he;
1150 char *addr_buf;
1151 struct sockaddr_in *addr;
1152
1153 assert(address != NULL);
1154 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1155
1156 addr = (struct sockaddr_in *)address->m_addr;
1157 addr_buf = (char *)&(addr->sin_addr);
1158
1159 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1160 if (he == NULL) {
1161 address->m_error = GSOCK_NOHOST;
1162 return GSOCK_NOHOST;
1163 }
1164
1165 strncpy(hostname, he->h_name, sbuf);
1166
1167 return GSOCK_NOERROR;
1168 }
1169
1170 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1171 {
1172 struct sockaddr_in *addr;
1173
1174 assert(address != NULL);
1175 CHECK_ADDRESS(address, INET, 0);
1176
1177 addr = (struct sockaddr_in *)address->m_addr;
1178
1179 return addr->sin_addr.s_addr;
1180 }
1181
1182 unsigned short GAddress_INET_GetPort(GAddress *address)
1183 {
1184 struct sockaddr_in *addr;
1185
1186 assert(address != NULL);
1187 CHECK_ADDRESS(address, INET, 0);
1188
1189 addr = (struct sockaddr_in *)address->m_addr;
1190 return ntohs(addr->sin_port);
1191 }
1192
1193 /*
1194 * -------------------------------------------------------------------------
1195 * Unix address family
1196 * -------------------------------------------------------------------------
1197 */
1198
1199 GSocketError _GAddress_Init_UNIX(GAddress *address)
1200 {
1201 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1202 if (address->m_addr == NULL) {
1203 address->m_error = GSOCK_MEMERR;
1204 return GSOCK_MEMERR;
1205 }
1206
1207 address->m_len = sizeof(struct sockaddr_un);
1208 address->m_family = GSOCK_UNIX;
1209 address->m_realfamily = PF_UNIX;
1210 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1211 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1212
1213 return TRUE;
1214 }
1215
1216 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1217 {
1218 struct sockaddr_un *addr;
1219
1220 assert(address != NULL);
1221
1222 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1223
1224 addr = ((struct sockaddr_un *)address->m_addr);
1225 memcpy(addr->sun_path, path, strlen(path));
1226
1227 return GSOCK_NOERROR;
1228 }
1229
1230 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1231 {
1232 struct sockaddr_un *addr;
1233
1234 assert(address != NULL);
1235 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1236
1237 addr = (struct sockaddr_un *)address->m_addr;
1238
1239 strncpy(path, addr->sun_path, sbuf);
1240
1241 return GSOCK_NOERROR;
1242 }
1243
1244 #endif
1245 /* wxUSE_SOCKETS */