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