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