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