]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
compilation error corrected
[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 /* GSocket_SetServer:
266 * Sets up the socket as a server. It uses the "Local" field of GSocket.
267 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
268 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
269 * been initialized, GSOCK_INVADDR if the local address has not been
270 * defined and GSOCK_IOERR for other internal errors.
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_Configure_Callbacks(sck);
317 GSocket_SetNonBlocking(sck, sck->m_non_blocking);
318 GSocket_SetTimeout(sck, sck->m_timeout);
319
320 return GSOCK_NOERROR;
321 }
322
323 /* GSocket_WaitConnection:
324 * Waits for an incoming client connection.
325 */
326 GSocket *GSocket_WaitConnection(GSocket *socket)
327 {
328 GSocket *connection;
329
330 assert(socket != NULL);
331
332 /* If the socket has already been created, we exit immediately */
333 if (socket->m_fd == -1 || !socket->m_server) {
334 socket->m_error = GSOCK_INVSOCK;
335 return NULL;
336 }
337
338 /* Reenable GSOCK_CONNECTION event */
339 _GSocket_Enable(socket, GSOCK_CONNECTION);
340
341 /* Create a GSocket object for the new connection */
342 connection = GSocket_new();
343 if (!connection) {
344 connection->m_error = GSOCK_MEMERR;
345 return NULL;
346 }
347
348 /* Accept the incoming connection */
349 ENABLE_TIMEOUT(connection);
350 connection->m_fd = accept(socket->m_fd, NULL, NULL);
351 DISABLE_TIMEOUT(connection);
352 if (connection->m_fd == -1) {
353 GSocket_destroy(connection);
354 switch(errno) {
355 case EINTR:
356 case ETIMEDOUT:
357 connection->m_error = GSOCK_TIMEDOUT;
358 break;
359 case EWOULDBLOCK:
360 connection->m_error = GSOCK_WOULDBLOCK;
361 break;
362 default:
363 connection->m_error = GSOCK_IOERR;
364 break;
365 }
366 return NULL;
367 }
368
369 /* Initialize all fields */
370 connection->m_stream = TRUE;
371 connection->m_server = FALSE;
372 connection->m_oriented = TRUE;
373
374 _GSocket_Configure_Callbacks(connection);
375 GSocket_SetNonBlocking(connection, connection->m_non_blocking);
376 GSocket_SetTimeout(connection, connection->m_timeout);
377
378 return connection;
379 }
380
381 /* Non oriented connections */
382
383 GSocketError GSocket_SetNonOriented(GSocket *sck)
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_local) {
393 sck->m_error = GSOCK_INVADDR;
394 return GSOCK_INVADDR;
395 }
396
397 sck->m_stream = FALSE;
398 sck->m_server = FALSE;
399 sck->m_oriented = FALSE;
400
401 /* Create the socket */
402 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
403
404 if (sck->m_fd < 0) {
405 sck->m_error = GSOCK_IOERR;
406 return GSOCK_IOERR;
407 }
408
409 /* Bind it to the LOCAL address */
410 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
411 close(sck->m_fd);
412 sck->m_fd = -1;
413 sck->m_error = GSOCK_IOERR;
414 return GSOCK_IOERR;
415 }
416
417 _GSocket_Configure_Callbacks(sck);
418 GSocket_SetNonBlocking(sck, sck->m_non_blocking);
419 GSocket_SetTimeout(sck, sck->m_timeout);
420
421 return GSOCK_NOERROR;
422 }
423
424 /* Client specific parts */
425
426 /* GSocket_Connect:
427 * Establishes a client connection to a server using the "Peer"
428 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
429 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
430 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
431 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
432 * the connection request can be completed later. Use GSocket_Select()
433 * to check or wait for a GSOCK_CONNECTION event.
434 */
435 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
436 {
437 int type, err;
438
439 assert(sck != NULL);
440
441 if (sck->m_fd != -1) {
442 sck->m_error = GSOCK_INVSOCK;
443 return GSOCK_INVSOCK;
444 }
445
446 if (!sck->m_peer) {
447 sck->m_error = GSOCK_INVADDR;
448 return GSOCK_INVADDR;
449 }
450
451 /* Test whether we want the socket to be a stream (e.g. TCP) */
452 sck->m_stream = (stream == GSOCK_STREAMED);
453 sck->m_oriented = TRUE;
454
455 if (sck->m_stream)
456 type = SOCK_STREAM;
457 else
458 type = SOCK_DGRAM;
459
460 /* Create the socket */
461 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
462
463 if (sck->m_fd == -1) {
464 sck->m_error = GSOCK_IOERR;
465 return GSOCK_IOERR;
466 }
467
468 _GSocket_Configure_Callbacks(sck);
469 GSocket_SetNonBlocking(sck, sck->m_non_blocking);
470 GSocket_SetTimeout(sck, sck->m_timeout);
471
472 /* Connect it to the PEER address */
473 ENABLE_TIMEOUT(sck);
474 err = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
475 DISABLE_TIMEOUT(sck);
476
477 if (err != 0 && errno != EINPROGRESS) {
478 close(sck->m_fd);
479 sck->m_fd = -1;
480 switch (errno) {
481 case EINTR:
482 case ETIMEDOUT:
483 sck->m_error = GSOCK_TIMEDOUT;
484 break;
485 default:
486 sck->m_error = GSOCK_IOERR;
487 break;
488 }
489 return GSOCK_IOERR;
490 }
491
492 /* It is not a server */
493 sck->m_server = FALSE;
494 sck->m_establishing = (errno == EINPROGRESS);
495
496 return (sck->m_establishing) ? GSOCK_WOULDBLOCK : GSOCK_NOERROR;
497 }
498
499 /* Generic IO */
500
501 /* Like recv(), send(), ... */
502 int GSocket_Read(GSocket *socket, char *buffer, int size)
503 {
504 assert(socket != NULL);
505
506 if (socket->m_fd == -1 || socket->m_server) {
507 socket->m_error = GSOCK_INVSOCK;
508 return -1;
509 }
510
511 /* Reenable GSOCK_INPUT event */
512 _GSocket_Enable(socket, GSOCK_INPUT);
513
514 if (socket->m_stream)
515 return _GSocket_Recv_Stream(socket, buffer, size);
516 else
517 return _GSocket_Recv_Dgram(socket, buffer, size);
518 }
519
520 int GSocket_Write(GSocket *socket, const char *buffer,
521 int size)
522 {
523 assert(socket != NULL);
524
525 if (socket->m_fd == -1 || socket->m_server) {
526 socket->m_error = GSOCK_INVSOCK;
527 return -1;
528 }
529
530 _GSocket_Enable(socket, GSOCK_OUTPUT);
531
532 if (socket->m_stream)
533 return _GSocket_Send_Stream(socket, buffer, size);
534 else
535 return _GSocket_Send_Dgram(socket, buffer, size);
536 }
537
538 /* GSocket_Select:
539 * Polls the socket to determine its status. This function will
540 * check for the events specified in the 'flags' parameter, and
541 * it will return a mask indicating which operations can be
542 * performed. This function won't block, regardless of the
543 * mode (blocking|nonblocking) of the socket.
544 */
545 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
546 {
547 fd_set readfds, writefds, exceptfds;
548 struct timeval tv;
549 GSocketEventFlags mask;
550 int error, len;
551
552 assert(socket != NULL);
553
554 if (socket->m_fd == -1)
555 {
556 socket->m_error = GSOCK_INVSOCK;
557 return FALSE;
558 }
559
560 FD_ZERO(&readfds);
561 FD_ZERO(&writefds);
562 FD_ZERO(&exceptfds);
563 FD_SET(socket->m_fd, &readfds);
564 FD_SET(socket->m_fd, &writefds);
565 FD_SET(socket->m_fd, &exceptfds);
566
567 tv.tv_sec = 0;
568 tv.tv_usec = 0;
569 select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv);
570
571 mask = 0;
572
573 /* If select() says that the socket is readable, then we have
574 * no way to distinguish if that means 'data available' (to
575 * recv) or 'incoming connection' (to accept). The same goes
576 * for writability: we cannot distinguish between 'you can
577 * send data' and 'connection request completed'. So we will
578 * assume the following: if the flag was set upon entry,
579 * that means that the event was possible.
580 */
581 if (FD_ISSET(socket->m_fd, &readfds))
582 {
583 mask |= (flags & GSOCK_CONNECTION_FLAG);
584 mask |= (flags & GSOCK_INPUT_FLAG);
585 }
586 if (FD_ISSET(socket->m_fd, &writefds))
587 {
588 if (socket->m_establishing)
589 {
590 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
591
592 if (error)
593 mask |= (flags & GSOCK_LOST_FLAG);
594 else
595 mask |= (flags & GSOCK_CONNECTION_FLAG);
596 }
597 mask |= (flags & GSOCK_OUTPUT_FLAG);
598 }
599 if (FD_ISSET(socket->m_fd, &exceptfds))
600 mask |= (flags & GSOCK_LOST_FLAG);
601
602 return mask;
603 }
604
605 /* Flags */
606
607 /* GSocket_SetNonBlocking:
608 * Sets the socket to non-blocking mode. This is useful if
609 * we don't want to wait.
610 */
611 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
612 {
613 assert(socket != NULL);
614
615 socket->m_non_blocking = non_block;
616
617 if (socket->m_fd != -1)
618 ioctl(socket->m_fd, FIONBIO, &non_block);
619 }
620
621 /* GSocket_SetTimeout:
622 * Sets the timeout for blocking calls. Time is
623 * expressed in milliseconds.
624 */
625 void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
626 {
627 assert(socket != NULL);
628
629 socket->m_timeout = millisec;
630 }
631
632 /* GSocket_GetError:
633 * Returns the last error occured for this socket.
634 */
635 GSocketError GSocket_GetError(GSocket *socket)
636 {
637 assert(socket != NULL);
638
639 return socket->m_error;
640 }
641
642 /* Callbacks */
643
644 /* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
645 * and LOST). The callbacks are called in the following situations:
646 *
647 * INPUT: There is at least one byte in the input buffer
648 * OUTPUT: The system is sure that the next write call will not block
649 * CONNECTION: Two cases are possible:
650 * Client socket -> the connection is established
651 * Server socket -> a client requests a connection
652 * LOST: The connection is lost
653 *
654 * An event is generated only once and its state is reseted when the
655 * relative IO call is requested.
656 * For example: INPUT -> GSocket_Read()
657 * CONNECTION -> GSocket_Accept()
658 */
659
660 /* GSocket_SetCallback:
661 * Enables the callbacks specified by 'flags'. Note that 'flags'
662 * may be a combination of flags OR'ed toghether, so the same
663 * callback function can be made to accept different events.
664 * The callback function must have the following prototype:
665 *
666 * void function(GSocket *socket, GSocketEvent event, char *cdata)
667 */
668 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
669 GSocketCallback callback, char *cdata)
670 {
671 int count;
672
673 assert (socket != NULL);
674
675 for (count=0;count<GSOCK_MAX_EVENT;count++) {
676 /* We test each flag and, if it is enabled, we enable the corresponding
677 event */
678 if ((flags & (1 << count)) != 0) {
679 socket->m_cbacks[count] = callback;
680 socket->m_data[count] = cdata;
681 }
682 }
683 _GSocket_Configure_Callbacks(socket);
684 }
685
686 /* GSocket_UnsetCallback:
687 * Disables all callbacks specified by 'flags', which may be a
688 * combination of flags OR'ed toghether.
689 */
690 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
691 {
692 int count;
693
694 assert(socket != NULL);
695
696 for (count=0;count<GSOCK_MAX_EVENT;count++) {
697 if ((flags & (1 << count)) != 0) {
698 socket->m_cbacks[count] = NULL;
699 }
700 }
701 _GSocket_Configure_Callbacks(socket);
702 }
703
704 #define CALL_CALLBACK(socket, event) \
705 if (socket->m_iocalls[event] && socket->m_cbacks[event]) { \
706 _GSocket_Disable(socket, event); \
707 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
708 }
709
710 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
711 {
712 socket->m_iocalls[event] = TRUE;
713 if (socket->m_cbacks[event])
714 _GSocket_Install_Callback(socket, event);
715 }
716
717 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
718 {
719 socket->m_iocalls[event] = FALSE;
720 if (socket->m_cbacks[event])
721 _GSocket_Uninstall_Callback(socket, event);
722 }
723
724 void _GSocket_Configure_Callbacks(GSocket *socket)
725 {
726 int count;
727 for (count=0;count<GSOCK_MAX_EVENT;count++) {
728 if ((socket->m_cbacks[count]) != NULL) {
729 _GSocket_Enable(socket, count);
730 } else {
731 _GSocket_Disable(socket, count);
732 }
733 }
734 }
735
736 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
737 {
738 int ret;
739
740 MASK_SIGNAL();
741 ENABLE_TIMEOUT(socket);
742 ret = recv(socket->m_fd, buffer, size, 0);
743 DISABLE_TIMEOUT(socket);
744 UNMASK_SIGNAL();
745
746 if (ret == -1 &&
747 errno != ETIMEDOUT && errno != EWOULDBLOCK && errno != EINTR) {
748 socket->m_error = GSOCK_IOERR;
749 return -1;
750 }
751 if (errno == EWOULDBLOCK) {
752 socket->m_error = GSOCK_WOULDBLOCK;
753 return -1;
754 }
755 if (errno == ETIMEDOUT || errno == EINTR) {
756 socket->m_error = GSOCK_TIMEDOUT;
757 return -1;
758 }
759 return ret;
760 }
761
762 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
763 {
764 struct sockaddr from;
765 SOCKLEN_T fromlen;
766 int ret;
767 GSocketError err;
768
769 fromlen = sizeof(from);
770
771 MASK_SIGNAL();
772 ENABLE_TIMEOUT(socket);
773 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
774 DISABLE_TIMEOUT(socket);
775 UNMASK_SIGNAL();
776 if (ret == -1 && errno != EWOULDBLOCK && errno != EINTR && errno != ETIMEDOUT) {
777 socket->m_error = GSOCK_IOERR;
778 return -1;
779 }
780 if (errno == EWOULDBLOCK) {
781 socket->m_error = GSOCK_WOULDBLOCK;
782 return -1;
783 }
784 if (errno == ETIMEDOUT || errno == EINTR) {
785 socket->m_error = GSOCK_TIMEDOUT;
786 return -1;
787 }
788
789 /* Translate a system address into a GSocket address */
790 if (!socket->m_peer) {
791 socket->m_peer = GAddress_new();
792 if (!socket->m_peer) {
793 socket->m_error = GSOCK_MEMERR;
794 return -1;
795 }
796 }
797 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
798 if (err != GSOCK_NOERROR) {
799 GAddress_destroy(socket->m_peer);
800 socket->m_peer = NULL;
801 socket->m_error = err;
802 return -1;
803 }
804
805 return ret;
806 }
807
808 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
809 {
810 int ret;
811 GSocketError err;
812
813 MASK_SIGNAL();
814 ENABLE_TIMEOUT(socket);
815 ret = send(socket->m_fd, buffer, size, 0);
816 DISABLE_TIMEOUT(socket);
817 UNMASK_SIGNAL();
818 if (ret == -1 && errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) {
819 socket->m_error = GSOCK_IOERR;
820 return -1;
821 }
822 if (errno == EWOULDBLOCK) {
823 socket->m_error = GSOCK_WOULDBLOCK;
824 return -1;
825 }
826 if (errno == ETIMEDOUT || errno == EINTR) {
827 socket->m_error = GSOCK_TIMEDOUT;
828 return -1;
829 }
830 return ret;
831 }
832
833 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
834 {
835 struct sockaddr *addr;
836 int len, ret;
837 GSocketError err;
838
839 if (!socket->m_peer) {
840 socket->m_error = GSOCK_INVADDR;
841 return -1;
842 }
843
844 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
845 if (err != GSOCK_NOERROR) {
846 socket->m_error = err;
847 return -1;
848 }
849
850 MASK_SIGNAL();
851 ENABLE_TIMEOUT(socket);
852 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
853 DISABLE_TIMEOUT(socket);
854 UNMASK_SIGNAL();
855
856 /* Frees memory allocated from _GAddress_translate_to */
857 free(addr);
858
859 if (ret == -1 && errno != EWOULDBLOCK) {
860 socket->m_error = GSOCK_IOERR;
861 return -1;
862 }
863 if (errno == EWOULDBLOCK) {
864 socket->m_error = GSOCK_WOULDBLOCK;
865 return -1;
866 }
867
868 return ret;
869 }
870
871 void _GSocket_Detected_Read(GSocket *socket)
872 {
873 char c;
874 int ret;
875
876 if (socket->m_stream) {
877 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
878
879 if (ret < 0 && socket->m_server) {
880 CALL_CALLBACK(socket, GSOCK_CONNECTION);
881 return;
882 }
883
884 if (ret > 0) {
885 CALL_CALLBACK(socket, GSOCK_INPUT);
886 } else {
887 CALL_CALLBACK(socket, GSOCK_LOST);
888 }
889 }
890 }
891
892 void _GSocket_Detected_Write(GSocket *socket)
893 {
894 if (socket->m_establishing) {
895 int error, len;
896
897 len = sizeof(error);
898
899 socket->m_establishing = FALSE;
900 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len);
901
902 if (error) {
903 socket->m_error = GSOCK_IOERR;
904 GSocket_Shutdown(socket);
905 } else
906 socket->m_error = GSOCK_NOERROR;
907
908 CALL_CALLBACK(socket, GSOCK_CONNECTION);
909 } else
910 CALL_CALLBACK(socket, GSOCK_OUTPUT);
911 }
912
913 /*
914 * -------------------------------------------------------------------------
915 * GAddress
916 * -------------------------------------------------------------------------
917 */
918
919 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
920 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
921 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
922 */
923 #define CHECK_ADDRESS(address, family, retval) \
924 { \
925 if (address->m_family == GSOCK_NOFAMILY) \
926 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
927 return address->m_error; \
928 }\
929 if (address->m_family != GSOCK_##family) {\
930 address->m_error = GSOCK_INVADDR; \
931 return retval; \
932 } \
933 }
934
935 GAddress *GAddress_new()
936 {
937 GAddress *address;
938
939 address = (GAddress *)malloc(sizeof(GAddress));
940
941 if (address == NULL)
942 return NULL;
943
944 address->m_family = GSOCK_NOFAMILY;
945 address->m_addr = NULL;
946 address->m_len = 0;
947
948 return address;
949 }
950
951 GAddress *GAddress_copy(GAddress *address)
952 {
953 GAddress *addr2;
954
955 assert(address != NULL);
956
957 addr2 = (GAddress *)malloc(sizeof(GAddress));
958
959 if (addr2 == NULL)
960 return NULL;
961
962 memcpy(addr2, address, sizeof(GAddress));
963
964 if (address->m_addr) {
965 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
966 if (addr2->m_addr == NULL) {
967 free(addr2);
968 return NULL;
969 }
970 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
971 }
972
973 return addr2;
974 }
975
976 void GAddress_destroy(GAddress *address)
977 {
978 assert(address != NULL);
979
980 free(address);
981 }
982
983 void GAddress_SetFamily(GAddress *address, GAddressType type)
984 {
985 assert(address != NULL);
986
987 address->m_family = type;
988 }
989
990 GAddressType GAddress_GetFamily(GAddress *address)
991 {
992 assert(address != NULL);
993
994 return address->m_family;
995 }
996
997 GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
998 address->m_realfamily = addr->sa_family;
999 switch (addr->sa_family) {
1000 case AF_INET:
1001 address->m_family = GSOCK_INET;
1002 break;
1003 case AF_UNIX:
1004 address->m_family = GSOCK_UNIX;
1005 break;
1006 #ifdef AF_INET6
1007 case AF_INET6:
1008 address->m_family = GSOCK_INET6;
1009 break;
1010 #endif
1011 default:
1012 {
1013 address->m_error = GSOCK_INVOP;
1014 return GSOCK_INVOP;
1015 }
1016 }
1017
1018 if (address->m_addr)
1019 free(address->m_addr);
1020
1021 address->m_len = len;
1022 address->m_addr = (struct sockaddr *)malloc(len);
1023 if (address->m_addr == NULL) {
1024 address->m_error = GSOCK_MEMERR;
1025 return GSOCK_MEMERR;
1026 }
1027 memcpy(address->m_addr, addr, len);
1028
1029 return GSOCK_NOERROR;
1030 }
1031
1032 GSocketError _GAddress_translate_to(GAddress *address,
1033 struct sockaddr **addr, int *len)
1034 {
1035 if (!address->m_addr) {
1036 address->m_error = GSOCK_INVADDR;
1037 return GSOCK_INVADDR;
1038 }
1039
1040 *len = address->m_len;
1041 *addr = (struct sockaddr *)malloc(address->m_len);
1042 if (*addr == NULL) {
1043 address->m_error = GSOCK_MEMERR;
1044 return GSOCK_MEMERR;
1045 }
1046
1047 memcpy(*addr, address->m_addr, address->m_len);
1048 return GSOCK_NOERROR;
1049 }
1050
1051 /*
1052 * -------------------------------------------------------------------------
1053 * Internet address family
1054 * -------------------------------------------------------------------------
1055 */
1056
1057 GSocketError _GAddress_Init_INET(GAddress *address)
1058 {
1059 address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
1060 if (address->m_addr == NULL) {
1061 address->m_error = GSOCK_MEMERR;
1062 return GSOCK_MEMERR;
1063 }
1064
1065 address->m_len = sizeof(struct sockaddr_in);
1066
1067 address->m_family = GSOCK_INET;
1068 address->m_realfamily = PF_INET;
1069 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1070 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1071
1072 return GSOCK_NOERROR;
1073 }
1074
1075 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1076 {
1077 struct hostent *he;
1078 struct in_addr *addr;
1079
1080 assert(address != NULL);
1081
1082 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1083
1084 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1085
1086 /* If it is a numeric host name, convert it now */
1087 #if defined(HAVE_INET_ATON)
1088 if (inet_aton(hostname, addr) == 0) {
1089 #elif defined(HAVE_INET_ADDR)
1090 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
1091 if ( (addr->s_addr = inet_addr(hostname)) == -1 ) {
1092 #else
1093 /* Use gethostbyname by default */
1094 if (1) {
1095 #endif
1096 struct in_addr *array_addr;
1097
1098 /* It is a real name, we solve it */
1099 if ((he = gethostbyname(hostname)) == NULL) {
1100 address->m_error = GSOCK_NOHOST;
1101 return GSOCK_NOHOST;
1102 }
1103 array_addr = (struct in_addr *) *(he->h_addr_list);
1104 addr->s_addr = array_addr[0].s_addr;
1105 }
1106 return GSOCK_NOERROR;
1107 }
1108
1109 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1110 unsigned long hostaddr)
1111 {
1112 struct in_addr *addr;
1113
1114 assert(address != NULL);
1115
1116 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1117
1118 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1119 addr->s_addr = hostaddr;
1120
1121 return GSOCK_NOERROR;
1122 }
1123
1124 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1125 const char *protocol)
1126 {
1127 struct servent *se;
1128 struct sockaddr_in *addr;
1129
1130 assert(address != NULL);
1131 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1132
1133 if (!port) {
1134 address->m_error = GSOCK_INVPORT;
1135 return GSOCK_INVPORT;
1136 }
1137
1138 se = getservbyname(port, protocol);
1139 if (!se) {
1140 if (isdigit(port[0])) {
1141 int port_int;
1142
1143 port_int = atoi(port);
1144 addr = (struct sockaddr_in *)address->m_addr;
1145 addr->sin_port = htons(port_int);
1146 return GSOCK_NOERROR;
1147 }
1148
1149 address->m_error = GSOCK_INVPORT;
1150 return GSOCK_INVPORT;
1151 }
1152
1153 addr = (struct sockaddr_in *)address->m_addr;
1154 addr->sin_port = se->s_port;
1155
1156 return GSOCK_NOERROR;
1157 }
1158
1159 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1160 {
1161 struct sockaddr_in *addr;
1162
1163 assert(address != NULL);
1164 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1165
1166 addr = (struct sockaddr_in *)address->m_addr;
1167 addr->sin_port = htons(port);
1168
1169 return GSOCK_NOERROR;
1170 }
1171
1172 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1173 {
1174 struct hostent *he;
1175 char *addr_buf;
1176 struct sockaddr_in *addr;
1177
1178 assert(address != NULL);
1179 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1180
1181 addr = (struct sockaddr_in *)address->m_addr;
1182 addr_buf = (char *)&(addr->sin_addr);
1183
1184 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1185 if (he == NULL) {
1186 address->m_error = GSOCK_NOHOST;
1187 return GSOCK_NOHOST;
1188 }
1189
1190 strncpy(hostname, he->h_name, sbuf);
1191
1192 return GSOCK_NOERROR;
1193 }
1194
1195 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1196 {
1197 struct sockaddr_in *addr;
1198
1199 assert(address != NULL);
1200 CHECK_ADDRESS(address, INET, 0);
1201
1202 addr = (struct sockaddr_in *)address->m_addr;
1203
1204 return addr->sin_addr.s_addr;
1205 }
1206
1207 unsigned short GAddress_INET_GetPort(GAddress *address)
1208 {
1209 struct sockaddr_in *addr;
1210
1211 assert(address != NULL);
1212 CHECK_ADDRESS(address, INET, 0);
1213
1214 addr = (struct sockaddr_in *)address->m_addr;
1215 return ntohs(addr->sin_port);
1216 }
1217
1218 /*
1219 * -------------------------------------------------------------------------
1220 * Unix address family
1221 * -------------------------------------------------------------------------
1222 */
1223
1224 GSocketError _GAddress_Init_UNIX(GAddress *address)
1225 {
1226 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1227 if (address->m_addr == NULL) {
1228 address->m_error = GSOCK_MEMERR;
1229 return GSOCK_MEMERR;
1230 }
1231
1232 address->m_len = sizeof(struct sockaddr_un);
1233 address->m_family = GSOCK_UNIX;
1234 address->m_realfamily = PF_UNIX;
1235 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1236 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1237
1238 return TRUE;
1239 }
1240
1241 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1242 {
1243 struct sockaddr_un *addr;
1244
1245 assert(address != NULL);
1246
1247 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1248
1249 addr = ((struct sockaddr_un *)address->m_addr);
1250 memcpy(addr->sun_path, path, strlen(path));
1251
1252 return GSOCK_NOERROR;
1253 }
1254
1255 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1256 {
1257 struct sockaddr_un *addr;
1258
1259 assert(address != NULL);
1260 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1261
1262 addr = (struct sockaddr_un *)address->m_addr;
1263
1264 strncpy(path, addr->sun_path, sbuf);
1265
1266 return GSOCK_NOERROR;
1267 }
1268
1269 #endif
1270 /* wxUSE_SOCKETS */