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