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