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