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