]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gsocket.c
fixing mngw32 (cross)compilation
[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>
e15bbde0
DW
60#if defined(__VISAGECPP__) && __IBMCPP__ < 400
61# ifdef min
62# undef min
63# endif
64# include <stdlib.h>
65#endif
fb9010ed
DW
66#include <stddef.h>
67#include <ctype.h>
68
69#include <signal.h>
70
71#include "wx/gsocket.h"
72#include "wx/os2/gsockos2.h"
73
74#ifndef SOCKLEN_T
75
76#ifdef __GLIBC__
77# if __GLIBC__ == 2
78# define SOCKLEN_T socklen_t
79# endif
80#else
81# define SOCKLEN_T int
82#endif
83
84#endif
85
86/* Global initialisers */
87
27f37ae5 88int GSocket_Init()
fb9010ed 89{
27f37ae5 90 return 1;
fb9010ed
DW
91}
92
93void GSocket_Cleanup()
94{
95}
96
97/* Constructors / Destructors */
98
99GSocket *GSocket_new()
100{
101 int i;
102 GSocket *socket;
103
104 socket = (GSocket *)malloc(sizeof(GSocket));
105
106 if (socket == NULL)
107 return NULL;
108
109 socket->m_fd = -1;
110 for (i=0;i<GSOCK_MAX_EVENT;i++)
111 {
112 socket->m_cbacks[i] = NULL;
113 }
114 socket->m_detected = 0;
115 socket->m_local = NULL;
116 socket->m_peer = NULL;
117 socket->m_error = GSOCK_NOERROR;
27f37ae5
SN
118 socket->m_server = 0;
119 socket->m_stream = 1;
fb9010ed 120 socket->m_gui_dependent = NULL;
27f37ae5 121 socket->m_non_blocking = 0;
fb9010ed
DW
122 socket->m_timeout = 10*60*1000;
123 /* 10 minutes * 60 sec * 1000 millisec */
27f37ae5 124 socket->m_establishing = 0;
fb9010ed 125
fb9010ed
DW
126 return socket;
127}
128
129void GSocket_destroy(GSocket *socket)
130{
131 assert(socket != NULL);
132
133 /* First, we check that the socket is really shutdowned */
134 if (socket->m_fd != -1)
135 GSocket_Shutdown(socket);
136
fb9010ed
DW
137 /* We destroy private addresses */
138 if (socket->m_local)
139 GAddress_destroy(socket->m_local);
140
141 if (socket->m_peer)
142 GAddress_destroy(socket->m_peer);
143
144 /* We destroy socket itself */
145 free(socket);
146}
147
148void GSocket_Shutdown(GSocket *socket)
149{
150 int evt;
151
152 assert(socket != NULL);
153
154 /* If socket has been created, we shutdown it */
155 if (socket->m_fd != -1)
156 {
157 shutdown(socket->m_fd, 2);
158 soclose(socket->m_fd);
159 socket->m_fd = -1;
160 }
161
162 /* We also disable GUI callbacks */
163 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
164 socket->m_cbacks[evt] = NULL;
165
166 socket->m_detected = 0;
426d5745 167 (socket);
fb9010ed
DW
168}
169
170/* Address handling */
171
172GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
173{
174 assert(socket != NULL);
175
176 if ((socket->m_fd != -1 && !socket->m_server)) {
177 socket->m_error = GSOCK_INVSOCK;
178 return GSOCK_INVSOCK;
179 }
180
181 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
182 socket->m_error = GSOCK_INVADDR;
183 return GSOCK_INVADDR;
184 }
185
186 if (socket->m_local)
187 GAddress_destroy(socket->m_local);
188
189 socket->m_local = GAddress_copy(address);
190
191 return GSOCK_NOERROR;
192}
193
194GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
195{
196 assert(socket != NULL);
197
198 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
199 socket->m_error = GSOCK_INVADDR;
200 return GSOCK_INVADDR;
201 }
202
203 if (socket->m_peer)
204 GAddress_destroy(socket->m_peer);
205
206 socket->m_peer = GAddress_copy(address);
207
208 return GSOCK_NOERROR;
209}
210
211GAddress *GSocket_GetLocal(GSocket *socket)
212{
213 GAddress *address;
214 struct sockaddr addr;
215 SOCKLEN_T size;
216 GSocketError err;
217
218 assert(socket != NULL);
219
220 if (socket->m_local)
221 return GAddress_copy(socket->m_local);
222
223 if (socket->m_fd == -1) {
224 socket->m_error = GSOCK_INVSOCK;
225 return NULL;
226 }
227
228 size = sizeof(addr);
229
230 if (getsockname(socket->m_fd, &addr, &size) < 0) {
231 socket->m_error = GSOCK_IOERR;
232 return NULL;
233 }
234
235 address = GAddress_new();
236 if (address == NULL) {
237 socket->m_error = GSOCK_MEMERR;
238 return NULL;
239 }
240 socket->m_error = _GAddress_translate_from(address, &addr, size);
241 if (socket->m_error != GSOCK_NOERROR) {
242 GAddress_destroy(address);
243 return NULL;
244 }
245
246 return address;
247}
248
249GAddress *GSocket_GetPeer(GSocket *socket)
250{
251 assert(socket != NULL);
252
253 if (socket->m_peer)
254 return GAddress_copy(socket->m_peer);
255
256 return NULL;
257}
258
259/* Server specific parts */
260
261/* GSocket_SetServer:
262 * Sets up the socket as a server. It uses the "Local" field of GSocket.
263 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
264 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
265 * been initialized, GSOCK_INVADDR if the local address has not been
266 * defined and GSOCK_IOERR for other internal errors.
267 */
268GSocketError GSocket_SetServer(GSocket *sck)
269{
270 int type;
271 int arg = 1;
272
273 assert(sck != NULL);
274
275 if (sck->m_fd != -1) {
276 sck->m_error = GSOCK_INVSOCK;
277 return GSOCK_INVSOCK;
278 }
279
280 if (!sck->m_local) {
281 sck->m_error = GSOCK_INVADDR;
282 return GSOCK_INVADDR;
283 }
284
285 /* We always have a stream here */
27f37ae5
SN
286 sck->m_stream = 1;
287 sck->m_server = 1;
fb9010ed
DW
288
289 /* Create the socket */
290 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
291
292 if (sck->m_fd == -1) {
293 sck->m_error = GSOCK_IOERR;
294 return GSOCK_IOERR;
295 }
296
297 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
fb9010ed
DW
298
299 /* Bind the socket to the LOCAL address */
300 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
301 soclose(sck->m_fd);
302 sck->m_fd = -1;
303 sck->m_error = GSOCK_IOERR;
304 return GSOCK_IOERR;
305 }
306
307 /* Enable listening up to 5 connections */
308 if (listen(sck->m_fd, 5) < 0) {
309 soclose(sck->m_fd);
310 sck->m_fd = -1;
311 sck->m_error = GSOCK_IOERR;
312 return GSOCK_IOERR;
313 }
314
315 return GSOCK_NOERROR;
316}
317
318/* GSocket_WaitConnection:
319 * Waits for an incoming client connection.
320 */
321GSocket *GSocket_WaitConnection(GSocket *socket)
322{
323 GSocket *connection;
324 int arg = 1;
325
326 assert(socket != NULL);
327
328 /* Reenable CONNECTION events */
329 _GSocket_Enable(socket, GSOCK_CONNECTION);
330
331 /* If the socket has already been created, we exit immediately */
332 if (socket->m_fd == -1 || !socket->m_server)
333 {
334 socket->m_error = GSOCK_INVSOCK;
335 return NULL;
336 }
337
338 /* Create a GSocket object for the new connection */
339 connection = GSocket_new();
340 if (!connection)
341 {
342 connection->m_error = GSOCK_MEMERR;
343 return NULL;
344 }
345
346 /* Accept the incoming connection */
347 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
348 {
349 GSocket_destroy(connection);
350 /* socket->m_error set by _GSocket_Input_Timeout */
351 return NULL;
352 }
353
354 connection->m_fd = accept(socket->m_fd, NULL, NULL);
355
356 if (connection->m_fd == -1)
357 {
358 if (errno == EWOULDBLOCK)
359 socket->m_error = GSOCK_WOULDBLOCK;
360 else
361 socket->m_error = GSOCK_IOERR;
362
363 GSocket_destroy(connection);
364 return NULL;
365 }
366
367 /* Initialize all fields */
27f37ae5
SN
368 connection->m_server = 0;
369 connection->m_stream = 1;
370 connection->m_oriented = 1;
fb9010ed
DW
371
372 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(int));
fb9010ed
DW
373 return connection;
374}
375
376/* Non oriented connections */
377
378GSocketError GSocket_SetNonOriented(GSocket *sck)
379{
380 int arg = 1;
381
382 assert(sck != NULL);
383
384 if (sck->m_fd != -1) {
385 sck->m_error = GSOCK_INVSOCK;
386 return GSOCK_INVSOCK;
387 }
388
389 if (!sck->m_local) {
390 sck->m_error = GSOCK_INVADDR;
391 return GSOCK_INVADDR;
392 }
393
27f37ae5
SN
394 sck->m_stream = 0;
395 sck->m_server = 0;
396 sck->m_oriented = 0;
fb9010ed
DW
397
398 /* Create the socket */
399 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
400
401 if (sck->m_fd < 0) {
402 sck->m_error = GSOCK_IOERR;
403 return GSOCK_IOERR;
404 }
405
406 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
fb9010ed
DW
407
408 /* Bind it to the LOCAL address */
409 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
410 soclose(sck->m_fd);
411 sck->m_fd = -1;
412 sck->m_error = GSOCK_IOERR;
413 return GSOCK_IOERR;
414 }
415
416 return GSOCK_NOERROR;
417}
418
419/* Client specific parts */
420
421/* GSocket_Connect:
422 * Establishes a client connection to a server using the "Peer"
423 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
424 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
425 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
426 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
427 * the connection request can be completed later. Use GSocket_Select()
428 * to check or wait for a GSOCK_CONNECTION event.
429 */
430GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
431{
432 int type, err, ret;
433 int arg = 1;
434
435 assert(sck != NULL);
436
437 /* Enable CONNECTION events (needed for nonblocking connections) */
438 _GSocket_Enable(sck, GSOCK_CONNECTION);
439
440 if (sck->m_fd != -1)
441 {
442 sck->m_error = GSOCK_INVSOCK;
443 return GSOCK_INVSOCK;
444 }
445
446 if (!sck->m_peer)
447 {
448 sck->m_error = GSOCK_INVADDR;
449 return GSOCK_INVADDR;
450 }
451
452 /* Test whether we want the socket to be a stream (e.g. TCP) */
453 sck->m_stream = (stream == GSOCK_STREAMED);
27f37ae5
SN
454 sck->m_oriented = 1;
455 sck->m_server = 0;
456 sck->m_establishing = 0;
fb9010ed
DW
457
458 if (sck->m_stream)
459 type = SOCK_STREAM;
460 else
461 type = SOCK_DGRAM;
462
463 /* Create the socket */
464 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
465
466 if (sck->m_fd == -1) {
467 sck->m_error = GSOCK_IOERR;
468 return GSOCK_IOERR;
469 }
470
471 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(int));
fb9010ed
DW
472
473 /* Connect it to the PEER address */
474 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
475
476 if (ret == -1)
477 {
478 err = errno;
479
480 /* If connect failed with EINPROGRESS and the GSocket object
481 * is in blocking mode, we select() for the specified timeout
482 * checking for writability to see if the connection request
483 * completes.
484 */
485 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
486 {
487 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
488 {
489 soclose(sck->m_fd);
490 sck->m_fd = -1;
491 /* sck->m_error is set in _GSocket_Output_Timeout */
492 fprintf(stderr, "Blocking connect timeouts\n");
493 return GSOCK_TIMEDOUT;
494 }
495 else
496 {
497 fprintf(stderr, "Blocking connect OK\n");
498 return GSOCK_NOERROR;
499 }
500 }
501
502 /* If connect failed with EINPROGRESS and the GSocket object
503 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
504 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
505 * this way if the connection completes, a GSOCK_CONNECTION
506 * event will be generated, if enabled.
507 */
508 if ((err == EINPROGRESS) && (sck->m_non_blocking))
509 {
510 sck->m_error = GSOCK_WOULDBLOCK;
27f37ae5 511 sck->m_establishing = 1;
fb9010ed
DW
512 fprintf(stderr, "Nonblocking connect in progress\n");
513
514 return GSOCK_WOULDBLOCK;
515 }
516
517 /* If connect failed with an error other than EINPROGRESS,
518 * then the call to GSocket_Connect has failed.
519 */
520 soclose(sck->m_fd);
521 sck->m_fd = -1;
522 sck->m_error = GSOCK_IOERR;
523
524 fprintf(stderr, "Connect failed (generic err)\n");
525 return GSOCK_IOERR;
526 }
527
528 fprintf(stderr, "Connect OK\n");
529 return GSOCK_NOERROR;
530}
531
532/* Generic IO */
533
534/* Like recv(), send(), ... */
535int GSocket_Read(GSocket *socket, char *buffer, int size)
536{
537 int ret;
538
539 assert(socket != NULL);
540
541 /* Reenable INPUT events */
542 _GSocket_Enable(socket, GSOCK_INPUT);
543
544 if (socket->m_fd == -1 || socket->m_server)
545 {
546 socket->m_error = GSOCK_INVSOCK;
547 return -1;
548 }
549
550 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
551 return -1;
552
553 if (socket->m_stream)
554 ret = _GSocket_Recv_Stream(socket, buffer, size);
555 else
556 ret = _GSocket_Recv_Dgram(socket, buffer, size);
557
558 if (ret == -1)
559 {
560 if (errno == EWOULDBLOCK)
561 socket->m_error = GSOCK_WOULDBLOCK;
562 else
563 socket->m_error = GSOCK_IOERR;
564 }
565
566 return ret;
567}
568
569int GSocket_Write(GSocket *socket, const char *buffer,
570 int size)
571{
572 int ret;
573
574 assert(socket != NULL);
575
576 if (socket->m_fd == -1 || socket->m_server)
577 {
578 socket->m_error = GSOCK_INVSOCK;
579 return -1;
580 }
581
582 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
583 return -1;
584
585 if (socket->m_stream)
586 ret = _GSocket_Send_Stream(socket, buffer, size);
587 else
588 ret = _GSocket_Send_Dgram(socket, buffer, size);
589
590 if (ret == -1)
591 {
592 if (errno == EWOULDBLOCK)
593 socket->m_error = GSOCK_WOULDBLOCK;
594 else
595 socket->m_error = GSOCK_IOERR;
596
597 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
598 * in MSW). Once the first OUTPUT event is received, users can assume
599 * that the socket is writable until a read operation fails. Only then
600 * will further OUTPUT events be posted.
601 */
602 _GSocket_Enable(socket, GSOCK_OUTPUT);
603 }
604
605 return ret;
606}
607
608/* GSocket_Select:
609 * Polls the socket to determine its status. This function will
610 * check for the events specified in the 'flags' parameter, and
611 * it will return a mask indicating which operations can be
612 * performed. This function won't block, regardless of the
613 * mode (blocking|nonblocking) of the socket.
614 */
615GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
616{
617 assert(socket != NULL);
618
619 return (flags & socket->m_detected);
620}
621
622/* Flags */
623
624/* GSocket_SetNonBlocking:
625 * Sets the socket to non-blocking mode. This is useful if
626 * we don't want to wait.
627 */
27f37ae5 628void GSocket_SetNonBlocking(GSocket *socket, int non_block)
fb9010ed
DW
629{
630 assert(socket != NULL);
631
632 socket->m_non_blocking = non_block;
633}
634
635/* GSocket_SetTimeout:
636 * Sets the timeout for blocking calls. Time is
637 * expressed in milliseconds.
638 */
639void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
640{
641 assert(socket != NULL);
642
643 socket->m_timeout = millisec;
644}
645
646/* GSocket_GetError:
647 * Returns the last error occured for this socket.
648 */
649GSocketError GSocket_GetError(GSocket *socket)
650{
651 assert(socket != NULL);
652
653 return socket->m_error;
654}
655
656/* Callbacks */
657
658/* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
659 * and LOST). The callbacks are called in the following situations:
660 *
661 * INPUT: There is at least one byte in the input buffer
662 * OUTPUT: The system is sure that the next write call will not block
663 * CONNECTION: Two cases are possible:
664 * Client socket -> the connection is established
665 * Server socket -> a client requests a connection
666 * LOST: The connection is lost
667 *
668 * An event is generated only once and its state is reseted when the
669 * relative IO call is requested.
670 * For example: INPUT -> GSocket_Read()
671 * CONNECTION -> GSocket_Accept()
672 */
673
674/* GSocket_SetCallback:
675 * Enables the callbacks specified by 'flags'. Note that 'flags'
676 * may be a combination of flags OR'ed toghether, so the same
677 * callback function can be made to accept different events.
678 * The callback function must have the following prototype:
679 *
680 * void function(GSocket *socket, GSocketEvent event, char *cdata)
681 */
682void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
683 GSocketCallback callback, char *cdata)
684{
685 int count;
686
687 assert(socket != NULL);
688
689 for (count = 0; count < GSOCK_MAX_EVENT; count++)
690 {
691 if ((flags & (1 << count)) != 0)
692 {
693 socket->m_cbacks[count] = callback;
694 socket->m_data[count] = cdata;
695 }
696 }
697}
698
699/* GSocket_UnsetCallback:
700 * Disables all callbacks specified by 'flags', which may be a
701 * combination of flags OR'ed toghether.
702 */
703void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
704{
705 int count;
706
707 assert(socket != NULL);
708
709 for (count = 0; count < GSOCK_MAX_EVENT; count++)
710 {
711 if ((flags & (1 << count)) != 0)
712 {
713 socket->m_cbacks[count] = NULL;
714 socket->m_data[count] = NULL;
715 }
716 }
717}
718
719#define CALL_CALLBACK(socket, event) { \
720 _GSocket_Disable(socket, event); \
721 if (socket->m_cbacks[event]) \
722 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
723}
724
725
726void _GSocket_Enable(GSocket *socket, GSocketEvent event)
727{
728 socket->m_detected &= ~(1 << event);
426d5745 729 (socket, event);
fb9010ed
DW
730}
731
732void _GSocket_Disable(GSocket *socket, GSocketEvent event)
733{
734 socket->m_detected |= (1 << event);
fb9010ed
DW
735}
736
737/* _GSocket_Input_Timeout:
738 * For blocking sockets, wait until data is available or
739 * until timeout ellapses.
740 */
741GSocketError _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 */
766GSocketError _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
787int _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
796int _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
832int _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
842int _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
867void _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
893void _GSocket_Detected_Write(GSocket *socket)
894{
895 if (socket->m_establishing && !socket->m_server)
896 {
897 int error, len;
898
27f37ae5 899 socket->m_establishing = 0;
fb9010ed
DW
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
946GAddress *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
962GAddress *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
987void GAddress_destroy(GAddress *address)
988{
989 assert(address != NULL);
990
991 free(address);
992}
993
994void GAddress_SetFamily(GAddress *address, GAddressType type)
995{
996 assert(address != NULL);
997
998 address->m_family = type;
999}
1000
1001GAddressType GAddress_GetFamily(GAddress *address)
1002{
1003 assert(address != NULL);
1004
1005 return address->m_family;
1006}
1007
1008GSocketError _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
1043GSocketError _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
1068GSocketError _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
1086GSocketError 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
b662c135
SN
1122GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1123{
1124 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1125}
1126
fb9010ed
DW
1127GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1128 unsigned long hostaddr)
1129{
1130 struct in_addr *addr;
1131
1132 assert(address != NULL);
1133
1134 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1135
1136 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1137 addr->s_addr = hostaddr;
1138
1139 return GSOCK_NOERROR;
1140}
1141
1142GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1143 const char *protocol)
1144{
1145 struct servent *se;
1146 struct sockaddr_in *addr;
1147
1148 assert(address != NULL);
1149 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1150
1151 if (!port) {
1152 address->m_error = GSOCK_INVPORT;
1153 return GSOCK_INVPORT;
1154 }
1155
1156 se = getservbyname((char*)port, (char*)protocol);
1157 if (!se) {
1158 if (isdigit(port[0])) {
1159 int port_int;
1160
1161 port_int = atoi(port);
1162 addr = (struct sockaddr_in *)address->m_addr;
1163 addr->sin_port = htons(port_int);
1164 return GSOCK_NOERROR;
1165 }
1166
1167 address->m_error = GSOCK_INVPORT;
1168 return GSOCK_INVPORT;
1169 }
1170
1171 addr = (struct sockaddr_in *)address->m_addr;
1172 addr->sin_port = se->s_port;
1173
1174 return GSOCK_NOERROR;
1175}
1176
1177GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1178{
1179 struct sockaddr_in *addr;
1180
1181 assert(address != NULL);
1182 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1183
1184 addr = (struct sockaddr_in *)address->m_addr;
1185 addr->sin_port = htons(port);
1186
1187 return GSOCK_NOERROR;
1188}
1189
1190GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1191{
1192 struct hostent *he;
1193 char *addr_buf;
1194 struct sockaddr_in *addr;
1195
1196 assert(address != NULL);
1197 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1198
1199 addr = (struct sockaddr_in *)address->m_addr;
1200 addr_buf = (char *)&(addr->sin_addr);
1201
1202 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1203 if (he == NULL) {
1204 address->m_error = GSOCK_NOHOST;
1205 return GSOCK_NOHOST;
1206 }
1207
1208 strncpy(hostname, he->h_name, sbuf);
1209
1210 return GSOCK_NOERROR;
1211}
1212
1213unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1214{
1215 struct sockaddr_in *addr;
1216
1217 assert(address != NULL);
1218 CHECK_ADDRESS(address, INET, 0);
1219
1220 addr = (struct sockaddr_in *)address->m_addr;
1221
1222 return addr->sin_addr.s_addr;
1223}
1224
1225unsigned short GAddress_INET_GetPort(GAddress *address)
1226{
1227 struct sockaddr_in *addr;
1228
1229 assert(address != NULL);
1230 CHECK_ADDRESS(address, INET, 0);
1231
1232 addr = (struct sockaddr_in *)address->m_addr;
1233 return ntohs(addr->sin_port);
1234}
1235
b662c135
SN
1236/*
1237 * -------------------------------------------------------------------------
1238 * Unix address family
1239 * -------------------------------------------------------------------------
1240 */
1241
1242GSocketError _GAddress_Init_UNIX(GAddress *address)
1243{
1244 assert (address != NULL);
1245 address->m_error = GSOCK_INVADDR;
1246 return GSOCK_INVADDR;
1247}
1248
1249GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1250{
1251 assert (address != NULL);
1252 address->m_error = GSOCK_INVADDR;
1253 return GSOCK_INVADDR;
1254}
1255
1256GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1257{
1258 assert (address != NULL);
1259 address->m_error = GSOCK_INVADDR;
1260 return GSOCK_INVADDR;
1261}
1262
fb9010ed
DW
1263#endif
1264 /* wxUSE_SOCKETS */