]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gsocket.c
drawing mono bitmaps now uses correct colours
[wxWidgets.git] / src / os2 / gsocket.c
CommitLineData
fb9010ed
DW
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"
fb9010ed
DW
10
11#if wxUSE_SOCKETS
12
9dea36ef 13#define BSD_SELECT /* use Berkley Sockets select */
fb9010ed
DW
14
15#include <assert.h>
fb9010ed 16#include <sys\types.h>
610c9851
SN
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
fb9010ed
DW
25#include <utils.h>
26#include <sys\time.h>
27#include <in.h>
28#include <netdb.h>
29#include <nerrno.h>
610c9851 30#endif
9ac6ff7b
DW
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>
476607a7 38#include <sys\select.h>
610c9851 39#ifndef __EMX__
9dea36ef
DW
40#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
41int _System bsdselect(int,
42 struct fd_set *,
43 struct fd_set *,
44 struct fd_set *,
45 struct timeval *);
46int _System soclose(int);
9ac6ff7b 47#endif
610c9851 48#endif
fb9010ed
DW
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
75bool GSocket_Init()
76{
77 return TRUE;
78}
79
80void GSocket_Cleanup()
81{
82}
83
84/* Constructors / Destructors */
85
86GSocket *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
119void 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
141void 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
165GSocketError 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
187GSocketError 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
204GAddress *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
242GAddress *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 */
261GSocketError 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 */
315GSocket *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
374GSocketError 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 */
427GSocketError 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(), ... */
533int 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
567int 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 */
613GSocketEventFlags 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 */
626void 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 */
637void 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 */
647GSocketError 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 */
680void 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 */
701void 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
724void _GSocket_Enable(GSocket *socket, GSocketEvent event)
725{
726 socket->m_detected &= ~(1 << event);
727 _GSocket_Install_Callback(socket, event);
728}
729
730void _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 */
740GSocketError _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 */
765GSocketError _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
786int _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
795int _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
831int _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
841int _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
866void _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
892void _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
945GAddress *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
961GAddress *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
986void GAddress_destroy(GAddress *address)
987{
988 assert(address != NULL);
989
990 free(address);
991}
992
993void GAddress_SetFamily(GAddress *address, GAddressType type)
994{
995 assert(address != NULL);
996
997 address->m_family = type;
998}
999
1000GAddressType GAddress_GetFamily(GAddress *address)
1001{
1002 assert(address != NULL);
1003
1004 return address->m_family;
1005}
1006
1007GSocketError _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
1042GSocketError _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
1067GSocketError _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
1085GSocketError 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
1121GSocketError 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
1136GSocketError 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
1171GSocketError 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
1184GSocketError 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
1207unsigned 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
1219unsigned 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 */