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