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