]> git.saurik.com Git - wxWidgets.git/blob - src/os2/gsocket.c
wxHtmlFilterHTML adds fake <meta> tag so that the parser knows charset
[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
11 #if wxUSE_SOCKETS
12
13 #define BSD_SELECT /* use Berkley Sockets select */
14
15 #include <assert.h>
16 #include <sys\types.h>
17 #ifdef __EMX__
18 #include <sys/time.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <netdb.h>
22 #include <errno.h>
23 #define HAVE_INET_ADDR
24 #else
25 #include <utils.h>
26 #include <sys\time.h>
27 #include <in.h>
28 #include <netdb.h>
29 #include <nerrno.h>
30 #endif
31 #if defined(__VISAGECPP__) && __IBMCPP__ < 400
32 #include <socket.h>
33 #include <ioctl.h>
34 #include <select.h>
35 #else
36 #include <sys\socket.h>
37 #include <sys\ioctl.h>
38 #include <sys\select.h>
39 #ifndef __EMX__
40 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
41 int _System bsdselect(int,
42 struct fd_set *,
43 struct fd_set *,
44 struct fd_set *,
45 struct timeval *);
46 int _System soclose(int);
47 #endif
48 #endif
49
50 #include <string.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <stddef.h>
54 #include <ctype.h>
55
56 #include <signal.h>
57
58 #include "wx/gsocket.h"
59 #include "wx/os2/gsockos2.h"
60
61 #ifndef SOCKLEN_T
62
63 #ifdef __GLIBC__
64 # if __GLIBC__ == 2
65 # define SOCKLEN_T socklen_t
66 # endif
67 #else
68 # define SOCKLEN_T int
69 #endif
70
71 #endif
72
73 /* Global initialisers */
74
75 bool GSocket_Init()
76 {
77 return TRUE;
78 }
79
80 void GSocket_Cleanup()
81 {
82 }
83
84 /* Constructors / Destructors */
85
86 GSocket *GSocket_new()
87 {
88 int i;
89 GSocket *socket;
90
91 socket = (GSocket *)malloc(sizeof(GSocket));
92
93 if (socket == NULL)
94 return NULL;
95
96 socket->m_fd = -1;
97 for (i=0;i<GSOCK_MAX_EVENT;i++)
98 {
99 socket->m_cbacks[i] = NULL;
100 }
101 socket->m_detected = 0;
102 socket->m_local = NULL;
103 socket->m_peer = NULL;
104 socket->m_error = GSOCK_NOERROR;
105 socket->m_server = FALSE;
106 socket->m_stream = TRUE;
107 socket->m_gui_dependent = NULL;
108 socket->m_non_blocking = FALSE;
109 socket->m_timeout = 10*60*1000;
110 /* 10 minutes * 60 sec * 1000 millisec */
111 socket->m_establishing = FALSE;
112
113 /* We initialize the GUI specific entries here */
114 _GSocket_GUI_Init(socket);
115
116 return socket;
117 }
118
119 void GSocket_destroy(GSocket *socket)
120 {
121 assert(socket != NULL);
122
123 /* First, we check that the socket is really shutdowned */
124 if (socket->m_fd != -1)
125 GSocket_Shutdown(socket);
126
127 /* We destroy GUI specific variables */
128 _GSocket_GUI_Destroy(socket);
129
130 /* We destroy private addresses */
131 if (socket->m_local)
132 GAddress_destroy(socket->m_local);
133
134 if (socket->m_peer)
135 GAddress_destroy(socket->m_peer);
136
137 /* We destroy socket itself */
138 free(socket);
139 }
140
141 void GSocket_Shutdown(GSocket *socket)
142 {
143 int evt;
144
145 assert(socket != NULL);
146
147 /* If socket has been created, we shutdown it */
148 if (socket->m_fd != -1)
149 {
150 shutdown(socket->m_fd, 2);
151 soclose(socket->m_fd);
152 socket->m_fd = -1;
153 }
154
155 /* We also disable GUI callbacks */
156 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
157 socket->m_cbacks[evt] = NULL;
158
159 socket->m_detected = 0;
160 _GSocket_Disable_Events(socket);
161 }
162
163 /* Address handling */
164
165 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
166 {
167 assert(socket != NULL);
168
169 if ((socket->m_fd != -1 && !socket->m_server)) {
170 socket->m_error = GSOCK_INVSOCK;
171 return GSOCK_INVSOCK;
172 }
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_local)
180 GAddress_destroy(socket->m_local);
181
182 socket->m_local = GAddress_copy(address);
183
184 return GSOCK_NOERROR;
185 }
186
187 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
188 {
189 assert(socket != NULL);
190
191 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
192 socket->m_error = GSOCK_INVADDR;
193 return GSOCK_INVADDR;
194 }
195
196 if (socket->m_peer)
197 GAddress_destroy(socket->m_peer);
198
199 socket->m_peer = GAddress_copy(address);
200
201 return GSOCK_NOERROR;
202 }
203
204 GAddress *GSocket_GetLocal(GSocket *socket)
205 {
206 GAddress *address;
207 struct sockaddr addr;
208 SOCKLEN_T size;
209 GSocketError err;
210
211 assert(socket != NULL);
212
213 if (socket->m_local)
214 return GAddress_copy(socket->m_local);
215
216 if (socket->m_fd == -1) {
217 socket->m_error = GSOCK_INVSOCK;
218 return NULL;
219 }
220
221 size = sizeof(addr);
222
223 if (getsockname(socket->m_fd, &addr, &size) < 0) {
224 socket->m_error = GSOCK_IOERR;
225 return NULL;
226 }
227
228 address = GAddress_new();
229 if (address == NULL) {
230 socket->m_error = GSOCK_MEMERR;
231 return NULL;
232 }
233 socket->m_error = _GAddress_translate_from(address, &addr, size);
234 if (socket->m_error != GSOCK_NOERROR) {
235 GAddress_destroy(address);
236 return NULL;
237 }
238
239 return address;
240 }
241
242 GAddress *GSocket_GetPeer(GSocket *socket)
243 {
244 assert(socket != NULL);
245
246 if (socket->m_peer)
247 return GAddress_copy(socket->m_peer);
248
249 return NULL;
250 }
251
252 /* Server specific parts */
253
254 /* GSocket_SetServer:
255 * Sets up the socket as a server. It uses the "Local" field of GSocket.
256 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
257 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
258 * been initialized, GSOCK_INVADDR if the local address has not been
259 * defined and GSOCK_IOERR for other internal errors.
260 */
261 GSocketError GSocket_SetServer(GSocket *sck)
262 {
263 int type;
264 int arg = 1;
265
266 assert(sck != NULL);
267
268 if (sck->m_fd != -1) {
269 sck->m_error = GSOCK_INVSOCK;
270 return GSOCK_INVSOCK;
271 }
272
273 if (!sck->m_local) {
274 sck->m_error = GSOCK_INVADDR;
275 return GSOCK_INVADDR;
276 }
277
278 /* We always have a stream here */
279 sck->m_stream = TRUE;
280 sck->m_server = TRUE;
281
282 /* Create the socket */
283 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
284
285 if (sck->m_fd == -1) {
286 sck->m_error = GSOCK_IOERR;
287 return GSOCK_IOERR;
288 }
289
290 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
291 _GSocket_Enable_Events(sck);
292
293 /* Bind the socket to the LOCAL address */
294 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
295 soclose(sck->m_fd);
296 sck->m_fd = -1;
297 sck->m_error = GSOCK_IOERR;
298 return GSOCK_IOERR;
299 }
300
301 /* Enable listening up to 5 connections */
302 if (listen(sck->m_fd, 5) < 0) {
303 soclose(sck->m_fd);
304 sck->m_fd = -1;
305 sck->m_error = GSOCK_IOERR;
306 return GSOCK_IOERR;
307 }
308
309 return GSOCK_NOERROR;
310 }
311
312 /* GSocket_WaitConnection:
313 * Waits for an incoming client connection.
314 */
315 GSocket *GSocket_WaitConnection(GSocket *socket)
316 {
317 GSocket *connection;
318 int arg = 1;
319
320 assert(socket != NULL);
321
322 /* Reenable CONNECTION events */
323 _GSocket_Enable(socket, GSOCK_CONNECTION);
324
325 /* If the socket has already been created, we exit immediately */
326 if (socket->m_fd == -1 || !socket->m_server)
327 {
328 socket->m_error = GSOCK_INVSOCK;
329 return NULL;
330 }
331
332 /* Create a GSocket object for the new connection */
333 connection = GSocket_new();
334 if (!connection)
335 {
336 connection->m_error = GSOCK_MEMERR;
337 return NULL;
338 }
339
340 /* Accept the incoming connection */
341 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
342 {
343 GSocket_destroy(connection);
344 /* socket->m_error set by _GSocket_Input_Timeout */
345 return NULL;
346 }
347
348 connection->m_fd = accept(socket->m_fd, NULL, NULL);
349
350 if (connection->m_fd == -1)
351 {
352 if (errno == EWOULDBLOCK)
353 socket->m_error = GSOCK_WOULDBLOCK;
354 else
355 socket->m_error = GSOCK_IOERR;
356
357 GSocket_destroy(connection);
358 return NULL;
359 }
360
361 /* Initialize all fields */
362 connection->m_server = FALSE;
363 connection->m_stream = TRUE;
364 connection->m_oriented = TRUE;
365
366 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(int));
367 _GSocket_Enable_Events(connection);
368
369 return connection;
370 }
371
372 /* Non oriented connections */
373
374 GSocketError GSocket_SetNonOriented(GSocket *sck)
375 {
376 int arg = 1;
377
378 assert(sck != NULL);
379
380 if (sck->m_fd != -1) {
381 sck->m_error = GSOCK_INVSOCK;
382 return GSOCK_INVSOCK;
383 }
384
385 if (!sck->m_local) {
386 sck->m_error = GSOCK_INVADDR;
387 return GSOCK_INVADDR;
388 }
389
390 sck->m_stream = FALSE;
391 sck->m_server = FALSE;
392 sck->m_oriented = FALSE;
393
394 /* Create the socket */
395 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
396
397 if (sck->m_fd < 0) {
398 sck->m_error = GSOCK_IOERR;
399 return GSOCK_IOERR;
400 }
401
402 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
403 _GSocket_Enable_Events(sck);
404
405 /* Bind it to the LOCAL address */
406 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
407 soclose(sck->m_fd);
408 sck->m_fd = -1;
409 sck->m_error = GSOCK_IOERR;
410 return GSOCK_IOERR;
411 }
412
413 return GSOCK_NOERROR;
414 }
415
416 /* Client specific parts */
417
418 /* GSocket_Connect:
419 * Establishes a client connection to a server using the "Peer"
420 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
421 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
422 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
423 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
424 * the connection request can be completed later. Use GSocket_Select()
425 * to check or wait for a GSOCK_CONNECTION event.
426 */
427 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
428 {
429 int type, err, ret;
430 int arg = 1;
431
432 assert(sck != NULL);
433
434 /* Enable CONNECTION events (needed for nonblocking connections) */
435 _GSocket_Enable(sck, GSOCK_CONNECTION);
436
437 if (sck->m_fd != -1)
438 {
439 sck->m_error = GSOCK_INVSOCK;
440 return GSOCK_INVSOCK;
441 }
442
443 if (!sck->m_peer)
444 {
445 sck->m_error = GSOCK_INVADDR;
446 return GSOCK_INVADDR;
447 }
448
449 /* Test whether we want the socket to be a stream (e.g. TCP) */
450 sck->m_stream = (stream == GSOCK_STREAMED);
451 sck->m_oriented = TRUE;
452 sck->m_server = FALSE;
453 sck->m_establishing = FALSE;
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 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
469 _GSocket_Enable_Events(sck);
470
471 /* Connect it to the PEER address */
472 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
473
474 if (ret == -1)
475 {
476 err = errno;
477
478 /* If connect failed with EINPROGRESS and the GSocket object
479 * is in blocking mode, we select() for the specified timeout
480 * checking for writability to see if the connection request
481 * completes.
482 */
483 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
484 {
485 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
486 {
487 soclose(sck->m_fd);
488 sck->m_fd = -1;
489 /* sck->m_error is set in _GSocket_Output_Timeout */
490 fprintf(stderr, "Blocking connect timeouts\n");
491 return GSOCK_TIMEDOUT;
492 }
493 else
494 {
495 fprintf(stderr, "Blocking connect OK\n");
496 return GSOCK_NOERROR;
497 }
498 }
499
500 /* If connect failed with EINPROGRESS and the GSocket object
501 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
502 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
503 * this way if the connection completes, a GSOCK_CONNECTION
504 * event will be generated, if enabled.
505 */
506 if ((err == EINPROGRESS) && (sck->m_non_blocking))
507 {
508 sck->m_error = GSOCK_WOULDBLOCK;
509 sck->m_establishing = TRUE;
510 fprintf(stderr, "Nonblocking connect in progress\n");
511
512 return GSOCK_WOULDBLOCK;
513 }
514
515 /* If connect failed with an error other than EINPROGRESS,
516 * then the call to GSocket_Connect has failed.
517 */
518 soclose(sck->m_fd);
519 sck->m_fd = -1;
520 sck->m_error = GSOCK_IOERR;
521
522 fprintf(stderr, "Connect failed (generic err)\n");
523 return GSOCK_IOERR;
524 }
525
526 fprintf(stderr, "Connect OK\n");
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 tv.tv_sec = (socket->m_timeout / 1000);
746 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
747
748 if (!socket->m_non_blocking)
749 {
750 FD_ZERO(&readfds);
751 FD_SET(socket->m_fd, &readfds);
752 if (select(socket->m_fd + 1, &readfds, NULL, NULL, &tv) == 0)
753 {
754 socket->m_error = GSOCK_TIMEDOUT;
755 return GSOCK_TIMEDOUT;
756 }
757 }
758 return GSOCK_NOERROR;
759 }
760
761 /* _GSocket_Output_Timeout:
762 * For blocking sockets, wait until data can be sent without
763 * blocking or until timeout ellapses.
764 */
765 GSocketError _GSocket_Output_Timeout(GSocket *socket)
766 {
767 struct timeval tv;
768 fd_set writefds;
769
770 tv.tv_sec = (socket->m_timeout / 1000);
771 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
772
773 if (!socket->m_non_blocking)
774 {
775 FD_ZERO(&writefds);
776 FD_SET(socket->m_fd, &writefds);
777 if (select(socket->m_fd + 1, NULL, &writefds, NULL, &tv) == 0)
778 {
779 socket->m_error = GSOCK_TIMEDOUT;
780 return GSOCK_TIMEDOUT;
781 }
782 }
783 return GSOCK_NOERROR;
784 }
785
786 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
787 {
788 int ret;
789
790 ret = recv(socket->m_fd, buffer, size, 0);
791
792 return ret;
793 }
794
795 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
796 {
797 struct sockaddr from;
798 SOCKLEN_T fromlen;
799 int ret;
800 GSocketError err;
801
802 fromlen = sizeof(from);
803
804 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
805
806 if (ret == -1)
807 return -1;
808
809 /* Translate a system address into a GSocket address */
810 if (!socket->m_peer)
811 {
812 socket->m_peer = GAddress_new();
813 if (!socket->m_peer)
814 {
815 socket->m_error = GSOCK_MEMERR;
816 return -1;
817 }
818 }
819 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
820 if (err != GSOCK_NOERROR)
821 {
822 GAddress_destroy(socket->m_peer);
823 socket->m_peer = NULL;
824 socket->m_error = err;
825 return -1;
826 }
827
828 return ret;
829 }
830
831 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
832 {
833 int ret;
834 GSocketError err;
835
836 ret = send(socket->m_fd, (char*)buffer, size, 0);
837
838 return ret;
839 }
840
841 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
842 {
843 struct sockaddr *addr;
844 int len, ret;
845 GSocketError err;
846
847 if (!socket->m_peer) {
848 socket->m_error = GSOCK_INVADDR;
849 return -1;
850 }
851
852 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
853 if (err != GSOCK_NOERROR) {
854 socket->m_error = err;
855 return -1;
856 }
857
858 ret = sendto(socket->m_fd, (char*)buffer, size, 0, addr, len);
859
860 /* Frees memory allocated from _GAddress_translate_to */
861 free(addr);
862
863 return ret;
864 }
865
866 void _GSocket_Detected_Read(GSocket *socket)
867 {
868 char c;
869 int ret;
870
871 if (socket->m_stream)
872 {
873 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
874
875 if (ret < 0 && socket->m_server)
876 {
877 CALL_CALLBACK(socket, GSOCK_CONNECTION);
878 return;
879 }
880
881 if (ret > 0)
882 {
883 CALL_CALLBACK(socket, GSOCK_INPUT);
884 }
885 else
886 {
887 CALL_CALLBACK(socket, GSOCK_LOST);
888 }
889 }
890 }
891
892 void _GSocket_Detected_Write(GSocket *socket)
893 {
894 if (socket->m_establishing && !socket->m_server)
895 {
896 int error, len;
897
898 socket->m_establishing = FALSE;
899
900 len = sizeof(error);
901 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
902
903 if (error)
904 {
905 CALL_CALLBACK(socket, GSOCK_LOST);
906 }
907 else
908 {
909 CALL_CALLBACK(socket, GSOCK_CONNECTION);
910 /* We have to fire this event by hand because CONNECTION (for clients)
911 * and OUTPUT are internally the same and we just disabled CONNECTION
912 * events with the above macro.
913 */
914 CALL_CALLBACK(socket, GSOCK_OUTPUT);
915 }
916 }
917 else
918 {
919 CALL_CALLBACK(socket, GSOCK_OUTPUT);
920 }
921 }
922
923 /*
924 * -------------------------------------------------------------------------
925 * GAddress
926 * -------------------------------------------------------------------------
927 */
928
929 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
930 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
931 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
932 */
933 #define CHECK_ADDRESS(address, family, retval) \
934 { \
935 if (address->m_family == GSOCK_NOFAMILY) \
936 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
937 return address->m_error; \
938 }\
939 if (address->m_family != GSOCK_##family) {\
940 address->m_error = GSOCK_INVADDR; \
941 return retval; \
942 } \
943 }
944
945 GAddress *GAddress_new()
946 {
947 GAddress *address;
948
949 address = (GAddress *)malloc(sizeof(GAddress));
950
951 if (address == NULL)
952 return NULL;
953
954 address->m_family = GSOCK_NOFAMILY;
955 address->m_addr = NULL;
956 address->m_len = 0;
957
958 return address;
959 }
960
961 GAddress *GAddress_copy(GAddress *address)
962 {
963 GAddress *addr2;
964
965 assert(address != NULL);
966
967 addr2 = (GAddress *)malloc(sizeof(GAddress));
968
969 if (addr2 == NULL)
970 return NULL;
971
972 memcpy(addr2, address, sizeof(GAddress));
973
974 if (address->m_addr) {
975 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
976 if (addr2->m_addr == NULL) {
977 free(addr2);
978 return NULL;
979 }
980 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
981 }
982
983 return addr2;
984 }
985
986 void GAddress_destroy(GAddress *address)
987 {
988 assert(address != NULL);
989
990 free(address);
991 }
992
993 void GAddress_SetFamily(GAddress *address, GAddressType type)
994 {
995 assert(address != NULL);
996
997 address->m_family = type;
998 }
999
1000 GAddressType GAddress_GetFamily(GAddress *address)
1001 {
1002 assert(address != NULL);
1003
1004 return address->m_family;
1005 }
1006
1007 GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
1008 address->m_realfamily = addr->sa_family;
1009 switch (addr->sa_family) {
1010 case AF_INET:
1011 address->m_family = GSOCK_INET;
1012 break;
1013 case AF_UNIX:
1014 address->m_family = GSOCK_UNIX;
1015 break;
1016 #ifdef AF_INET6
1017 case AF_INET6:
1018 address->m_family = GSOCK_INET6;
1019 break;
1020 #endif
1021 default:
1022 {
1023 address->m_error = GSOCK_INVOP;
1024 return GSOCK_INVOP;
1025 }
1026 }
1027
1028 if (address->m_addr)
1029 free(address->m_addr);
1030
1031 address->m_len = len;
1032 address->m_addr = (struct sockaddr *)malloc(len);
1033 if (address->m_addr == NULL) {
1034 address->m_error = GSOCK_MEMERR;
1035 return GSOCK_MEMERR;
1036 }
1037 memcpy(address->m_addr, addr, len);
1038
1039 return GSOCK_NOERROR;
1040 }
1041
1042 GSocketError _GAddress_translate_to(GAddress *address,
1043 struct sockaddr **addr, int *len)
1044 {
1045 if (!address->m_addr) {
1046 address->m_error = GSOCK_INVADDR;
1047 return GSOCK_INVADDR;
1048 }
1049
1050 *len = address->m_len;
1051 *addr = (struct sockaddr *)malloc(address->m_len);
1052 if (*addr == NULL) {
1053 address->m_error = GSOCK_MEMERR;
1054 return GSOCK_MEMERR;
1055 }
1056
1057 memcpy(*addr, address->m_addr, address->m_len);
1058 return GSOCK_NOERROR;
1059 }
1060
1061 /*
1062 * -------------------------------------------------------------------------
1063 * Internet address family
1064 * -------------------------------------------------------------------------
1065 */
1066
1067 GSocketError _GAddress_Init_INET(GAddress *address)
1068 {
1069 address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
1070 if (address->m_addr == NULL) {
1071 address->m_error = GSOCK_MEMERR;
1072 return GSOCK_MEMERR;
1073 }
1074
1075 address->m_len = sizeof(struct sockaddr_in);
1076
1077 address->m_family = GSOCK_INET;
1078 address->m_realfamily = PF_INET;
1079 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1080 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1081
1082 return GSOCK_NOERROR;
1083 }
1084
1085 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1086 {
1087 struct hostent *he;
1088 struct in_addr *addr;
1089
1090 assert(address != NULL);
1091
1092 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1093
1094 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1095
1096 /* If it is a numeric host name, convert it now */
1097 #if defined(HAVE_INET_ATON)
1098 if (inet_aton(hostname, addr) == 0) {
1099 #elif defined(HAVE_INET_ADDR)
1100 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
1101 if ( (addr->s_addr = inet_addr(hostname)) == -1 ) {
1102 #endif
1103 struct in_addr *array_addr;
1104
1105 /* It is a real name, we solve it */
1106 he = gethostbyname((char*)hostname);
1107 if (he == NULL) {
1108 address->m_error = GSOCK_NOHOST;
1109 return GSOCK_NOHOST;
1110 }
1111 array_addr = (struct in_addr *) *(he->h_addr_list);
1112 addr->s_addr = array_addr[0].s_addr;
1113 #if defined(HAVE_INET_ATON)
1114 }
1115 #elif defined(HAVE_INET_ADDR)
1116 }
1117 #endif
1118 return GSOCK_NOERROR;
1119 }
1120
1121 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1122 unsigned long hostaddr)
1123 {
1124 struct in_addr *addr;
1125
1126 assert(address != NULL);
1127
1128 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1129
1130 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1131 addr->s_addr = hostaddr;
1132
1133 return GSOCK_NOERROR;
1134 }
1135
1136 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1137 const char *protocol)
1138 {
1139 struct servent *se;
1140 struct sockaddr_in *addr;
1141
1142 assert(address != NULL);
1143 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1144
1145 if (!port) {
1146 address->m_error = GSOCK_INVPORT;
1147 return GSOCK_INVPORT;
1148 }
1149
1150 se = getservbyname((char*)port, (char*)protocol);
1151 if (!se) {
1152 if (isdigit(port[0])) {
1153 int port_int;
1154
1155 port_int = atoi(port);
1156 addr = (struct sockaddr_in *)address->m_addr;
1157 addr->sin_port = htons(port_int);
1158 return GSOCK_NOERROR;
1159 }
1160
1161 address->m_error = GSOCK_INVPORT;
1162 return GSOCK_INVPORT;
1163 }
1164
1165 addr = (struct sockaddr_in *)address->m_addr;
1166 addr->sin_port = se->s_port;
1167
1168 return GSOCK_NOERROR;
1169 }
1170
1171 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1172 {
1173 struct sockaddr_in *addr;
1174
1175 assert(address != NULL);
1176 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1177
1178 addr = (struct sockaddr_in *)address->m_addr;
1179 addr->sin_port = htons(port);
1180
1181 return GSOCK_NOERROR;
1182 }
1183
1184 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1185 {
1186 struct hostent *he;
1187 char *addr_buf;
1188 struct sockaddr_in *addr;
1189
1190 assert(address != NULL);
1191 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1192
1193 addr = (struct sockaddr_in *)address->m_addr;
1194 addr_buf = (char *)&(addr->sin_addr);
1195
1196 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1197 if (he == NULL) {
1198 address->m_error = GSOCK_NOHOST;
1199 return GSOCK_NOHOST;
1200 }
1201
1202 strncpy(hostname, he->h_name, sbuf);
1203
1204 return GSOCK_NOERROR;
1205 }
1206
1207 unsigned long GAddress_INET_GetHostAddress(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
1216 return addr->sin_addr.s_addr;
1217 }
1218
1219 unsigned short GAddress_INET_GetPort(GAddress *address)
1220 {
1221 struct sockaddr_in *addr;
1222
1223 assert(address != NULL);
1224 CHECK_ADDRESS(address, INET, 0);
1225
1226 addr = (struct sockaddr_in *)address->m_addr;
1227 return ntohs(addr->sin_port);
1228 }
1229
1230 #endif
1231 /* wxUSE_SOCKETS */