]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/gsocket.c
added wxCheckListBox::HitTest() (modified patch 594524)
[wxWidgets.git] / src / msw / gsocket.c
... / ...
CommitLineData
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: gsocket.c
4 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
5 * Purpose: GSocket main MSW file
6 * CVSID: $Id$
7 * -------------------------------------------------------------------------
8 */
9
10/*
11 * PLEASE don't put C++ comments here - this is a C source file.
12 */
13
14#ifdef _MSC_VER
15 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
16 * warning: conditional expression is constant.
17 */
18# pragma warning(disable:4115)
19 /* FD_SET,
20 * warning: named type definition in parentheses.
21 */
22# pragma warning(disable:4127)
23 /* GAddress_UNIX_GetPath,
24 * warning: unreferenced formal parameter.
25 */
26# pragma warning(disable:4100)
27#endif /* _MSC_VER */
28
29
30#ifndef __GSOCKET_STANDALONE__
31# include "wx/defs.h"
32# include "wx/setup.h"
33#endif
34
35#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
36
37#ifndef __GSOCKET_STANDALONE__
38# include "wx/msw/gsockmsw.h"
39# include "wx/gsocket.h"
40#else
41# include "gsockmsw.h"
42# include "gsocket.h"
43#endif /* __GSOCKET_STANDALONE__ */
44
45/* Redefine some GUI-only functions to do nothing in console mode */
46#if defined(wxUSE_GUI) && !wxUSE_GUI
47# define _GSocket_GUI_Init(socket) (1)
48# define _GSocket_GUI_Destroy(socket)
49# define _GSocket_Enable_Events(socket)
50# define _GSocket_Disable_Events(socket)
51#endif /* wxUSE_GUI */
52
53
54#include <assert.h>
55#include <string.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <stddef.h>
59#include <ctype.h>
60
61#include <winsock.h>
62
63/* if we use configure for MSW SOCKLEN_T will be already defined */
64#ifndef SOCKLEN_T
65# define SOCKLEN_T int
66#endif
67
68
69/* Constructors / Destructors for GSocket */
70
71GSocket *GSocket_new(void)
72{
73 int i, success;
74 GSocket *socket;
75
76 if ((socket = (GSocket *) malloc(sizeof(GSocket))) == NULL)
77 return NULL;
78
79 socket->m_fd = INVALID_SOCKET;
80 for (i = 0; i < GSOCK_MAX_EVENT; i++)
81 {
82 socket->m_cbacks[i] = NULL;
83 }
84 socket->m_detected = 0;
85 socket->m_local = NULL;
86 socket->m_peer = NULL;
87 socket->m_error = GSOCK_NOERROR;
88 socket->m_server = FALSE;
89 socket->m_stream = TRUE;
90 socket->m_non_blocking = FALSE;
91 socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */
92 socket->m_timeout.tv_usec = 0;
93 socket->m_establishing = FALSE;
94
95 /* Per-socket GUI-specific initialization */
96 success = _GSocket_GUI_Init(socket);
97 if (!success)
98 {
99 free(socket);
100 socket = NULL;
101 }
102
103 return socket;
104}
105
106void GSocket_close(GSocket *socket)
107{
108 _GSocket_Disable_Events(socket);
109 closesocket(socket->m_fd);
110 socket->m_fd = INVALID_SOCKET;
111}
112
113void GSocket_destroy(GSocket *socket)
114{
115 assert(socket != NULL);
116
117 /* Per-socket GUI-specific cleanup */
118 _GSocket_GUI_Destroy(socket);
119
120 /* Check that the socket is really shutdowned */
121 if (socket->m_fd != INVALID_SOCKET)
122 GSocket_Shutdown(socket);
123
124 /* Destroy private addresses */
125 if (socket->m_local)
126 GAddress_destroy(socket->m_local);
127
128 if (socket->m_peer)
129 GAddress_destroy(socket->m_peer);
130
131 /* Destroy the socket itself */
132 free(socket);
133}
134
135/* GSocket_Shutdown:
136 * Disallow further read/write operations on this socket, close
137 * the fd and disable all callbacks.
138 */
139void GSocket_Shutdown(GSocket *socket)
140{
141 int evt;
142
143 assert(socket != NULL);
144
145 /* If socket has been created, shutdown it */
146 if (socket->m_fd != INVALID_SOCKET)
147 {
148 shutdown(socket->m_fd, 2);
149 GSocket_close(socket);
150 }
151
152 /* Disable GUI callbacks */
153 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
154 socket->m_cbacks[evt] = NULL;
155
156 socket->m_detected = GSOCK_LOST_FLAG;
157}
158
159/* Address handling */
160
161/* GSocket_SetLocal:
162 * GSocket_GetLocal:
163 * GSocket_SetPeer:
164 * GSocket_GetPeer:
165 * Set or get the local or peer address for this socket. The 'set'
166 * functions return GSOCK_NOERROR on success, an error code otherwise.
167 * The 'get' functions return a pointer to a GAddress object on success,
168 * or NULL otherwise, in which case they set the error code of the
169 * corresponding GSocket.
170 *
171 * Error codes:
172 * GSOCK_INVSOCK - the socket is not valid.
173 * GSOCK_INVADDR - the address is not valid.
174 */
175GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
176{
177 assert(socket != NULL);
178
179 /* the socket must be initialized, or it must be a server */
180 if (socket->m_fd != INVALID_SOCKET && !socket->m_server)
181 {
182 socket->m_error = GSOCK_INVSOCK;
183 return GSOCK_INVSOCK;
184 }
185
186 /* check address */
187 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
188 {
189 socket->m_error = GSOCK_INVADDR;
190 return GSOCK_INVADDR;
191 }
192
193 if (socket->m_local)
194 GAddress_destroy(socket->m_local);
195
196 socket->m_local = GAddress_copy(address);
197
198 return GSOCK_NOERROR;
199}
200
201GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
202{
203 assert(socket != NULL);
204
205 /* check address */
206 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
207 {
208 socket->m_error = GSOCK_INVADDR;
209 return GSOCK_INVADDR;
210 }
211
212 if (socket->m_peer)
213 GAddress_destroy(socket->m_peer);
214
215 socket->m_peer = GAddress_copy(address);
216
217 return GSOCK_NOERROR;
218}
219
220GAddress *GSocket_GetLocal(GSocket *socket)
221{
222 GAddress *address;
223 struct sockaddr addr;
224 SOCKLEN_T size = sizeof(addr);
225 GSocketError err;
226
227 assert(socket != NULL);
228
229 /* try to get it from the m_local var first */
230 if (socket->m_local)
231 return GAddress_copy(socket->m_local);
232
233 /* else, if the socket is initialized, try getsockname */
234 if (socket->m_fd == INVALID_SOCKET)
235 {
236 socket->m_error = GSOCK_INVSOCK;
237 return NULL;
238 }
239
240 if (getsockname(socket->m_fd, &addr, &size) == SOCKET_ERROR)
241 {
242 socket->m_error = GSOCK_IOERR;
243 return NULL;
244 }
245
246 /* got a valid address from getsockname, create a GAddress object */
247 if ((address = GAddress_new()) == NULL)
248 {
249 socket->m_error = GSOCK_MEMERR;
250 return NULL;
251 }
252
253 if ((err = _GAddress_translate_from(address, &addr, size)) != GSOCK_NOERROR)
254 {
255 GAddress_destroy(address);
256 socket->m_error = err;
257 return NULL;
258 }
259
260 return address;
261}
262
263GAddress *GSocket_GetPeer(GSocket *socket)
264{
265 assert(socket != NULL);
266
267 /* try to get it from the m_peer var */
268 if (socket->m_peer)
269 return GAddress_copy(socket->m_peer);
270
271 return NULL;
272}
273
274/* Server specific parts */
275
276/* GSocket_SetServer:
277 * Sets up this socket as a server. The local address must have been
278 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
279 * Returns GSOCK_NOERROR on success, one of the following otherwise:
280 *
281 * Error codes:
282 * GSOCK_INVSOCK - the socket is in use.
283 * GSOCK_INVADDR - the local address has not been set.
284 * GSOCK_IOERR - low-level error.
285 */
286GSocketError GSocket_SetServer(GSocket *sck)
287{
288 u_long arg = 1;
289
290 assert(sck != NULL);
291
292 /* must not be in use */
293 if (sck->m_fd != INVALID_SOCKET)
294 {
295 sck->m_error = GSOCK_INVSOCK;
296 return GSOCK_INVSOCK;
297 }
298
299 /* the local addr must have been set */
300 if (!sck->m_local)
301 {
302 sck->m_error = GSOCK_INVADDR;
303 return GSOCK_INVADDR;
304 }
305
306 /* Initialize all fields */
307 sck->m_server = TRUE;
308 sck->m_stream = TRUE;
309 sck->m_oriented = TRUE;
310
311 /* Create the socket */
312 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
313
314 if (sck->m_fd == INVALID_SOCKET)
315 {
316 sck->m_error = GSOCK_IOERR;
317 return GSOCK_IOERR;
318 }
319
320 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
321 _GSocket_Enable_Events(sck);
322
323 /* Bind to the local address,
324 * retrieve the actual address bound,
325 * and listen up to 5 connections.
326 */
327 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
328 (getsockname(sck->m_fd,
329 sck->m_local->m_addr,
330 (SOCKLEN_T *)&sck->m_local->m_len) != 0) ||
331 (listen(sck->m_fd, 5) != 0))
332 {
333 GSocket_close(sck);
334 sck->m_error = GSOCK_IOERR;
335 return GSOCK_IOERR;
336 }
337
338 return GSOCK_NOERROR;
339}
340
341/* GSocket_WaitConnection:
342 * Waits for an incoming client connection. Returns a pointer to
343 * a GSocket object, or NULL if there was an error, in which case
344 * the last error field will be updated for the calling GSocket.
345 *
346 * Error codes (set in the calling GSocket)
347 * GSOCK_INVSOCK - the socket is not valid or not a server.
348 * GSOCK_TIMEDOUT - timeout, no incoming connections.
349 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
350 * GSOCK_MEMERR - couldn't allocate memory.
351 * GSOCK_IOERR - low-level error.
352 */
353GSocket *GSocket_WaitConnection(GSocket *sck)
354{
355 GSocket *connection;
356 struct sockaddr from;
357 SOCKLEN_T fromlen = sizeof(from);
358 GSocketError err;
359 u_long arg = 1;
360
361 assert(sck != NULL);
362
363 /* Reenable CONNECTION events */
364 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
365
366 /* If the socket has already been created, we exit immediately */
367 if (sck->m_fd == INVALID_SOCKET || !sck->m_server)
368 {
369 sck->m_error = GSOCK_INVSOCK;
370 return NULL;
371 }
372
373 /* Create a GSocket object for the new connection */
374 connection = GSocket_new();
375
376 if (!connection)
377 {
378 sck->m_error = GSOCK_MEMERR;
379 return NULL;
380 }
381
382 /* Wait for a connection (with timeout) */
383 if (_GSocket_Input_Timeout(sck) == GSOCK_TIMEDOUT)
384 {
385 GSocket_destroy(connection);
386 /* sck->m_error set by _GSocket_Input_Timeout */
387 return NULL;
388 }
389
390 connection->m_fd = accept(sck->m_fd, &from, &fromlen);
391
392 if (connection->m_fd == INVALID_SOCKET)
393 {
394 if (WSAGetLastError() == WSAEWOULDBLOCK)
395 sck->m_error = GSOCK_WOULDBLOCK;
396 else
397 sck->m_error = GSOCK_IOERR;
398
399 GSocket_destroy(connection);
400 return NULL;
401 }
402
403 /* Initialize all fields */
404 connection->m_server = FALSE;
405 connection->m_stream = TRUE;
406 connection->m_oriented = TRUE;
407
408 /* Setup the peer address field */
409 connection->m_peer = GAddress_new();
410 if (!connection->m_peer)
411 {
412 GSocket_destroy(connection);
413 sck->m_error = GSOCK_MEMERR;
414 return NULL;
415 }
416 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
417 if (err != GSOCK_NOERROR)
418 {
419 GAddress_destroy(connection->m_peer);
420 GSocket_destroy(connection);
421 sck->m_error = err;
422 return NULL;
423 }
424
425 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
426 _GSocket_Enable_Events(connection);
427
428 return connection;
429}
430
431/* Client specific parts */
432
433/* GSocket_Connect:
434 * For stream (connection oriented) sockets, GSocket_Connect() tries
435 * to establish a client connection to a server using the peer address
436 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
437 * connection has been succesfully established, or one of the error
438 * codes listed below. Note that for nonblocking sockets, a return
439 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
440 * request can be completed later; you should use GSocket_Select()
441 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
442 * corresponding asynchronous events.
443 *
444 * For datagram (non connection oriented) sockets, GSocket_Connect()
445 * just sets the peer address established with GSocket_SetPeer() as
446 * default destination.
447 *
448 * Error codes:
449 * GSOCK_INVSOCK - the socket is in use or not valid.
450 * GSOCK_INVADDR - the peer address has not been established.
451 * GSOCK_TIMEDOUT - timeout, the connection failed.
452 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
453 * GSOCK_MEMERR - couldn't allocate memory.
454 * GSOCK_IOERR - low-level error.
455 */
456GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
457{
458 int ret, err;
459 u_long arg = 1;
460
461 assert(sck != NULL);
462
463 /* Enable CONNECTION events (needed for nonblocking connections) */
464 sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
465
466 if (sck->m_fd != INVALID_SOCKET)
467 {
468 sck->m_error = GSOCK_INVSOCK;
469 return GSOCK_INVSOCK;
470 }
471
472 if (!sck->m_peer)
473 {
474 sck->m_error = GSOCK_INVADDR;
475 return GSOCK_INVADDR;
476 }
477
478 /* Streamed or dgram socket? */
479 sck->m_stream = (stream == GSOCK_STREAMED);
480 sck->m_oriented = TRUE;
481 sck->m_server = FALSE;
482 sck->m_establishing = FALSE;
483
484 /* Create the socket */
485 sck->m_fd = socket(sck->m_peer->m_realfamily,
486 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
487
488 if (sck->m_fd == INVALID_SOCKET)
489 {
490 sck->m_error = GSOCK_IOERR;
491 return GSOCK_IOERR;
492 }
493
494 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
495 _GSocket_Enable_Events(sck);
496
497 /* Connect it to the peer address, with a timeout (see below) */
498 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
499
500 if (ret == SOCKET_ERROR)
501 {
502 err = WSAGetLastError();
503
504 /* If connect failed with EWOULDBLOCK and the GSocket object
505 * is in blocking mode, we select() for the specified timeout
506 * checking for writability to see if the connection request
507 * completes.
508 */
509 if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking))
510 {
511 err = _GSocket_Connect_Timeout(sck);
512
513 if (err != GSOCK_NOERROR)
514 {
515 GSocket_close(sck);
516 /* sck->m_error is set in _GSocket_Connect_Timeout */
517 }
518
519 return (GSocketError) err;
520 }
521
522 /* If connect failed with EWOULDBLOCK and the GSocket object
523 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
524 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
525 * this way if the connection completes, a GSOCK_CONNECTION
526 * event will be generated, if enabled.
527 */
528 if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking))
529 {
530 sck->m_establishing = TRUE;
531 sck->m_error = GSOCK_WOULDBLOCK;
532 return GSOCK_WOULDBLOCK;
533 }
534
535 /* If connect failed with an error other than EWOULDBLOCK,
536 * then the call to GSocket_Connect() has failed.
537 */
538 GSocket_close(sck);
539 sck->m_error = GSOCK_IOERR;
540 return GSOCK_IOERR;
541 }
542
543 return GSOCK_NOERROR;
544}
545
546/* Datagram sockets */
547
548/* GSocket_SetNonOriented:
549 * Sets up this socket as a non-connection oriented (datagram) socket.
550 * Before using this function, the local address must have been set
551 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
552 * on success, or one of the following otherwise.
553 *
554 * Error codes:
555 * GSOCK_INVSOCK - the socket is in use.
556 * GSOCK_INVADDR - the local address has not been set.
557 * GSOCK_IOERR - low-level error.
558 */
559GSocketError GSocket_SetNonOriented(GSocket *sck)
560{
561 u_long arg = 1;
562
563 assert(sck != NULL);
564
565 if (sck->m_fd != INVALID_SOCKET)
566 {
567 sck->m_error = GSOCK_INVSOCK;
568 return GSOCK_INVSOCK;
569 }
570
571 if (!sck->m_local)
572 {
573 sck->m_error = GSOCK_INVADDR;
574 return GSOCK_INVADDR;
575 }
576
577 /* Initialize all fields */
578 sck->m_stream = FALSE;
579 sck->m_server = FALSE;
580 sck->m_oriented = FALSE;
581
582 /* Create the socket */
583 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
584
585 if (sck->m_fd == INVALID_SOCKET)
586 {
587 sck->m_error = GSOCK_IOERR;
588 return GSOCK_IOERR;
589 }
590
591 ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
592 _GSocket_Enable_Events(sck);
593
594 /* Bind to the local address,
595 * and retrieve the actual address bound.
596 */
597 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
598 (getsockname(sck->m_fd,
599 sck->m_local->m_addr,
600 (SOCKLEN_T *)&sck->m_local->m_len) != 0))
601 {
602 GSocket_close(sck);
603 sck->m_error = GSOCK_IOERR;
604 return GSOCK_IOERR;
605 }
606
607 return GSOCK_NOERROR;
608}
609
610/* Generic IO */
611
612/* Like recv(), send(), ... */
613int GSocket_Read(GSocket *socket, char *buffer, int size)
614{
615 int ret;
616
617 assert(socket != NULL);
618
619 /* Reenable INPUT events */
620 socket->m_detected &= ~GSOCK_INPUT_FLAG;
621
622 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
623 {
624 socket->m_error = GSOCK_INVSOCK;
625 return -1;
626 }
627
628 /* If the socket is blocking, wait for data (with a timeout) */
629 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
630 return -1;
631
632 /* Read the data */
633 if (socket->m_stream)
634 ret = _GSocket_Recv_Stream(socket, buffer, size);
635 else
636 ret = _GSocket_Recv_Dgram(socket, buffer, size);
637
638 if (ret == SOCKET_ERROR)
639 {
640 if (WSAGetLastError() != WSAEWOULDBLOCK)
641 socket->m_error = GSOCK_IOERR;
642 else
643 socket->m_error = GSOCK_WOULDBLOCK;
644 return -1;
645 }
646
647 return ret;
648}
649
650int GSocket_Write(GSocket *socket, const char *buffer, int size)
651{
652 int ret;
653
654 assert(socket != NULL);
655
656 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
657 {
658 socket->m_error = GSOCK_INVSOCK;
659 return -1;
660 }
661
662 /* If the socket is blocking, wait for writability (with a timeout) */
663 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
664 return -1;
665
666 /* Write the data */
667 if (socket->m_stream)
668 ret = _GSocket_Send_Stream(socket, buffer, size);
669 else
670 ret = _GSocket_Send_Dgram(socket, buffer, size);
671
672 if (ret == SOCKET_ERROR)
673 {
674 if (WSAGetLastError() != WSAEWOULDBLOCK)
675 socket->m_error = GSOCK_IOERR;
676 else
677 socket->m_error = GSOCK_WOULDBLOCK;
678
679 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
680 * does). Once the first OUTPUT event is received, users can assume
681 * that the socket is writable until a read operation fails. Only then
682 * will further OUTPUT events be posted.
683 */
684 socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
685 return -1;
686 }
687
688 return ret;
689}
690
691/* GSocket_Select:
692 * Polls the socket to determine its status. This function will
693 * check for the events specified in the 'flags' parameter, and
694 * it will return a mask indicating which operations can be
695 * performed. This function won't block, regardless of the
696 * mode (blocking | nonblocking) of the socket.
697 */
698GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
699{
700#if defined(wxUSE_GUI) && !wxUSE_GUI
701
702 GSocketEventFlags result = 0;
703 fd_set readfds;
704 fd_set writefds;
705 fd_set exceptfds;
706 static const struct timeval tv = { 0, 0 };
707
708 assert(socket != NULL);
709
710 FD_ZERO(&readfds);
711 FD_ZERO(&writefds);
712 FD_ZERO(&exceptfds);
713 FD_SET(socket->m_fd, &readfds);
714 FD_SET(socket->m_fd, &writefds);
715 FD_SET(socket->m_fd, &exceptfds);
716
717 /* Check known state first */
718 result |= (GSOCK_CONNECTION_FLAG & socket->m_detected & flags);
719 result |= (GSOCK_LOST_FLAG & socket->m_detected & flags);
720
721 /* Try select now */
722 if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
723 return result;
724
725 /* Check for readability */
726 if (FD_ISSET(socket->m_fd, &readfds))
727 {
728 /* Assume that closure of the socket is always reported via exceptfds */
729 if (socket->m_server && socket->m_stream)
730 result |= (GSOCK_CONNECTION_FLAG & flags);
731 else
732 result |= (GSOCK_INPUT_FLAG & flags);
733 }
734
735 /* Check for writability */
736 if (FD_ISSET(socket->m_fd, &writefds))
737 {
738 if (socket->m_establishing && !socket->m_server)
739 {
740 result |= (GSOCK_CONNECTION_FLAG & flags);
741 socket->m_establishing = FALSE;
742 socket->m_detected |= GSOCK_CONNECTION_FLAG;
743 }
744 else
745 result |= (GSOCK_OUTPUT_FLAG & flags);
746 }
747
748 /* Check for exceptions and errors */
749 if (FD_ISSET(socket->m_fd, &exceptfds))
750 {
751 result |= (GSOCK_LOST_FLAG & flags);
752 socket->m_establishing = FALSE;
753 socket->m_detected = GSOCK_LOST_FLAG;
754 }
755
756 return result;
757
758#else
759
760 assert(socket != NULL);
761 return flags & socket->m_detected;
762
763#endif /* !wxUSE_GUI */
764}
765
766/* Attributes */
767
768/* GSocket_SetNonBlocking:
769 * Sets the socket to non-blocking mode. All IO calls will return
770 * immediately.
771 */
772void GSocket_SetNonBlocking(GSocket *socket, int non_block)
773{
774 assert(socket != NULL);
775
776 socket->m_non_blocking = non_block;
777}
778
779/* GSocket_SetTimeout:
780 * Sets the timeout for blocking calls. Time is expressed in
781 * milliseconds.
782 */
783void GSocket_SetTimeout(GSocket *socket, unsigned long millis)
784{
785 assert(socket != NULL);
786
787 socket->m_timeout.tv_sec = (millis / 1000);
788 socket->m_timeout.tv_usec = (millis % 1000) * 1000;
789}
790
791/* GSocket_GetError:
792 * Returns the last error occured for this socket. Note that successful
793 * operations do not clear this back to GSOCK_NOERROR, so use it only
794 * after an error.
795 */
796GSocketError GSocket_GetError(GSocket *socket)
797{
798 assert(socket != NULL);
799
800 return socket->m_error;
801}
802
803/* Callbacks */
804
805/* GSOCK_INPUT:
806 * There is data to be read in the input buffer. If, after a read
807 * operation, there is still data available, the callback function will
808 * be called again.
809 * GSOCK_OUTPUT:
810 * The socket is available for writing. That is, the next write call
811 * won't block. This event is generated only once, when the connection is
812 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
813 * when the output buffer empties again. This means that the app should
814 * assume that it can write since the first OUTPUT event, and no more
815 * OUTPUT events will be generated unless an error occurs.
816 * GSOCK_CONNECTION:
817 * Connection succesfully established, for client sockets, or incoming
818 * client connection, for server sockets. Wait for this event (also watch
819 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
820 * GSOCK_LOST:
821 * The connection is lost (or a connection request failed); this could
822 * be due to a failure, or due to the peer closing it gracefully.
823 */
824
825/* GSocket_SetCallback:
826 * Enables the callbacks specified by 'flags'. Note that 'flags'
827 * may be a combination of flags OR'ed toghether, so the same
828 * callback function can be made to accept different events.
829 * The callback function must have the following prototype:
830 *
831 * void function(GSocket *socket, GSocketEvent event, char *cdata)
832 */
833void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
834 GSocketCallback callback, char *cdata)
835{
836 int count;
837
838 assert(socket != NULL);
839
840 for (count = 0; count < GSOCK_MAX_EVENT; count++)
841 {
842 if ((flags & (1 << count)) != 0)
843 {
844 socket->m_cbacks[count] = callback;
845 socket->m_data[count] = cdata;
846 }
847 }
848}
849
850/* GSocket_UnsetCallback:
851 * Disables all callbacks specified by 'flags', which may be a
852 * combination of flags OR'ed toghether.
853 */
854void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
855{
856 int count;
857
858 assert(socket != NULL);
859
860 for (count = 0; count < GSOCK_MAX_EVENT; count++)
861 {
862 if ((flags & (1 << count)) != 0)
863 {
864 socket->m_cbacks[count] = NULL;
865 socket->m_data[count] = NULL;
866 }
867 }
868}
869
870/* Internals (IO) */
871
872/* _GSocket_Input_Timeout:
873 * For blocking sockets, wait until data is available or
874 * until timeout ellapses.
875 */
876GSocketError _GSocket_Input_Timeout(GSocket *socket)
877{
878 fd_set readfds;
879
880 if (!socket->m_non_blocking)
881 {
882 FD_ZERO(&readfds);
883 FD_SET(socket->m_fd, &readfds);
884 if (select(0, &readfds, NULL, NULL, &socket->m_timeout) == 0)
885 {
886 socket->m_error = GSOCK_TIMEDOUT;
887 return GSOCK_TIMEDOUT;
888 }
889 }
890 return GSOCK_NOERROR;
891}
892
893/* _GSocket_Output_Timeout:
894 * For blocking sockets, wait until data can be sent without
895 * blocking or until timeout ellapses.
896 */
897GSocketError _GSocket_Output_Timeout(GSocket *socket)
898{
899 fd_set writefds;
900
901 if (!socket->m_non_blocking)
902 {
903 FD_ZERO(&writefds);
904 FD_SET(socket->m_fd, &writefds);
905 if (select(0, NULL, &writefds, NULL, &socket->m_timeout) == 0)
906 {
907 socket->m_error = GSOCK_TIMEDOUT;
908 return GSOCK_TIMEDOUT;
909 }
910 }
911 return GSOCK_NOERROR;
912}
913
914/* _GSocket_Connect_Timeout:
915 * For blocking sockets, wait until the connection is
916 * established or fails, or until timeout ellapses.
917 */
918GSocketError _GSocket_Connect_Timeout(GSocket *socket)
919{
920 fd_set writefds;
921 fd_set exceptfds;
922
923 FD_ZERO(&writefds);
924 FD_ZERO(&exceptfds);
925 FD_SET(socket->m_fd, &writefds);
926 FD_SET(socket->m_fd, &exceptfds);
927 if (select(0, NULL, &writefds, &exceptfds, &socket->m_timeout) == 0)
928 {
929 socket->m_error = GSOCK_TIMEDOUT;
930 return GSOCK_TIMEDOUT;
931 }
932 if (!FD_ISSET(socket->m_fd, &writefds))
933 {
934 socket->m_error = GSOCK_IOERR;
935 return GSOCK_IOERR;
936 }
937
938 return GSOCK_NOERROR;
939}
940
941int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
942{
943 return recv(socket->m_fd, buffer, size, 0);
944}
945
946int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
947{
948 struct sockaddr from;
949 SOCKLEN_T fromlen = sizeof(from);
950 int ret;
951 GSocketError err;
952
953 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
954
955 if (ret == SOCKET_ERROR)
956 return SOCKET_ERROR;
957
958 /* Translate a system address into a GSocket address */
959 if (!socket->m_peer)
960 {
961 socket->m_peer = GAddress_new();
962 if (!socket->m_peer)
963 {
964 socket->m_error = GSOCK_MEMERR;
965 return -1;
966 }
967 }
968 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
969 if (err != GSOCK_NOERROR)
970 {
971 GAddress_destroy(socket->m_peer);
972 socket->m_peer = NULL;
973 socket->m_error = err;
974 return -1;
975 }
976
977 return ret;
978}
979
980int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
981{
982 return send(socket->m_fd, buffer, size, 0);
983}
984
985int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
986{
987 struct sockaddr *addr;
988 int len, ret;
989 GSocketError err;
990
991 if (!socket->m_peer)
992 {
993 socket->m_error = GSOCK_INVADDR;
994 return -1;
995 }
996
997 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
998 if (err != GSOCK_NOERROR)
999 {
1000 socket->m_error = err;
1001 return -1;
1002 }
1003
1004 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1005
1006 /* Frees memory allocated by _GAddress_translate_to */
1007 free(addr);
1008
1009 return ret;
1010}
1011
1012
1013/*
1014 * -------------------------------------------------------------------------
1015 * GAddress
1016 * -------------------------------------------------------------------------
1017 */
1018
1019/* CHECK_ADDRESS verifies that the current address family is either
1020 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1021 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1022 * an appropiate error code.
1023 *
1024 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1025 */
1026#define CHECK_ADDRESS(address, family) \
1027{ \
1028 if (address->m_family == GSOCK_NOFAMILY) \
1029 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1030 return address->m_error; \
1031 if (address->m_family != GSOCK_##family) \
1032 { \
1033 address->m_error = GSOCK_INVADDR; \
1034 return GSOCK_INVADDR; \
1035 } \
1036}
1037
1038#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1039{ \
1040 if (address->m_family == GSOCK_NOFAMILY) \
1041 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1042 return retval; \
1043 if (address->m_family != GSOCK_##family) \
1044 { \
1045 address->m_error = GSOCK_INVADDR; \
1046 return retval; \
1047 } \
1048}
1049
1050
1051GAddress *GAddress_new(void)
1052{
1053 GAddress *address;
1054
1055 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1056 return NULL;
1057
1058 address->m_family = GSOCK_NOFAMILY;
1059 address->m_addr = NULL;
1060 address->m_len = 0;
1061
1062 return address;
1063}
1064
1065GAddress *GAddress_copy(GAddress *address)
1066{
1067 GAddress *addr2;
1068
1069 assert(address != NULL);
1070
1071 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1072 return NULL;
1073
1074 memcpy(addr2, address, sizeof(GAddress));
1075
1076 if (address->m_addr)
1077 {
1078 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1079 if (addr2->m_addr == NULL)
1080 {
1081 free(addr2);
1082 return NULL;
1083 }
1084 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1085 }
1086
1087 return addr2;
1088}
1089
1090void GAddress_destroy(GAddress *address)
1091{
1092 assert(address != NULL);
1093
1094 if (address->m_addr)
1095 free(address->m_addr);
1096
1097 free(address);
1098}
1099
1100void GAddress_SetFamily(GAddress *address, GAddressType type)
1101{
1102 assert(address != NULL);
1103
1104 address->m_family = type;
1105}
1106
1107GAddressType GAddress_GetFamily(GAddress *address)
1108{
1109 assert(address != NULL);
1110
1111 return address->m_family;
1112}
1113
1114GSocketError _GAddress_translate_from(GAddress *address,
1115 struct sockaddr *addr, int len)
1116{
1117 address->m_realfamily = addr->sa_family;
1118 switch (addr->sa_family)
1119 {
1120 case AF_INET:
1121 address->m_family = GSOCK_INET;
1122 break;
1123 case AF_UNIX:
1124 address->m_family = GSOCK_UNIX;
1125 break;
1126#ifdef AF_INET6
1127 case AF_INET6:
1128 address->m_family = GSOCK_INET6;
1129 break;
1130#endif
1131 default:
1132 {
1133 address->m_error = GSOCK_INVOP;
1134 return GSOCK_INVOP;
1135 }
1136 }
1137
1138 if (address->m_addr)
1139 free(address->m_addr);
1140
1141 address->m_len = len;
1142 address->m_addr = (struct sockaddr *) malloc(len);
1143
1144 if (address->m_addr == NULL)
1145 {
1146 address->m_error = GSOCK_MEMERR;
1147 return GSOCK_MEMERR;
1148 }
1149 memcpy(address->m_addr, addr, len);
1150
1151 return GSOCK_NOERROR;
1152}
1153
1154GSocketError _GAddress_translate_to(GAddress *address,
1155 struct sockaddr **addr, int *len)
1156{
1157 if (!address->m_addr)
1158 {
1159 address->m_error = GSOCK_INVADDR;
1160 return GSOCK_INVADDR;
1161 }
1162
1163 *len = address->m_len;
1164 *addr = (struct sockaddr *) malloc(address->m_len);
1165 if (*addr == NULL)
1166 {
1167 address->m_error = GSOCK_MEMERR;
1168 return GSOCK_MEMERR;
1169 }
1170
1171 memcpy(*addr, address->m_addr, address->m_len);
1172 return GSOCK_NOERROR;
1173}
1174
1175/*
1176 * -------------------------------------------------------------------------
1177 * Internet address family
1178 * -------------------------------------------------------------------------
1179 */
1180
1181GSocketError _GAddress_Init_INET(GAddress *address)
1182{
1183 address->m_len = sizeof(struct sockaddr_in);
1184 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1185 if (address->m_addr == NULL)
1186 {
1187 address->m_error = GSOCK_MEMERR;
1188 return GSOCK_MEMERR;
1189 }
1190
1191 address->m_family = GSOCK_INET;
1192 address->m_realfamily = PF_INET;
1193 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1194 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1195
1196 return GSOCK_NOERROR;
1197}
1198
1199GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1200{
1201 struct hostent *he;
1202 struct in_addr *addr;
1203
1204 assert(address != NULL);
1205
1206 CHECK_ADDRESS(address, INET);
1207
1208 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1209
1210 addr->s_addr = inet_addr(hostname);
1211
1212 /* If it is a numeric host name, convert it now */
1213 if (addr->s_addr == INADDR_NONE)
1214 {
1215 struct in_addr *array_addr;
1216
1217 /* It is a real name, we solve it */
1218 if ((he = gethostbyname(hostname)) == NULL)
1219 {
1220 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1221 address->m_error = GSOCK_NOHOST;
1222 return GSOCK_NOHOST;
1223 }
1224 array_addr = (struct in_addr *) *(he->h_addr_list);
1225 addr->s_addr = array_addr[0].s_addr;
1226 }
1227 return GSOCK_NOERROR;
1228}
1229
1230GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1231{
1232 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1233}
1234
1235GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1236 unsigned long hostaddr)
1237{
1238 struct in_addr *addr;
1239
1240 assert(address != NULL);
1241
1242 CHECK_ADDRESS(address, INET);
1243
1244 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1245 addr->s_addr = hostaddr;
1246
1247 return GSOCK_NOERROR;
1248}
1249
1250GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1251 const char *protocol)
1252{
1253 struct servent *se;
1254 struct sockaddr_in *addr;
1255
1256 assert(address != NULL);
1257 CHECK_ADDRESS(address, INET);
1258
1259 if (!port)
1260 {
1261 address->m_error = GSOCK_INVPORT;
1262 return GSOCK_INVPORT;
1263 }
1264
1265 se = getservbyname(port, protocol);
1266 if (!se)
1267 {
1268 if (isdigit(port[0]))
1269 {
1270 int port_int;
1271
1272 port_int = atoi(port);
1273 addr = (struct sockaddr_in *)address->m_addr;
1274 addr->sin_port = htons((u_short) port_int);
1275 return GSOCK_NOERROR;
1276 }
1277
1278 address->m_error = GSOCK_INVPORT;
1279 return GSOCK_INVPORT;
1280 }
1281
1282 addr = (struct sockaddr_in *)address->m_addr;
1283 addr->sin_port = se->s_port;
1284
1285 return GSOCK_NOERROR;
1286}
1287
1288GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1289{
1290 struct sockaddr_in *addr;
1291
1292 assert(address != NULL);
1293 CHECK_ADDRESS(address, INET);
1294
1295 addr = (struct sockaddr_in *)address->m_addr;
1296 addr->sin_port = htons(port);
1297
1298 return GSOCK_NOERROR;
1299}
1300
1301GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1302{
1303 struct hostent *he;
1304 char *addr_buf;
1305 struct sockaddr_in *addr;
1306
1307 assert(address != NULL);
1308 CHECK_ADDRESS(address, INET);
1309
1310 addr = (struct sockaddr_in *)address->m_addr;
1311 addr_buf = (char *)&(addr->sin_addr);
1312
1313 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1314 if (he == NULL)
1315 {
1316 address->m_error = GSOCK_NOHOST;
1317 return GSOCK_NOHOST;
1318 }
1319
1320 strncpy(hostname, he->h_name, sbuf);
1321
1322 return GSOCK_NOERROR;
1323}
1324
1325unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1326{
1327 struct sockaddr_in *addr;
1328
1329 assert(address != NULL);
1330 CHECK_ADDRESS_RETVAL(address, INET, 0);
1331
1332 addr = (struct sockaddr_in *)address->m_addr;
1333
1334 return addr->sin_addr.s_addr;
1335}
1336
1337unsigned short GAddress_INET_GetPort(GAddress *address)
1338{
1339 struct sockaddr_in *addr;
1340
1341 assert(address != NULL);
1342 CHECK_ADDRESS_RETVAL(address, INET, 0);
1343
1344 addr = (struct sockaddr_in *)address->m_addr;
1345 return ntohs(addr->sin_port);
1346}
1347
1348/*
1349 * -------------------------------------------------------------------------
1350 * Unix address family
1351 * -------------------------------------------------------------------------
1352 */
1353
1354GSocketError _GAddress_Init_UNIX(GAddress *address)
1355{
1356 assert (address != NULL);
1357 address->m_error = GSOCK_INVADDR;
1358 return GSOCK_INVADDR;
1359}
1360
1361GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1362{
1363 assert (address != NULL);
1364 address->m_error = GSOCK_INVADDR;
1365 return GSOCK_INVADDR;
1366}
1367
1368GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1369{
1370 assert (address != NULL);
1371 address->m_error = GSOCK_INVADDR;
1372 return GSOCK_INVADDR;
1373}
1374
1375#else /* !wxUSE_SOCKETS */
1376
1377/*
1378 * Translation unit shouldn't be empty, so include this typedef to make the
1379 * compiler (VC++ 6.0, for example) happy
1380 */
1381typedef void (*wxDummy)();
1382
1383#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
1384
1385// vi:sts=4:sw=4:et